mirror of https://gitee.com/godoos/godoos.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
335 lines
12 KiB
335 lines
12 KiB
/*
|
|
Copyright (c) 2009 Open Lab
|
|
Written by Roberto Bicchierai http://roberto.open-lab.com
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
a copy of this software and associated documentation files (the
|
|
"Software"), to deal in the Software without restriction, including
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
|
permit persons to whom the Software is furnished to do so, subject to
|
|
the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be
|
|
included in all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
jQuery.fn.dateField = function(options) {
|
|
//console.debug("dateField",options);
|
|
//check if the input field is passed correctly
|
|
if (!options.inputField){
|
|
console.error("You must supply an input field");
|
|
return false;
|
|
}
|
|
|
|
// -------------------------- start default option values --------------------------
|
|
|
|
if (typeof(options.firstDayOfWeek) == "undefined")
|
|
options.firstDayOfWeek=Date.firstDayOfWeek;
|
|
|
|
if (typeof(options.useWheel) == "undefined")
|
|
options.useWheel=true;
|
|
|
|
if (typeof(options.dateFormat) == "undefined")
|
|
options.dateFormat=Date.defaultFormat;
|
|
|
|
if (typeof(options.todayLabel) == "undefined")
|
|
options.todayLabel=Date.today;
|
|
|
|
/* optional
|
|
options.notBeforeMillis //disable buttons if before millis
|
|
options.notAfterMillis //disable buttons if after millis
|
|
options.width // imposta una larghezza al calendario
|
|
options.height
|
|
options.showToday // show "today" on the year or month bar
|
|
options.centerOnScreen //se true centra invece che usa nearBestPosition
|
|
options.useYears:0 // se >0 non disegna prev-next ma n anni prima e n anni dopo quello corrente
|
|
options.useMonths:0 // se >0 non disegna prev-next ma n mesi prima e n mesi dopo quello corrente
|
|
*/
|
|
// -------------------------- end default option values --------------------------
|
|
|
|
|
|
|
|
// ------------------ start
|
|
if(options.inputField.is("[readonly]") && !options.inputField.is(".noFocus") || options.inputField.is("[disabled]"))
|
|
return;
|
|
|
|
var calendar = {currentDate: new Date()};
|
|
calendar.options = options;
|
|
|
|
//build the calendar on the first element in the set of matched elements.
|
|
var theOpener = this.eq(0);
|
|
var theDiv=$("<div>").addClass("calBox");
|
|
|
|
if(options.width)
|
|
theDiv.css("width",options.width);
|
|
|
|
if(options.height)
|
|
theDiv.css("height",options.height);
|
|
|
|
|
|
//create calendar elements elements
|
|
var divNavBar = $("<div>").addClass("calNav");
|
|
var divDays = $("<div>").addClass("calDay");
|
|
|
|
divDays.addClass("calFullMonth");
|
|
theDiv.append(divNavBar).append(divDays);
|
|
|
|
if (options.isSearchField){
|
|
var divShortcuts=$("<div>").addClass("shortCuts").html("<span title='last quarter'>LQ</span> <span title='last month'>LM</span> <span title='this month'>M</span> <span title='last week'>LW</span> <span title='this week'>W</span> <span title='yesterday'>Y</span> <span title='today'>T</span><span title='tomorrow'>TO</span><span title='next week'>NW</span> <span title='next month'>NM</span> <span title='this quarter'>Q</span> <span title='next quarter'>NQ</span>");
|
|
divShortcuts.click(function(ev){
|
|
var el=$(ev.target);
|
|
if(el.is("span")){
|
|
if (!options.isSearchField)
|
|
options.inputField.val(Date.parseString(el.text().trim(),options.dateFormat,true).format(options.dateFormat));
|
|
else
|
|
options.inputField.val(el.text().trim());
|
|
calendar.closeCalendar()
|
|
}
|
|
});
|
|
theDiv.append(divShortcuts);
|
|
}
|
|
|
|
//mobile management
|
|
if ($("body").is(".mobile")){
|
|
enableComponentOverlay(options.inputField,theDiv);
|
|
}
|
|
$("body").append(theDiv);
|
|
|
|
|
|
if (options.centerOnScreen){
|
|
theDiv.oneTime(10,"ce",function(){$(this).centerOnScreen()});
|
|
} else {
|
|
nearBestPosition(theOpener,theDiv);
|
|
}
|
|
theDiv.css("z-index",10000);
|
|
|
|
|
|
//register for click outside. Delayed to avoid it run immediately
|
|
$("body").oneTime(100, "regclibodcal", function() {
|
|
$("body").bind("click.dateField", function() {
|
|
calendar.closeCalendar();
|
|
});
|
|
});
|
|
|
|
|
|
calendar.drawCalendar = function(date) {
|
|
calendar.currentDate = date;
|
|
//console.debug("drawCalendar",date);
|
|
|
|
|
|
var fillNavBar = function(date) {
|
|
//console.debug("fillNavBar",date);
|
|
var today = new Date();//today
|
|
divNavBar.empty();
|
|
|
|
var showToday = options.showToday;
|
|
//use the classic prev next bar
|
|
if (!options.useYears && !options.useMonths) {
|
|
var t = new Date(date.getTime());
|
|
t.setDate(1);
|
|
t.setMonth(t.getMonth() - 1);
|
|
var spanPrev = $("<span>").addClass("calElement noCallback prev").attr("millis", t.getTime());
|
|
var spanToday = $("<span>").addClass("calElement noCallback goToday").attr("millis", new Date().getTime()).attr("title", "today");
|
|
t.setMonth(t.getMonth() + 1);
|
|
var spanMonth = $("<span>").html(t.format("MMMM yyyy"));
|
|
t.setMonth(t.getMonth() + 1);
|
|
var spanNext = $("<span>").addClass("calElement noCallback next").attr("millis", t.getTime());
|
|
divNavBar.append(spanPrev, spanToday, spanMonth, spanNext);
|
|
|
|
// use the year month bar
|
|
} else {
|
|
if (options.useYears>0){
|
|
options.useMonths=options.useMonths||1; //if shows years -> shows also months
|
|
t = new Date(date.getTime());
|
|
var yB= $("<div class='calYear'>");
|
|
var w=100/(2*options.useYears+1+(showToday?1:0));
|
|
t.setFullYear(t.getFullYear()-options.useYears);
|
|
if(showToday){
|
|
var s = $("<span>").addClass("calElement noCallback goToday").attr("millis", today.getTime()).append(options.todayLabel).css("width",w+"%");
|
|
showToday=false;
|
|
yB.append(s);
|
|
}
|
|
for (var i=-options.useYears;i<=options.useYears;i++){
|
|
var s = $("<span>").addClass("calElement noCallback").attr("millis", t.getTime()).append(t.getFullYear()).css("width",w+"%");
|
|
if (today.getFullYear()== t.getFullYear()) //current year
|
|
s.addClass("today");
|
|
if (i==0) //selected year
|
|
s.addClass("selected");
|
|
|
|
yB.append(s);
|
|
t.setFullYear(t.getFullYear()+1);
|
|
}
|
|
divNavBar.append(yB);
|
|
}
|
|
if (options.useMonths>0){
|
|
t = new Date(date.getTime());
|
|
t.setDate(1);
|
|
var w=100/(2*options.useMonths+1+(showToday?1:0));
|
|
t.setMonth(t.getMonth()-options.useMonths);
|
|
var yB= $("<div class='calMonth'>");
|
|
|
|
if(showToday){
|
|
var s = $("<span>").addClass("calElement noCallback goToday").attr("millis", today.getTime()).append(options.todayLabel).css("width",w+"%");
|
|
yB.append(s);
|
|
}
|
|
|
|
for (var i=-options.useMonths;i<=options.useMonths;i++){
|
|
var s = $("<span>").addClass("calElement noCallback").attr("millis", t.getTime()).append(t.format("MMM")).css("width",w+"%");
|
|
if (today.getFullYear()== t.getFullYear() && today.getMonth()== t.getMonth()) //current year
|
|
s.addClass("today");
|
|
if (i==0) //selected month
|
|
s.addClass("selected");
|
|
yB.append(s);
|
|
t.setMonth(t.getMonth()+1);
|
|
}
|
|
divNavBar.append(yB);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
var fillDaysFullMonth = function(date) {
|
|
divDays.empty();
|
|
var today = new Date();//today
|
|
var w = 100/7;
|
|
// draw day headers
|
|
var d = new Date(date);
|
|
d.setFirstDayOfThisWeek(options.firstDayOfWeek);
|
|
for (var i = 0; i < 7; i++) {
|
|
var span = $("<span>").addClass("calDayHeader").attr("day", d.getDay());
|
|
if (d.isHoliday())
|
|
span.addClass("holy");
|
|
span.css("width",w+"%");
|
|
span.html(Date.dayAbbreviations[d.getDay()]);
|
|
|
|
//call the dayHeaderRenderer
|
|
if (typeof(options.dayHeaderRenderer) == "function")
|
|
options.dayHeaderRenderer(span,d.getDay());
|
|
|
|
divDays.append(span);
|
|
d.setDate(d.getDate()+1);
|
|
}
|
|
|
|
//draw cells
|
|
d = new Date(date);
|
|
d.setDate(1); // set day to start of month
|
|
d.setFirstDayOfThisWeek(options.firstDayOfWeek);//go to first day of week
|
|
|
|
var i=0;
|
|
|
|
while ((d.getMonth()<=date.getMonth() && d.getFullYear()<=date.getFullYear()) || d.getFullYear()<date.getFullYear() || (i%7!=0)) {
|
|
var span = $("<span>").addClass("calElement day").attr("millis", d.getTime());
|
|
|
|
span.html("<span class=dayNumber>" + d.getDate() + "</span>").css("width",w+"%");
|
|
if (d.getYear() == today.getYear() && d.getMonth() == today.getMonth() && d.getDate() == today.getDate())
|
|
span.addClass("today");
|
|
if (d.getYear() == date.getYear() && d.getMonth() == date.getMonth() && d.getDate() == date.getDate())
|
|
span.addClass("selected");
|
|
|
|
if (d.isHoliday())
|
|
span.addClass("holy");
|
|
|
|
if(d.getMonth()!=date.getMonth())
|
|
span.addClass("calOutOfScope");
|
|
|
|
//call the dayRenderer
|
|
if (typeof(options.dayRenderer) == "function")
|
|
options.dayRenderer(span,d);
|
|
|
|
divDays.append(span);
|
|
d.setDate(d.getDate()+1);
|
|
i++;
|
|
}
|
|
|
|
};
|
|
|
|
fillNavBar(date);
|
|
fillDaysFullMonth(date);
|
|
|
|
//disable all buttons out of validity period
|
|
if (options.notBeforeMillis ||options.notAfterMillis) {
|
|
var notBefore = options.notBeforeMillis ? options.notBeforeMillis : Number.MIN_VALUE;
|
|
var notAfter = options.notAfterMillis ? options.notAfterMillis : Number.MAX_VALUE;
|
|
divDays.find(".calElement[millis]").each(function(){
|
|
var el=$(this);
|
|
var m=parseInt(el.attr("millis"));
|
|
if (m>notAfter || m<notBefore)
|
|
el.addClass("disabled");
|
|
})
|
|
}
|
|
|
|
};
|
|
|
|
calendar.closeCalendar=function(){
|
|
//mobile management
|
|
if ($("body").is(".mobile")){
|
|
disableComponentOverlay();
|
|
}
|
|
theDiv.remove();
|
|
$("body").unbind("click.dateField");
|
|
};
|
|
|
|
theDiv.click(function(ev) {
|
|
var el = $(ev.target).closest(".calElement");
|
|
if (el.length > 0) {
|
|
var millis = parseInt(el.attr("millis"));
|
|
var date = new Date(millis);
|
|
|
|
if (el.is(".disabled")) {
|
|
ev.stopPropagation();
|
|
return;
|
|
}
|
|
|
|
if (el.hasClass("day")) {
|
|
calendar.closeCalendar();
|
|
if (!el.is(".noCallback")) {
|
|
options.inputField.val(date.format(options.dateFormat)).attr("millis", date.getTime()).focus();
|
|
if (typeof(options.callback) == "function")
|
|
options.callback.apply(options.inputField,[date]); // in callBack you can use "this" that refers to the input
|
|
}
|
|
} else {
|
|
calendar.drawCalendar(date);
|
|
}
|
|
}
|
|
ev.stopPropagation();
|
|
});
|
|
|
|
|
|
//if mousewheel
|
|
if ($.event.special.mousewheel && options.useWheel) {
|
|
divDays.mousewheel(function(event, delta) {
|
|
var d = new Date(calendar.currentDate.getTime());
|
|
d.setMonth(d.getMonth() + delta);
|
|
calendar.drawCalendar(d);
|
|
return false;
|
|
});
|
|
}
|
|
|
|
|
|
// start calendar to the date in the input
|
|
var dateStr=options.inputField.val();
|
|
|
|
if (!dateStr || !Date.isValid(dateStr,options.dateFormat,true)){
|
|
calendar.drawCalendar(new Date());
|
|
} else {
|
|
var date = Date.parseString(dateStr,options.dateFormat,true);
|
|
var newDateStr=date.format(options.dateFormat);
|
|
//set date string formatted if not equals
|
|
if (!options.isSearchField) {
|
|
options.inputField.attr("millis", date.getTime());
|
|
if (dateStr != newDateStr)
|
|
options.inputField.val(newDateStr);
|
|
}
|
|
calendar.drawCalendar(date);
|
|
}
|
|
|
|
return calendar;
|
|
};
|
|
|