Ext JS provides a date field component for taking date input on forms.
This component only accepts a date value. What if there is a requirement to accept some other value, e.g. "Not Provided". You have to keep the field blank, as entering "Not Provided" results into validation error.
DatePicker.js
Datefield.js
This component only accepts a date value. What if there is a requirement to accept some other value, e.g. "Not Provided". You have to keep the field blank, as entering "Not Provided" results into validation error.
But keeping a field blank will make the allowBlank : false validation fail. How to allow the user to submit the form at the same time ensuring that s/he has provided a correct value for date field (including "Not Provided").
To resolve this challenge, we have customized the date picker and date field provided by Ext JS framework to include a feature to have "Not Provided" button and to consider "Not Provided" as a valid data. The new date picker which we call as 'techmights-datefield' looks as follows.
The user can click on "Not Provided" if the s/he doesn't wants to enter a date. The "Not Provided" value will be considered valid for this field.
The code for customized date picker and date field controls is as follows.
DatePicker.js
Ext.define('TMS.view.DatePicker',
{
extend : 'Ext.picker.Date',
NPBtn : undefined,
NPText : "Not Provided",
renderTpl: [
'<div id="{id}-innerEl" role="grid">',
'<div role="presentation" class="{baseCls}-header">',
// the href attribute is required for the :hover selector to work in IE6/7/quirks
'<a id="{id}-prevEl" class="{baseCls}-prev {baseCls}-arrow" href="#" role="button" title="{prevText}" hidefocus="on" ></a>',
'<div class="{baseCls}-month" id="{id}-middleBtnEl">{%this.renderMonthBtn(values, out)%}</div>',
// the href attribute is required for the :hover selector to work in IE6/7/quirks
'<a id="{id}-nextEl" class="{baseCls}-next {baseCls}-arrow" href="#" role="button" title="{nextText}" hidefocus="on" ></a>',
'</div>',
'<table id="{id}-eventEl" class="{baseCls}-inner" cellspacing="0" role="grid">',
'<thead role="presentation"><tr role="row">',
'<tpl for="dayNames">',
'<th role="columnheader" class="{parent.baseCls}-column-header" title="{.}">',
'<div class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>',
'</th>',
'</tpl>',
'</tr></thead>',
'<tbody role="presentation"><tr role="row">',
'<tpl for="days">',
'{#:this.isEndOfWeek}',
'<td role="gridcell" id="{[Ext.id()]}">',
// the href attribute is required for the :hover selector to work in IE6/7/quirks
'<a role="presentation" hidefocus="on" class="{parent.baseCls}-date" href="#"></a>',
'</td>',
'</tpl>',
'</tr></tbody>',
'</table>',
'<div id="{id}-footerEl" role="presentation" class="{baseCls}-footer">{%this.renderNPBtn(values, out)%}',
'<tpl if="showToday">',
'{%this.renderTodayBtn(values, out)%}',
'</tpl>',
'</div>',
'</div>',
{
firstInitial: function(value) {
return Ext.picker.Date.prototype.getDayInitial(value);
},
isEndOfWeek: function(value) {
// convert from 1 based index to 0 based
// by decrementing value once.
value--;
var end = value % 7 === 0 && value !== 0;
return end ? '</tr><tr role="row">' : '';
},
renderTodayBtn: function(values, out) {
Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out);
},
renderMonthBtn: function(values, out) {
Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out);
},
renderNPBtn: function(values, out) {
Ext.DomHelper.generateMarkup(values.$comp.NPBtn.getRenderTree(), out);
},
}
],
beforeRender: function ()
{
var me = this;
me.NPBtn = new Ext.button.Button({
ownerCt: me,
ownerLayout: me.getComponentLayout(),
text: me.NPText,
tooltip: me.NPBtn,
tooltipType: 'title',
handler: me.selectNP,
scope: me
});
me.callParent();
},
finishRenderChildren: function () {
var me = this;
me.callParent();
me.NPBtn.finishRender();
},
/**
* Sets the value to "Not Provided".
* @return {Ext.picker.Date} this
*/
selectNP : function(){
var me = this,
btn = me.NPBtn,
handler = me.handler;
if(btn && !btn.disabled){
me.setValue(me.NPText);
me.fireEvent('select', me, me.value);
if (handler) {
handler.call(me.scope || me, me, me.value);
}
me.onSelect();
}
return me;
},
/**
* Sets the value of the date field
* @param {Date} value The date to set or "Not Provided"
* @return {Ext.picker.Date} this
*/
setValue : function(value){
if(value != this.NPText)
this.value = Ext.Date.clearTime(value, true);
else
this.value = value;
return this.update(this.value);
},
/**
* Update the contents of the picker
* @private
* @param {Date} date The new date or "Not Provided"
* @param {Boolean} forceRefresh True to force a full refresh
*/
update : function(date, forceRefresh)
{
var me = this,
active = me.activeDate;
if (me.rendered)
{
if(date != me.NPText)
{
me.activeDate = date;
if(!forceRefresh && active && me.el && active.getMonth() == date.getMonth() && active.getFullYear() == date.getFullYear()){
me.selectedUpdate(date, active);
} else {
me.fullUpdate(date, active);
}
}
}
return me;
}
});
Datefield.js
Ext.define('TMS.view.DateField',
{
extend : 'Ext.form.field.Date',
alias : 'widget.techmights-datefield',
requires: ['TMS.view.DatePicker'],
NPText : "Not Provided",
createPicker: function() {
var me = this,
format = Ext.String.format;
return new TMS.view.DatePicker({
pickerField: me,
ownerCt: me.ownerCt,
renderTo: document.body,
floating: true,
hidden: true,
focusOnShow: true,
minDate: me.minValue,
maxDate: me.maxValue,
disabledDatesRE: me.disabledDatesRE,
disabledDatesText: me.disabledDatesText,
disabledDays: me.disabledDays,
disabledDaysText: me.disabledDaysText,
format: me.format,
showToday: me.showToday,
startDay: me.startDay,
minText: format(me.minText, me.formatDate(me.minValue)),
maxText: format(me.maxText, me.formatDate(me.maxValue)),
listeners: {
scope: me,
select: me.onSelect
},
keyNavConfig: {
esc: function() {
me.collapse();
}
}
});
},
rawToValue: function(rawValue) {
if(rawValue === this.NPText)
return rawValue;
return this.parseDate(rawValue) || rawValue || null;
},
valueToRaw: function(value) {
if(value === this.NPText)
return value;
return this.formatDate(this.parseDate(value));
},
getErrors: function(value) {
var me = this;
var errors = me.callParent(arguments);
if(!Ext.isEmpty(value) && value.toUpperCase() == me.NPText.toUpperCase())
return ((errors.length>2) ? [errors[0]] : [] );
return errors;
}
});



No comments:
Post a Comment
Your comments are very much valuable for us. Thanks for giving your precious time.