Introduction
This article describe how to customize the small calendar as a week picker.
Pre-request
Please check Client Side Programming and The use, apply Attribute at References section before reading this article
The Program
calendar_as_week_picker.zul
<zk xmlns:w="client">
    <style>
        .custom-selected-node {
            background-color: #99FF99 !important;
        }
    </style>
    <vlayout>
        <label value="selected dates" />
        <textbox rows="7" id="tbx" width="300px" />
    </vlayout>
    <calendar id="cal" use="test.custom.component.WeekPicker">
        <attribute w:name="_markCal"><![CDATA[
            function (opts) {
                // clear old custom-selected-node
                jq('.custom-selected-node').each(function () {
                    jq(this).removeClass('custom-selected-node');
                });
                this.$_markCal(opts);
                if (this._view == 'day') {
                    // target: current focused date (td)
                    // parent: tr
                    var target = jq('.z-calendar-seld')[0],
                        parent = target.parentNode,
                        node = parent.firstChild,
                        beforeCnt = 0,
                        found;
                    // loop through each td
                    while (node) {
                        // add selected style
                        jq(node).addClass('custom-selected-node');
                        if (node == target) {
                            found = true;
                        } else if (!found) {
                            // count nodes before target
                            beforeCnt++;
                        }
                        node = node.nextSibling;
                    }
                    // fire event to server
                    this.fire('onCustomSelect', {bcnt: beforeCnt});
                }
            }
        ]]></attribute>
        <attribute name="onCustomSelect"><![CDATA[
            List dates = self.getSelectedDates();
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd / MM / yyyy");
            String value = "";
            for (int i = 0; i < dates.size(); i++) {
                value = value + sdf.format((Date)dates.get(i)) + "\n";
            }
            tbx.setValue(value);
        ]]></attribute>
    </calendar>
</zk>WeekPicker.java
package test.custom.component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Calendar;
public class WeekPicker extends Calendar {
    private static final long serialVersionUID = 7513083343273393743L;
    private List<Date> _selectedDates;
    static {
        addClientEvent(WeekPicker.class, "onCustomSelect", CE_IMPORTANT|CE_REPEAT_IGNORE|CE_NON_DEFERRABLE);
    }
    public List<Date> getSelectedDates () {
        return _selectedDates;
    }
    private void updateSelectedDates (int beforeCnt) {
        _selectedDates = new ArrayList<Date>();
        java.util.Calendar cal = java.util.Calendar.getInstance();
        // current selected date
        cal.setTime(getValue());
        // move to first day of the week
        cal.add(java.util.Calendar.DATE, (-1*beforeCnt));
        // add seven days to _selectedDates
        for (int i = 0; i < 7; i++) {
            _selectedDates.add(cal.getTime());
            cal.add(java.util.Calendar.DATE, 1);
        }
    }
    public void service(org.zkoss.zk.au.AuRequest request, boolean everError) {
        final String cmd = request.getCommand();
        if (cmd.equals("onCustomSelect")) {
            final Map<String, Object> data = request.getData();
            // get node count before selected date
            final Integer beforeCnt = (Integer)data.get("bcnt");
            // update selected dates
            updateSelectedDates(beforeCnt);
            // post event
            Events.postEvent("onCustomSelect", this, null);
        } else {
            super.service(request, everError);
        }
    }
}The Result
View demo on line
http://screencast.com/t/N35NM2T98yY
References
Calendar.js
https://github.com/zkoss/zk/blob/master/zul/src/archive/web/js/zul/db/Calendar.js
Calendar.java
https://github.com/zkoss/zk/blob/master/zul/src/org/zkoss/zul/Calendar.java
Client Side Programming
http://books.zkoss.org/wiki/Small_Talks/2010/April/Client_Side_Programming
The use, apply Attribute
http://books.zkoss.org/wiki/ZK_Developer%27s_Guide/Fundamental_ZK/ZK_User_Interface_Markup_Language/ZK_Attributes#The_use.2C_apply_Attribute
Download
calendar_as_week_picker.zul
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/WebContent/calendar_as_week_picker.zul
WeekPicker.java
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/src/test/custom/component/WeekPicker.java
Demo Flash
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/calendar_as_week_picker.swf
 
Good work.I have a question.I have a scenario let us suppose my application is open in a browser tab,and in second browser tab i have open a simple.html(right now its is inside my application) page where i have a button now i will want if i click on this button some event will fire into my application and a tab will be created inside my application which already open in browser .Can it possible with ZK?
ReplyDeleteThis is doable, you can use ajax call to load a zul page on a html button click, then set some data on a component onCreate in that zul page, and use Server push to check that data and create new tab.
Deleteplease refer to
http://ben-bai.blogspot.tw/2013/04/notify-zul-from-html.html
One more question i was tying to create a new component in zk by extending zk image component i have to support title and alt . how can i do it
ReplyDelete
DeleteYou can refer to some similar article
http://ben-bai.blogspot.tw/2012/08/zk-component-development-tutorial.html
http://ben-bai.blogspot.tw/2013/01/zk-datebox-customize-datebox-as.html
http://ben-bai.blogspot.tw/2013/01/extending-and-customizing-zk-component.html
but if you just want to set some native dom attribute, you can use Client Attribute property,
e.g.,
<zk xmlns:ca="client/attribute">
<image src="abc" ca:alt="image not found" ca:title="image title" />
</zk>
for more information, please refer to document
http://books.zkoss.org/wiki/ZUML_Reference/ZUML/Namespaces/Client_Attribute
For the 7 version of zk use (in the last comment):
ReplyDeletehttps://forum.zkoss.org/question/91254/how-to-display-week-selected-in-calendar/