webshims.register('forms-picker', function($, webshims, window, document, undefined, options){
"use strict";
var picker = webshims.picker;
var actions = picker._actions;
var moduleOpts = options;
var getDateArray = function(date){
var ret = [date.getFullYear(), moduleOpts.addZero(date.getMonth() + 1), moduleOpts.addZero(date.getDate())];
ret.month = ret[0]+'-'+ret[1];
ret.date = ret[0]+'-'+ret[1]+'-'+ret[2];
return ret;
};
var today = getDateArray(new Date(new Date().getTime() - (new Date().getTimezoneOffset() * 60 * 1000 )));
var _setFocus = function(element, _noFocus){
element = $(element || this.activeButton);
this.activeButton.attr({tabindex: '-1', 'aria-selected': 'false'});
this.activeButton = element.attr({tabindex: '0', 'aria-selected': 'true'});
this.index = this.buttons.index(this.activeButton[0]);
clearTimeout(this.timer);
picker._genericSetFocus.apply(this, arguments);
};
var _initialFocus = function(){
var sel;
if(this.popover.navedInitFocus){
sel = this.popover.navedInitFocus.sel || this.popover.navedInitFocus;
if((!this.activeButton || !this.activeButton[0]) && this.buttons[sel]){
this.activeButton = this.buttons[sel]();
} else if(sel){
this.activeButton = $(sel, this.element);
}
if(!this.activeButton[0] && this.popover.navedInitFocus.alt){
this.activeButton = this.buttons[this.popover.navedInitFocus.alt]();
}
}
if(!this.activeButton || !this.activeButton[0]){
this.activeButton = this.buttons.filter('.checked-value');
}
if(!this.activeButton[0]){
this.activeButton = this.buttons.filter('.this-value');
}
if(!this.activeButton[0]){
this.activeButton = this.buttons.eq(0);
}
this.setFocus(this.activeButton, this.opts.noFocus);
};
var formcfg = webshims.formcfg;
var curCfg = formcfg[$.webshims.activeLang()] || formcfg[''];
$.webshims.activeLang({
register: 'form-core',
callback: function(){
$.each(arguments, function(i, val){
if(formcfg[val]){
curCfg = formcfg[val];
return false;
}
});
}
});
webshims.ListBox = function (element, popover, opts){
this.element = $('ul', element);
this.popover = popover;
this.opts = opts || {};
this.buttons = $('button:not(:disabled)', this.element);
this.ons(this);
this._initialFocus();
};
webshims.ListBox.prototype = {
setFocus: _setFocus,
_initialFocus: _initialFocus,
prev: function(){
var index = this.index - 1;
if(index < 0){
if(this.opts.prev){
this.popover.navedInitFocus = 'last';
this.popover.actionFn(this.opts.prev);
this.popover.navedInitFocus = false;
}
} else {
this.setFocus(this.buttons.eq(index));
}
},
next: function(){
var index = this.index + 1;
if(index >= this.buttons.length){
if(this.opts.next){
this.popover.navedInitFocus = 'first';
this.popover.actionFn(this.opts.next);
this.popover.navedInitFocus = false;
}
} else {
this.setFocus(this.buttons.eq(index));
}
},
ons: function(that){
this.element
.on({
'keydown': function(e){
var handled;
var key = e.keyCode;
if(e.ctrlKey){return;}
if(key == 36 || key == 33){
that.setFocus(that.buttons.eq(0));
handled = true;
} else if(key == 34 || key == 35){
that.setFocus(that.buttons.eq(that.buttons.length - 1));
handled = true;
} else if(key == 38 || key == 37){
that.prev();
handled = true;
} else if(key == 40 || key == 39){
that.next();
handled = true;
}
if(handled){
return false;
}
}
})
;
}
};
webshims.Grid = function (element, popover, opts){
this.element = $('tbody', element);
this.popover = popover;
this.opts = opts || {};
this.buttons = $('button:not(:disabled,.othermonth)', this.element);
this.ons(this);
this._initialFocus();
if(this.popover.openedByFocus){
this.popover.activeElement = this.activeButton;
}
};
webshims.Grid.prototype = {
setFocus: _setFocus,
_initialFocus: _initialFocus,
first: function(){
this.setFocus(this.buttons.eq(0));
},
last: function(){
this.setFocus(this.buttons.eq(this.buttons.length - 1));
},
upPage: function(){
$('.ws-picker-header > button:not(:disabled)', this.popover.element).trigger('click');
},
downPage: function(){
this.activeButton.filter(':not([data-action="changeInput"])').trigger('click');
},
ons: function(that){
this.element
.on({
'keydown': function(e){
var handled;
var key = e.keyCode;
if(e.shiftKey){return;}
if((e.ctrlKey && key == 40)){
handled = 'downPage';
} else if((e.ctrlKey && key == 38)){
handled = 'upPage';
} else if(key == 33 || (e.ctrlKey && key == 37)){
handled = 'prevPage';
} else if(key == 34 || (e.ctrlKey && key == 39)){
handled = 'nextPage';
} else if(e.keyCode == 36 || e.keyCode == 33){
handled = 'first';
} else if(e.keyCode == 35){
handled = 'last';
} else if(e.keyCode == 38){
handled = 'up';
} else if(e.keyCode == 37){
handled = 'prev';
} else if(e.keyCode == 40){
handled = 'down';
} else if(e.keyCode == 39){
handled = 'next';
}
if(handled){
that[handled]();
return false;
}
}
})
;
}
};
$.each({
prevPage: {get: 'last', action: 'prev'},
nextPage: {get: 'first', action: 'next'}
}, function(name, val){
webshims.Grid.prototype[name] = function(){
if(this.opts[val.action]){
this.popover.navedInitFocus = {
sel: 'button[data-id="'+ this.activeButton.attr('data-id') +'"]:not(:disabled,.othermonth)',
alt: val.get
};
this.popover.actionFn(this.opts[val.action]);
this.popover.navedInitFocus = false;
}
};
});
$.each({
up: {traverse: 'prevAll', get: 'last', action: 'prev', reverse: true},
down: {traverse: 'nextAll', get: 'first', action: 'next'}
}, function(name, val){
webshims.Grid.prototype[name] = function(){
var cellIndex = this.activeButton.closest('td').prop('cellIndex');
var sel = 'td:nth-child('+(cellIndex + 1)+') button:not(:disabled,.othermonth)';
var button = this.activeButton.closest('tr')[val.traverse]();
if(val.reverse){
button = $(button.get().reverse());
}
button = button.find(sel)[val.get]();
if(!button[0]){
if(this.opts[val.action]){
this.popover.navedInitFocus = sel+':'+val.get;
this.popover.actionFn(this.opts[val.action]);
this.popover.navedInitFocus = false;
}
} else {
this.setFocus(button.eq(0));
}
};
});
$.each({
prev: {traverse: 'prevAll',get: 'last', reverse: true},
next: {traverse: 'nextAll', get: 'first'}
}, function(name, val){
webshims.Grid.prototype[name] = function(){
var sel = 'button:not(:disabled,.othermonth)';
var button = this.activeButton.closest('td')[val.traverse]('td');
if(val.reverse){
button = $(button.get().reverse());
}
button = button.find(sel)[val.get]();
if(!button[0]){
button = this.activeButton.closest('tr')[val.traverse]('tr');
if(val.reverse){
button = $(button.get().reverse());
}
button = button.find(sel)[val.get]();
}
if(!button[0]){
if(this.opts[name]){
this.popover.navedInitFocus = val.get;
this.popover.actionFn(this.opts[name]);
this.popover.navedInitFocus = false;
}
} else {
this.setFocus(button.eq(0));
}
};
});
//taken from jquery ui
picker.getWeek = function(date){
var time;
var checkDate = new Date(date.getTime());
checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
time = checkDate.getTime();
checkDate.setMonth(0);
checkDate.setDate(1);
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
};
picker.getYearList = function(value, data){
var j, i, val, disabled, lis, prevDisabled, nextDisabled, classStr, classArray, start;
var size = data.options.size;
var max = data.options.max.split('-');
var min = data.options.min.split('-');
var currentValue = data.options.value.split('-');
var xthCorrect = 0;
var enabled = 0;
var str = '';
var rowNum = 0;
if(data.options.useDecadeBase == 'max' && max[0]){
xthCorrect = 11 - (max[0] % 12);
} else if(data.options.useDecadeBase == 'min' && min[0]){
xthCorrect = 11 - (min[0] % 12);
}
value = value[0] * 1;
start = value - ((value + xthCorrect) % (12 * size));
for(j = 0; j < size; j++){
if(j){
start += 12;
} else {
prevDisabled = picker.isInRange([start-1], max, min) ? {'data-action': 'setYearList','value': start-1} : false;
}
str += '
';
lis = [];
for(i = 0; i < 12; i++){
val = start + i ;
classArray = [];
if( !picker.isInRange([val], max, min) ){
disabled = ' disabled=""';
} else {
disabled = '';
enabled++;
}
if(val == today[0]){
classArray.push('this-value');
}
if(currentValue[0] == val){
classArray.push('checked-value');
}
classStr = classArray.length ? ' class="'+ (classArray.join(' ')) +'"' : '';
if(i && !(i % 3)){
rowNum++;
lis.push('
');
}
lis.push(' | ');
}
if(j == size - 1){
nextDisabled = picker.isInRange([val+1], max, min) ? {'data-action': 'setYearList','value': val+1} : false;
}
str += '';
}
return {
enabled: enabled,
main: str,
next: nextDisabled,
prev: prevDisabled,
type: 'Grid'
};
};
picker.getMonthList = function(value, data){
var j, i, name, val, disabled, lis, fullyDisabled, prevDisabled, nextDisabled, classStr, classArray;
var o = data.options;
var size = o.size;
var max = o.max.split('-');
var min = o.min.split('-');
var currentValue = o.value.split('-');
var enabled = 0;
var rowNum = 0;
var str = '';
value = value[0] - Math.floor((size - 1) / 2);
for(j = 0; j < size; j++){
if(j){
value++;
} else {
prevDisabled = picker.isInRange([value-1], max, min) ? {'data-action': 'setMonthList','value': value-1} : false;
}
if(j == size - 1){
nextDisabled = picker.isInRange([value+1], max, min) ? {'data-action': 'setMonthList','value': value+1} : false;
}
lis = [];
if( !picker.isInRange([value, '01'], max, min) && !picker.isInRange([value, '12'], max, min)){
disabled = ' disabled=""';
fullyDisabled = true;
} else {
fullyDisabled = false;
disabled = '';
}
if(o.minView >= 1){
disabled = ' disabled=""';
}
str += '';
for(i = 0; i < 12; i++){
val = curCfg.date.monthkeys[i+1];
name = (curCfg.date[o.monthNames] || curCfg.date.monthNames)[i];
classArray = [];
if(fullyDisabled || !picker.isInRange([value, val], max, min) ){
disabled = ' disabled=""';
} else {
disabled = '';
enabled++;
}
if(value == today[0] && today[1] == val){
classArray.push('this-value');
}
if(currentValue[0] == value && currentValue[1] == val){
classArray.push('checked-value');
}
classStr = (classArray.length) ? ' class="'+ (classArray.join(' ')) +'"' : '';
if(i && !(i % 3)){
rowNum++;
lis.push('
');
}
lis.push(' | ');
}
str += '';
}
return {
enabled: enabled,
main: str,
prev: prevDisabled,
next: nextDisabled,
type: 'Grid'
};
};
picker.getDayList = function(value, data){
var j, i, k, day, nDay, name, val, disabled, lis, prevDisabled, nextDisabled, addTr, week, rowNum;
var lastMotnh, curMonth, otherMonth, dateArray, monthName, fullMonthName, buttonStr, date2, classArray;
var o = data.options;
var size = o.size;
var max = o.max.split('-');
var min = o.min.split('-');
var currentValue = o.value.split('-');
var monthNames = curCfg.date[o.monthNamesHead] || curCfg.date[o.monthNames] || curCfg.date.monthNames;
var enabled = 0;
var str = [];
var date = new Date(value[0], value[1] - 1, 1);
date.setMonth(date.getMonth() - Math.floor((size - 1) / 2));
for(j = 0; j < size; j++){
date.setDate(1);
lastMotnh = date.getMonth();
rowNum = 0;
if(!j){
date2 = new Date(date.getTime());
date2.setDate(-1);
dateArray = getDateArray(date2);
prevDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray[0]+'-'+dateArray[1]} : false;
}
dateArray = getDateArray(date);
str.push('');
if(data.options.showWeek){
str.push('');
}
for(k = curCfg.date.firstDay; k < curCfg.date.dayNamesShort.length; k++){
str.push(''+ curCfg.date.dayNamesShort[k] +' | ');
}
k = curCfg.date.firstDay;
while(k--){
str.push(''+ curCfg.date.dayNamesShort[k] +' | ');
}
str.push('
');
if(data.options.showWeek) {
week = picker.getWeek(date);
str.push(''+ week +' | ');
}
for (i = 0; i < 99; i++) {
addTr = (i && !(i % 7));
curMonth = date.getMonth();
otherMonth = lastMotnh != curMonth;
day = date.getDay();
classArray = [];
if(addTr && otherMonth ){
str.push('
');
break;
}
if(addTr){
rowNum++;
str.push('');
if(data.options.showWeek) {
week++;
if(week > 52){
week = picker.getWeek(date);
}
str.push(''+ week +' | ');
}
}
if(!i){
if(day != curCfg.date.firstDay){
nDay = day - curCfg.date.firstDay;
if(nDay < 0){
nDay += 7;
}
date.setDate(date.getDate() - nDay);
day = date.getDay();
curMonth = date.getMonth();
otherMonth = lastMotnh != curMonth;
}
}
dateArray = getDateArray(date);
buttonStr = ' | ');
date.setDate(date.getDate() + 1);
}
str.push('
');
if(j == size - 1){
dateArray = getDateArray(date);
dateArray[2] = 1;
nextDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray.date} : false;
}
}
return {
enabled: 9,
main: str.join(''),
prev: prevDisabled,
next: nextDisabled,
type: 'Grid'
};
};
picker.isInRange = function(values, max, min){
var i;
var ret = true;
for(i = 0; i < values.length; i++){
if(min[i] && min[i] > values[i]){
ret = false;
break;
} else if( !(min[i] && min[i] == values[i]) ){
break;
}
}
if(ret){
for(i = 0; i < values.length; i++){
if((max[i] && max[i] < values[i])){
ret = false;
break;
} else if( !(max[i] && max[i] == values[i]) ){
break;
}
}
}
return ret;
};
picker.createMonthSelect = function(value, max, min, monthNames){
if(!monthNames){
monthNames = curCfg.date.monthNames;
}
var selected;
var i = 0;
var options = [];
var tempVal = value[1]-1;
for(; i < monthNames.length; i++){
selected = tempVal == i ? ' selected=""' : '';
if(selected || picker.isInRange([value[0], i+1], max, min)){
options.push('');
}
}
return options;
};
picker.createYearSelect = function(value, max, min, valueAdd){
var temp;
var goUp = true;
var goDown = true;
var options = [''];
var i = 0;
if(!valueAdd){
valueAdd = '';
}
while(i < 8 && (goUp || goDown)){
i++;
temp = value-i;
if(goUp && picker.isInRange([temp], max, min)){
options.unshift('');
} else {
goUp = false;
}
temp = value + i;
if(goDown && picker.isInRange([temp], max, min)){
options.push('');
} else {
goDown = false;
}
}
return options;
};
(function(){
var retNames = function(name){
return 'get'+name+'List';
};
var retSetNames = function(name){
return 'set'+name+'List';
};
var stops = {
date: 'Day',
week: 'Day',
month: 'Month'
};
$.each({'setYearList' : ['Year', 'Month', 'Day'], 'setMonthList': ['Month', 'Day'], 'setDayList': ['Day']}, function(setName, names){
var getNames = names.map(retNames);
var setNames = names.map(retSetNames);
actions[setName] = function(val, popover, data, startAt){
val = ''+val;
var o = data.options;
var values = val.split('-');
if(!startAt){
startAt = 0;
}
$.each(getNames, function(i, item){
if(i >= startAt){
var content = picker[item](values, data);
if( values.length < 2 || content.enabled > 1 || stops[data.type] === names[i]){
popover.element
.attr({'data-currentview': setNames[i]})
.addClass('ws-size-'+o.size)
.data('pickercontent', {
data: data,
content: content,
values: values
})
;
popover.bodyElement.html(content.main);
if(content.prev){
popover.prevElement
.attr(content.prev)
.prop({disabled: false})
;
} else {
popover.prevElement
.removeAttr('data-action')
.prop({disabled: true})
;
}
if(content.next){
popover.nextElement
.attr(content.next)
.prop({disabled: false})
;
} else {
popover.nextElement
.removeAttr('data-action')
.prop({disabled: true})
;
}
if(webshims[content.type]){
new webshims[content.type](popover.bodyElement.children(), popover, content);
}
popover.element.trigger('pickerchange');
return false;
}
}
});
};
});
})();
picker.showPickerContent = function(data, popover){
var options = data.options;
if(!data._popoverinit){
picker.commonInit(data, popover);
picker.commonDateInit(data, popover);
}
if(!data._popoverinit || options.restartView) {
actions.setYearList( options.defValue || options.value, popover, data, options.startView);
} else {
actions[popover.element.attr('data-currentview') || 'setYearList']( options.defValue || options.value, popover, data, 0);
}
data._popoverinit = true;
};
picker.commonDateInit = function(data, popover){
var actionfn = function(e){
if(!$(this).is('.othermonth') || $(this).css('cursor') == 'pointer'){
popover.actionFn({
'data-action': $.attr(this, 'data-action'),
value: $(this).val() || $.attr(this, 'value')
});
}
return false;
};
var id = new Date().getTime();
var generateList = function(o, max, min){
var options = [];
var label = '';
var labelId = '';
o.options = data.getOptions() || {};
$('div.ws-options', popover.contentElement).remove();
$.each(o.options[0], function(val, label){
var disabled = picker.isInRange(val.split('-'), o.maxS, o.minS) ?
'' :
' disabled="" '
;
options.push('');
});
if(options.length){
id++;
if(o.options[1]){
labelId = 'datalist-'+id;
label = ''+ o.options[1] +'
';
labelId = ' aria-labelledbyid="'+ labelId +'" ';
}
new webshims.ListBox($('').insertAfter(popover.bodyElement)[0], popover, {noFocus: true});
}
};
var updateContent = function(){
if(popover.isDirty){
var o = data.options;
o.maxS = o.max.split('-');
o.minS = o.min.split('-');
$('button', popover.buttonRow).each(function(){
var text;
if($(this).is('.ws-empty')){
text = curCfg.date.clear;
if(!text){
text = formcfg[''].date.clear || 'clear';
webshims.warn("could not get clear text from form cfg");
}
} else if($(this).is('.ws-current')){
text = (curCfg[data.type] || {}).currentText;
if(!text){
text = (formcfg[''][[data.type]] || {}).currentText || 'current';
webshims.warn("could not get currentText from form cfg");
}
$.prop(this, 'disabled', !picker.isInRange(today[data.type].split('-'), o.maxS, o.minS));
}
if(text){
$(this).text(text).attr({'aria-label': text});
if(webshims.assumeARIA){
$.attr(this, 'aria-label', text);
}
}
});
popover.nextElement.attr({'aria-label': curCfg.date.nextText});
$('> span', popover.nextElement).html(curCfg.date.nextText);
popover.prevElement.attr({'aria-label': curCfg.date.prevText});
$('> span', popover.prevElement).html(curCfg.date.prevText);
generateList(o, o.maxS, o.minS);
}
$('button.ws-empty', popover.buttonRow).prop('disabled', $.prop(data.orig, 'required'));
popover.isDirty = false;
};
popover.actionFn = function(obj){
if(actions[obj['data-action']]){
actions[obj['data-action']](obj.value, popover, data, 0);
} else {
webshims.warn('no action for '+ obj['data-action']);
}
};
popover.contentElement.html('
');
popover.nextElement = $('button.ws-next', popover.contentElement);
popover.prevElement = $('button.ws-prev', popover.contentElement);
popover.bodyElement = $('div.ws-picker-body', popover.contentElement);
popover.buttonRow = $('div.ws-button-row', popover.contentElement);
popover.element.on('updatepickercontent', updateContent);
popover.contentElement
.on('click', 'button[data-action]', actionfn)
.on('change', 'select[data-action]', actionfn)
;
$(data.options.orig).on('input', function(){
var currentView;
if(data.options.updateOnInput && popover.isVisible && data.options.value && (currentView = popover.element.attr('data-currentview'))){
actions[currentView]( data.options.value , popover, data, 0);
}
});
$(document).onTrigger('wslocalechange', data._propertyChange);
};
});