basedatepicker.lzx
<library>
<include href="base/basedatepickerweek.lzx"/>
<include href="base/basecomponent.lzx"/>
<dataset name="datepicker_strings_en">
<months>
<month index="0" full="January" abr="Jan"/>
<month index="1" full="February" abr="Feb"/>
<month index="2" full="March" abr="Mar"/>
<month index="3" full="April" abr="Apr"/>
<month index="4" full="May" abr="May"/>
<month index="5" full="June" abr="Jun"/>
<month index="6" full="July" abr="Jul"/>
<month index="7" full="August" abr="Aug"/>
<month index="8" full="September" abr="Sep"/>
<month index="9" full="October" abr="Oct"/>
<month index="10" full="November" abr="Nov"/>
<month index="11" full="December" abr="Dec"/>
</months>
</dataset>
<class name="basedatepicker" extends="basecomponent">
<attribute name="daysinmonth" value="[ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
"/>
<attribute name="selecteddatepickerday" value="null
"/>
<attribute name="weekclass" when="once"/>
<attribute name="dayclass" when="once"/>
<attribute name="xinset" type="number" value="null
"/>
<attribute name="yinset" type="number" value="null
"/>
<attribute name="_focusDay" value="null
"/>
<attribute name="showingmonth" type="number" value="null
"/>
<attribute name="showingyear" type="number" value="null
"/>
<attribute name="showingdate" value="null
" type="expression"/>
<attribute name="latestdate" when="once" value="null
"/>
<attribute name="earliestdate" when="once" value="null
"/>
<attribute name="selecteddate" when="once" value="null
"/>
<attribute name="_basedatepicker_inited" type="boolean" value="false
"/>
<attribute name="_ignoreKeyUp" type="boolean" value="false
"/>
<method name="init">
super.init();
var todaysDate = new Date();
if( this.showingdate == null ) {
this.showingdate = new Date();
this.showingdate.setDate(1);
}
if( this.earliestdate == null ) {
this.earliestdate = new Date();
}
if( this.latestdate == null ) {
this.latestdate = new Date();
this.latestdate.setFullYear(this.latestdate.getFullYear() + 1);
}
if( this.xinset == null ) {
this.xinset = 0;
}
if( this.yinset == null ) {
this.yinset = 0;
}
//this.showingmonth = this.showingdate.getMonth();
//this.showingyear = this.showingdate.getFullYear();
for( var i = 0 ; i < 6 ; i++ ) {
var w = new weekclass(this.content, { dayclass : dayclass } );
}
this.content.bringToFront();
this.setMonthToShow( this.showingdate.getMonth(),
this.showingdate.getFullYear() );
this._basedatepicker_inited = true;
</method>
<method name="setSelecteddatepickerday" args="d">
if( this.selecteddatepickerday != null &&
d != this.selecteddatepickerday ) {
this.selecteddatepickerday.setAttribute('selected',false );
}
this.selecteddatepickerday = d;
//only set a new selected date if it has changed or wasn't yet set
var seldate = this.selecteddate;
if( seldate == null ||
(seldate.getDate() != d.daynum ||
seldate.getFullYear() != this.showingyear ||
seldate.getMonth() != this.showingmonth) ) {
this.setAttribute('selecteddate', new Date( this.showingyear,
this.showingmonth,
d.daynum ) );
}
</method>
<method name="setStartingDay" args="d,max">
var cd = 1 - d;
var earlydate = -10;
var latedate = 40;
var selectedDateOfMonth = -100;
// make sure currently selecteddate is marked as such if needed
if( this.selecteddate != null &&
this.selecteddate.getMonth() == this.showingmonth &&
this.selecteddate.getFullYear() == this.showingyear ) {
selectedDateOfMonth = this.selecteddate.getDate();
} else { //if selecteddate isn't in this month, clear
if( this.selecteddatepickerday != null) {
this.selecteddatepickerday.setAttribute('selected', false );
}
this.selecteddatepickerday = null;
}
if( earliestdate.getFullYear() == this.showingyear &&
earliestdate.getMonth() == this.showingmonth ) {
earlydate = earliestdate.getDate();
} else if (
(earliestdate.getFullYear() == this.showingyear &&
earliestdate.getMonth() < this.showingmonth ) ||
earliestdate.getFullYear() < this.showingyear ) {
earlydate = 1;
} else {
earlydate = 40;
}
if ( latestdate.getFullYear() == this.showingyear &&
latestdate.getMonth() == this.showingmonth ) {
latedate = latestdate.getDate();
} else if (
(latestdate.getFullYear() == this.showingyear &&
latestdate.getMonth() > this.showingmonth ) ||
latestdate.getFullYear() > this.showingyear) {
latedate = 40;
} else {
latedate = -10;
}
for( var i = 0 ; i < content.subviews.length ; i++ ) {
var w = content.subviews[i];
w.setStartingDay( cd,
max,
earlydate,
latedate );
//set basepickerday as selected
if( cd <= selectedDateOfMonth &&
(cd + 7) >= selectedDateOfMonth ) {
var bpd = selectedDateOfMonth - cd;
if (content && content.subviews && content.subviews[i] && content.subviews[i].subviews && content.subviews[i].subviews[bpd]) {
content.subviews[i].subviews[ bpd ].setAttribute(
'selected', true );
}
}
cd+=7;
}
</method>
<method name="setMonthToShow" args="newMonth,newYear">
// if we are trying to show the same month again OR
// null args have been passed and the component isn't being inited,
// return
if( this._basedatepicker_inited && (
(newYear == null || newMonth == null) ||
( this.showingmonth == newMonth
&& this.showingyear == newYear )
)
)
{
return;
}
var newDate = new Date( newYear, newMonth, 1 );
this.showingmonth = newMonth;
this.showingyear = newYear ;
this.setStartingDay( newDate.getDay(),
getNumberOfDaysInMonth(newMonth,newYear));
</method>
<method name="getNumberOfDaysInMonth" args="month,year">
var returnValue;
if( month == 1 ) {
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
returnValue = 29;
} else {
returnValue = 28;
}
} else {
returnValue = this.daysinmonth[ month ];
}
return returnValue;
</method>
<method name="handleKeyUp" args="k">
if( !this._ignoreKeyUp ) {
if( k == 13 ) {
content.subviews[this._focusDay[0]].subviews[this._focusDay[1]].buttonrelease();
}
} else {
this._ignoreKeyUp = false;
}
</method>
<method name="handleKeyDown" args="k">
if( k == 37 ) {
this.focusPreviousDay();
}
else if ( k == 38 ) {
this.focusPreviousWeek();
}
else if ( k == 39 ) {
this.focusNextDay();
}
else if ( k == 40 ) {
this.focusNextWeek();
} else if ( k == 13 ) {
this.selectFocusDay();
content.subviews[this._focusDay[0]].subviews[this._focusDay[1]].buttonpush();
}
</method>
<method name="focusOnFirstDayInMonth">
var focusDay = content.subviews[0].getFirstDayInMonth();
this.focusOnDay( 0, focusDay );
return [ 0, focusDay ];
</method>
<method name="focusOnLastDayInMonth">
var ld = this.getLastDayInMonth();
this.focusOnDay( ld[0], ld[1] );
</method>
<method name="selectFocusDay">
this.content.subviews[
this._focusDay[0] ].subviews[ this._focusDay[1]
].setAttribute('selected', true );
</method>
<method name="isDayDisabled" args="week,day">
return this.content.subviews[week].subviews[day].disabled;
</method>
<method name="focusOnDay" args="week,day">
if( this._focusDay != null ) {
if( !content.subviews[ week ].subviews[day].selectable ) {
return;
} else {
this.removeFocusFromDay( this._focusDay[0], this._focusDay[1] );
}
}
content.subviews[ week ].focusOnDay(day);
this._focusDay = [ week, day ];
</method>
<method name="removeFocusFromDay" args="week,day">
this.content.subviews[ week ].removeFocusFromDay(day);
</method>
<method name="focusPreviousDay">
if( this.content.subviews[ this._focusDay[0] ].isFirstDayInMonth( this._focusDay[1] ) ) {
this.showPreviousMonth();
this.focusOnLastDayInMonth();
} else {
if( this._focusDay[1] == 0 ) { //is this the first
//week of the month?
this.focusOnDay( this._focusDay[0] - 1, 6 );
} else {
this.focusOnDay( this._focusDay[0], this._focusDay[1] - 1 );
}
}
</method>
<method name="focusNextDay">
if( content.subviews[ this._focusDay[0] ].isLastDayInMonth(this._focusDay[1]) ) {
this.showNextMonth();
this.focusOnFirstDayInMonth();
} else {
if( this._focusDay[1] < 6 ) {
this.focusOnDay( this._focusDay[0], this._focusDay[1] + 1 );
} else {
this.focusOnDay( this._focusDay[0] + 1, 0 );
}
}
</method>
<method name="focusNextWeek">
if( this.isLastWeekInMonth( this._focusDay[0] ) ) {
this.showNextMonth();
this.focusOnFirstDayInMonth();
}
else {
if( this.isDayDisabled( this._focusDay[0] + 1 , this._focusDay[1] ) ) {
this.focusOnLastDayInMonth();
} else {
this.focusOnDay( this._focusDay[0] + 1, this._focusDay[1] );
}
}
</method>
<method name="focusPreviousWeek">
if( this._focusDay[0] == 0 ) {
this.showPreviousMonth();
this.focusOnLastDayInMonth();
} else {
if( this.isDayDisabled( this._focusDay[0] - 1, this._focusDay[1] ) ) {
this.focusOnFirstDayInMonth();
} else {
this.focusOnDay( this._focusDay[0] - 1, this._focusDay[1] );
}
}
</method>
<method name="showNextMonth">
if( this.showingmonth == 11 ) {
var newYear = Number(this.showingyear) + 1;
this.setMonthToShow( 0, newYear );
} else {
var newMonth = Number( this.showingmonth ) + 1;
this.setMonthToShow( newMonth, this.showingyear );
this.focusOnFirstDayInMonth();
}
</method>
<method name="showPreviousMonth">
if( this.showingmonth == 0 ) {
this.setMonthToShow( 11, this.showingyear - 1 );
} else {
this.setMonthToShow( this.showingmonth - 1, this.showingyear );
}
</method>
<method name="isLastWeekInMonth" args="w">
var returnValue;
if( content.subviews[w].subviews[6].disabled ||
content.subviews[w].subviews[6].daynum ==
this.getNumberOfDaysInMonth( this.showingmonth,
this.showingyear ) ) {
returnValue = true;
} else {
returnValue = false;
}
return returnValue;
</method>
<method name="getLastDayInMonth">
var returnValue;
for( var i = 5 ; i >= 0 ; i-- ) {
var cur = this.content.subviews[i].getLastDayInMonth();
if( cur != -1 ) {
returnValue = [ i, cur ];
break;
}
}
return returnValue;
</method>
<handler name="onshowingmonth">
this.showingdate.setMonth( this.showingmonth );
</handler>
<handler name="onshowingyear">
this.showingdate.setYear( this.showingyear );
</handler>
<handler name="onkeydown" reference="lz.Keys" args="k">
if ( content.hasfocus ) {
this.handleKeyDown(k);
}
</handler>
<handler name="onkeyup" reference="lz.Keys" args="k">
if ( content.hasfocus ) {
this.handleKeyUp(k);
}
</handler>
<handler name="onblur" reference="this.content">
this.removeFocusFromDay( this._focusDay[0], this._focusDay[1] );
</handler>
<handler name="onfocus" reference="this.content">
if( this._focusDay == null ) {
this.focusOnFirstDayInMonth();
} else {
this.focusOnDay( this._focusDay[0], this._focusDay[1] );
}
</handler>
<view name="content" x="${classroot.xinset}" y="${classroot.yinset}" focusable="true">
<attribute name="hasfocus" type="boolean" value="false
"/>
<handler name="onfocus">
this.hasfocus = true;
</handler>
<handler name="onblur">
this.hasfocus = false;
</handler>
</view>
<doc>
<tag name="shortdesc"><text>An abstract date picker.</text></tag>
<text>
<p>
Basedatepicker is an abstract class from which you can build a fully
functional month-based datepicker from. When creating an implementation of
the basedatepicker, it is expected that certain methods from basedatepicker,
basedatepickerday and basedatepickerweek will be overridden to provide full
functionality of a datepicker. For datepicker, these methods include
doSpaceUp(), doEnterUp(), and optionally setMonthToShow(). See the source code of
datepicker for a more extensive example. See also <xref linkend="lz.basedatepickerday"/> and <xref linkend="lz.basedatepickerweek"/>
</p>
<example class="program" id="basedatepicker-1">
<canvas height="200">
<class name="myday"
extends="basedatepickerday"
bgcolor="green"
width="20"
height="20">
<handler name="onclick">
<![CDATA[
if( !this.disabled ) {
this.setAttribute('selected', true);
}
]]>
</handler>
<text text="${parent.daynum}"
visible="${!parent.disabled}"
opacity="${parent.selectable ? 1 : .3 }"/>
</class>
<class name="myweek" extends="basedatepickerweek">
<simplelayout axis="x" spacing="1"/>
</class>
<class name="mydatepicker"
extends="basedatepicker"
weekclass="lz.myweek"
dayclass="lz.myday"
xinset="0"
yinset="0">
<method name="setMonthToShow" args="month, year">
super.setMonthToShow(month,year);
this.display.month.datapath.setXPath(
"datepicker_strings_en:/months/month[@index='" + month + "']/@full" );
this.display.year.setAttribute('text', year );
</method>
<handler name="onselecteddate">
if( this.selecteddate != null ) {
this.selected.year.setAttribute('text', this.selecteddate.getFullYear() );
this.selected.month.datapath.setXPath(
"datepicker_strings_en:/months/month[@index='" +
this.selecteddate.getMonth() + "']/@full" );
this.selected.date.setAttribute('text', this.selecteddate.getDate() );
}
</handler>
<view options="ignorelayout">
<text width="20" height="20" bgcolor="red" text="S"/>
<text width="20" height="20" bgcolor="red" text="M"/>
<text width="20" height="20" bgcolor="red" text="T"/>
<text width="20" height="20" bgcolor="red" text="W"/>
<text width="20" height="20" bgcolor="red" text="T"/>
<text width="20" height="20" bgcolor="red" text="F"/>
<text width="20" height="20" bgcolor="red" text="S"/>
<simplelayout axis="x" spacing="1"/>
</view>
<view>
<button text="previous" onclick="classroot.showPreviousMonth()"/>
<button text="next" onclick="classroot.showNextMonth()"/>
<simplelayout axis="x"/>
</view>
<view name="display">
<text> Showing: </text>
<text name="month" datapath="." resize="true"/>
<text name="year" resize="true"/>
<simplelayout axis="x" spacing="2"/>
</view>
<view name="selected">
<text> Selected: </text>
<text name="month" datapath="." resize="true"/>
<text name="date" resize="true"/>
<text name="year" resize="true"/>
<simplelayout axis="x" spacing="2"/>
</view>
<simplelayout axis="y" placement="content" spacing="1" inset="20"/>
<simplelayout axis="y"/>
</class>
<mydatepicker/>
</canvas>
</example>
</text>
</doc>
</class>
</library>
Cross References
Includes
Classes
Named Instances