Introduction
This article reply to Senthil's blog post (http://emrpms.blogspot.in/2013/01/zk-datebox-customize-datebox-as.html), describe how to define a custom component that extends ZK component and do customization as needed.
Pre-request
The yearbox/monthbox customization by client side programming
http://ben-bai.blogspot.tw/2013/01/zk-datebox-customize-datebox-as.html
The basic tutorial of how to create a component
http://ben-bai.blogspot.tw/2012/08/zk-component-development-tutorial.html
Project Structure
We specify src and src/archive as two source folders separately.
src for .java files (not used in this sample)
src/archive for others (lang-addon.xml, .js, .wpd and .css.dsp)
The Program
lang-addon.xml
Define all component here, since we put it in the location that will be loaded by ZK automatically so no need to specify it in zk.xml.
<!-- Tested with ZK 6.0.2 -->
<language-addon>
<addon-name>customDatebox</addon-name>
<language-name>xul/html</language-name>
<!-- It specifies what language addons this addon
depends on. If specified, this addon will be
parsed after all the specified addons are parsed -->
<depends>zul</depends>
<!-- define yearbox -->
<component>
<component-name>yearbox</component-name>
<!-- extends datebox component,
this denotes using all files (java/js/css.dsp)
of the original datebox by default if
no other file(s) specified -->
<extends>datebox</extends>
<!-- specify custom widget class file -->
<widget-class>custom.zk.components.Yearbox</widget-class>
</component>
<!-- define monthbox -->
<component>
<component-name>monthbox</component-name>
<!-- extends datebox component,
this denotes using all files (java/js/css.dsp)
of the original datebox by default if
no other file(s) specified -->
<extends>datebox</extends>
<!-- specify custom widget class file -->
<widget-class>custom.zk.components.Monthbox</widget-class>
</component>
</language-addon>
zk.wpd
Define the dependency and loading sequence
<!-- Tested with ZK 6.0.2 -->
<!-- note the depends attribute should be zul.db
since ZK supports load package on demand
will not load all recuired package if you only
specify zul
according to lang.xml in zul project, it more
likely just load zul and zul.wgt by default -->
<package name="custom.zk.components" language="xul/html" depends="zul.db">
<widget name="Yearbox" />
<widget name="Monthbox" />
<script src="override.js"/>
</package>
Yearbox.js
The customized widget class for yearbox, simply extends original datebox since what we need is only the widget class "custom.zk.components.Yearbox" so we can use the API widget.$instanceof to detect whether a calendar pop is belongs to a yearbox.
//
// Tested with ZK 6.0.2
//
(function () {
// simply extends Datebox,
// what we need is only the widget class
// custom.zk.components.Yearbox
custom.zk.components.Yearbox = zk.$extends(zul.db.Datebox, {
});
})();
Monthbox.js
The customized widget class for monthbox, simply extends original datebox since what we need is only the widget class "custom.zk.components.Monthbox" so we can use the API widget.$instanceof to detect whether a calendar pop is belongs to a monthbox.
//
// Tested with ZK 6.0.2
//
(function () {
// simply extends Datebox,
// what we need is only the widget class
// custom.zk.components.Monthbox
custom.zk.components.Monthbox = zk.$extends(zul.db.Datebox, {
});
})();
override.js
Override zul.db.CalendarPop here, change default action according to the parent's class of calendar pop. We use the API widget.$instanceof to detect whether a calendar pop is belongs to a yearbox or a monthbox.
zk.afterLoad("zul.db", function () {
// Datebox Calendar Renderer
var _Cwgt = {};
zk.override(zul.db.CalendarPop.prototype, _Cwgt, {
// switch the view after redraw or open as needed
redraw: function (out) {
_Cwgt.redraw.apply(this, arguments); //call the original method
this._customChangeView ();
},
open: function (silent) {
_Cwgt.open.apply(this, arguments); //call the original method
this._customChangeView ();
},
_customChangeView: function () {
// cannot show month/day
if (this._isYearboxCalPop()) {
var view = this._view;
// switch to year view as needed
if (view == 'month' || view == 'day')
this._setView("year");
} else if (this._isMonthboxCalPop()) {
// cannot show day view
// switch to month view as needed
if (this._view == 'day')
this._setView("month");
}
},
// customize the chooseDate function
_chooseDate: function (target, val) {
var view = this._view;
if (this._isYearboxCalPop()
|| this._isMonthboxCalPop()) {
// do customize chooseDate if the parent (datebox)
// has specific class
var date = this.getTime(),
year = (view == 'decade' || view == 'year')? val : date.getFullYear(),
month = view == 'month'? val : 0;
// set date value
this._setTime(year, month, 1);
if (view == 'decade') {
// switch to year view if at decade view
this._setView("year");
} else if (this._isMonthboxCalPop()
&& view == 'year') {
// switch to month view if at year view and the month view is allowed
this._setView("month");
} else if (this._isMonthboxCalPop() && view == 'month'
|| this._isYearboxCalPop() && view == 'year') {
// close calendar and update value if already at the smallest allowed view
this.close();
this.parent.updateChange_();
}
} else {
_Cwgt._chooseDate.apply(this, arguments); //call the original method
}
},
_isYearboxCalPop: function () {
return this.parent.$instanceof(custom.zk.components.Yearbox);
},
_isMonthboxCalPop: function () {
return this.parent.$instanceof(custom.zk.components.Monthbox);
}
});
});
index.zul
Test page
<zk>
<vbox>
<label value="yearbox" />
<yearbox format="yyyy">
<attribute name="onChange"><![CDATA[
Date date = self.getValue();
alert("Year: " + (date.getYear()+1900));
]]></attribute>
</yearbox>
<label value="monthbox" />
<monthbox format="yyyy-MM">
<attribute name="onChange"><![CDATA[
Date date = self.getValue();
alert("Year: " + (date.getYear()+1900) + "\n"
+ "Month: " + (date.getMonth()+1));
]]></attribute>
</monthbox>
</vbox>
</zk>
The Result
The result is the same as http://ben-bai.blogspot.tw/2013/01/zk-datebox-customize-datebox-as.html
Reference
Datebox.js
https://github.com/zkoss/zk/blob/6.0/zul/src/archive/web/js/zul/db/Datebox.js
lang.xml in Zul project
https://github.com/zkoss/zk/blob/6.0/zul/src/archive/metainfo/zk/lang.xml
Download
Full project at github
https://github.com/benbai123/ZK_Practice/tree/master/Components/projects/Components_Customization/DateboxCustomization
Thanks a lot
ReplyDeleteNo problem, I'm happy to be helpful :)
DeleteAgain me, please refer the following forum thread.
ReplyDeletehttp://forum.zkoss.org/question/86736/masked-input-component/
http://forum.zkoss.org/question/65608/watermark-and-masks-dont-work-on-textboxes-in-mold-rounded/
Hi Ben
ReplyDeleteI am trying to use new ZK 7 Navigation bar component for my new project. Look at the following post in my blog
http://emrpms.blogspot.in/2013/09/zk-dynamic-menu-part-5.html
In the above, i have used group box and toolbar as left navigation bar and created dynamically.
I am just trying to replace the left navigation with new ZK 7 Nav Bar. But not sure whether it supports children binding and template concept ?
Actually I'm also not sure since ZK7 still under RC version and probably will be changed if needed, I'd suggest postpone your upgrade process for now.
DeleteThis monthbox and yearbox solution seems not work at the latest ZK7,
ReplyDeleteAfter selecting month,then the box is still empty!
Yes, dom structure changed in ZK7, almost need to redo all customization for ZK7.
Deleteman, your tutorial is very incomplete for new learners it can't be used at all.
ReplyDeleteYes, this article is for limited target audience that already know some knowledge of ZK (especially the complex structure of component definition), you probably need some other background knowledge to understand this article.
DeleteHi Ben this is a great example. I need to ask you a thing like what changes do I need to make for making Datebox use Hijri calendar instead of default(GregorianCalendar)
ReplyDeleteDo you mean thai buddhist calendar? If so, you need to set th_TH locale,
Deletee.g.,
<datebox locale="th_TH"/>
I mean this chronology (http://joda-time.sourceforge.net/cal_islamic.html)
Deleteinstead of default GregorianCalendar the datebox must use Islamic calendar
I guess this is not implemented yet, you can ask a new feature at http://tracker.zkoss.org/secure/IssueNavigator.jspa?mode=hide&requestId=10002
DeleteIs there a way I can implement that feature I mean can u suggest me anything so that Datebox will use Islamic calendar by default instead of GregorianCalendar
DeleteYes, but it is very difficult.
DeleteYou need to override/extend ZK's date formatter and client side renderer, they are very complex
You can also ask on ZK Forum for more information
http://forum.zkoss.org/questions/
This is really helpful and informative, as this gave me more insight to create more ideas and solutions for my plan.
ReplyDeleteAre you believing that a Mobile App Ideas is costly? The App Ideas is leading web and Mobile App development. We provide the best IT Services at best rates. Contact us now!