1// Ion.Calendar 2// version 2.0.2, build: 92 3// © 2013 Denis Ineshin | IonDen.com 4// 5// Project page: http://ionden.com/a/plugins/ion.calendar/ 6// GitHub page: https://github.com/IonDen/ion.calendar 7// 8// Released under MIT licence: 9// http://ionden.com/a/plugins/licence-en.html 10// ===================================================================================================================== 11 12(function($){ 13 try { 14 var timeNow = moment(); 15 } catch(e){ 16 alert("Can't find Moment.js, please read the ion.calendar description."); 17 throw new Error("Can't find Moment.js library"); 18 } 19 20 var methods = { 21 init: function(options){ 22 var settings = $.extend({ 23 lang: "en", 24 sundayFirst: true, 25 years: "80", 26 format: "", 27 clickable: true, 28 startDate: "", 29 hideArrows: false, 30 onClick: null, 31 onReady: null 32 }, options), 33 html, i; 34 35 36 return this.each(function(){ 37 var $calendar = $(this); 38 39 //prevent overwrite 40 if($calendar.data("isActive")) { 41 return; 42 } 43 $calendar.data("isActive", true); 44 45 46 47 var $prev, 48 $next, 49 $month, 50 $year, 51 $day, 52 53 timeSelected, 54 timeNowLocal = moment(timeNow.locale(settings.lang)), 55 timeForWork, 56 weekFirstDay, 57 weekLastDay, 58 monthLastDay, 59 60 tempYears, 61 fromYear, 62 toYear, 63 firstStart = true; 64 65 66 67 // public methods 68 this.updateData = function(options){ 69 settings = $.extend(settings, options); 70 removeHTML(); 71 }; 72 73 74 75 // private methods 76 var removeHTML = function(){ 77 $prev.off(); 78 $next.off(); 79 $month.off(); 80 $year.off(); 81 $calendar.empty(); 82 83 prepareData(); 84 prepareCalendar(); 85 }; 86 87 var prepareData = function(){ 88 // start date 89 if(settings.startDate) { 90 if(settings.format.indexOf("L") >= 0) { 91 timeSelected = moment(settings.startDate, "YYYY.MM.DD").locale(settings.lang); 92 } else { 93 timeSelected = moment(settings.startDate, settings.format).locale(settings.lang); 94 } 95 } 96 97 98 // years diapason 99 settings.years = settings.years.toString(); 100 tempYears = settings.years.split("-"); 101 if(tempYears.length === 1) { 102 fromYear = moment().subtract("years", tempYears[0]).format("YYYY"); 103 toYear = moment().format("YYYY"); 104 } else if(tempYears.length === 2){ 105 fromYear = tempYears[0]; 106 toYear = tempYears[1]; 107 } 108 fromYear = parseInt(fromYear); 109 toYear = parseInt(toYear); 110 111 if(toYear < timeNowLocal.format("YYYY")) { 112 timeNowLocal.year(toYear).month(11); 113 } 114 if(fromYear > timeNowLocal.format("YYYY")) { 115 timeNowLocal.year(fromYear).month(0); 116 } 117 }; 118 119 var prepareCalendar = function(){ 120 timeForWork = moment(timeNowLocal); 121 122 weekFirstDay = parseInt(timeForWork.startOf("month").format("d")); 123 weekLastDay = parseInt(timeForWork.endOf("month").format("d")); 124 monthLastDay = parseInt(timeForWork.endOf("month").format("D")); 125 126 html = '<div class="ic__container">'; 127 html += '<div class="ic__header">'; 128 html += '<div class="ic__prev"><div></div></div>'; 129 html += '<div class="ic__next"><div></div></div>'; 130 131 // head month 132 html += '<div class="ic__month"><select class="ic__month-select">'; 133 for(i = 0; i < 12; i++){ 134 if(i === parseInt(timeNowLocal.format("M")) - 1){ 135 html += '<option value="' + i + '" selected="selected">' + timeForWork.month(i).format("MMMM") + '</option>'; 136 } else { 137 html += '<option value="' + i + '">' + timeForWork.month(i).format("MMMM") + '</option>'; 138 } 139 } 140 html += '</select></div>'; 141 142 // head year 143 html += '<div class="ic__year"><select class="ic__year-select">'; 144 for(i = fromYear; i <= toYear; i++){ 145 if(i === parseInt(timeNowLocal.format("YYYY"))){ 146 html += '<option value="' + i + '" selected="selected">' + i + '</option>'; 147 } else { 148 html += '<option value="' + i + '">' + i + '</option>'; 149 } 150 } 151 html += '</select></div>'; 152 153 html += '</div>'; 154 155 if(settings.sundayFirst) { 156 157 // week 158 html += '<table class="ic__week-head"><tr>'; 159 for(i = 0; i < 7; i++) { 160 html += '<td>' + timeForWork.day(i).format("dd") + '</td>'; 161 } 162 html += '</tr></table>'; 163 164 // month 165 html += '<table class="ic__days"><tr>'; 166 // empty days 167 for(i = 0; i < weekFirstDay; i++) { 168 html += '<td class="ic__day-empty"> </td>'; 169 } 170 // days 171 for(i = 1; i <= monthLastDay; i++) { 172 // current day 173 if(moment(timeNowLocal).date(i).format("D.M.YYYY") === timeNow.format("D.M.YYYY")) { 174 html += '<td class="ic__day ic__day_state_current">' + i + '</td>'; 175 } else if(timeSelected && moment(timeNowLocal).date(i).format("D.M.YYYY") === timeSelected.format("D.M.YYYY")) { 176 html += '<td class="ic__day ic__day_state_selected">' + i + '</td>'; 177 } else { 178 html += '<td class="ic__day">' + i + '</td>'; 179 } 180 181 // new week - new line 182 if((weekFirstDay + i) / 7 === Math.floor((weekFirstDay + i) / 7)) { 183 html += '</tr><tr>'; 184 } 185 } 186 // empty days 187 for(i = weekLastDay; i < 6; i++) { 188 html += '<td class="ic__day-empty"> </td>'; 189 } 190 html += '</tr></table>'; 191 192 } else { 193 194 // week 195 html += '<table class="ic__week-head"><tr>'; 196 for(i = 1; i < 8; i++) { 197 if(i < 7) { 198 html += '<td>' + timeForWork.day(i).format("dd") + '</td>'; 199 } else { 200 html += '<td>' + timeForWork.day(0).format("dd") + '</td>'; 201 } 202 } 203 html += '</tr></table>'; 204 205 // days 206 html += '<table class="ic__days"><tr>'; 207 208 // empty days 209 if(weekFirstDay > 0) { 210 weekFirstDay = weekFirstDay - 1; 211 } else { 212 weekFirstDay = 6; 213 } 214 for(i = 0; i < weekFirstDay; i++) { 215 html += '<td class="ic__day-empty"> </td>'; 216 } 217 218 for(i = 1; i <= monthLastDay; i++) { 219 // current day 220 if(moment(timeNowLocal).date(i).format("D.M.YYYY") === timeNow.format("D.M.YYYY")) { 221 html += '<td class="ic__day ic__day_state_current">' + i + '</td>'; 222 } else if(timeSelected && moment(timeNowLocal).date(i).format("D.M.YYYY") === timeSelected.format("D.M.YYYY")) { 223 html += '<td class="ic__day ic__day_state_selected">' + i + '</td>'; 224 } else if(moment(timeNowLocal).date(i) > timeNow) { 225 html += '<td class="ic__day ic__day_disabled">' + i + '</td>'; 226 } else { 227 html += '<td class="ic__day">' + i + '</td>'; 228 } 229 230 // new week - new line 231 if((weekFirstDay + i) / 7 === Math.floor((weekFirstDay + i) / 7)) { 232 html += '</tr><tr>'; 233 } 234 } 235 // empty days 236 if(weekLastDay < 1) { 237 weekLastDay = 7; 238 } 239 for(i = weekLastDay - 1; i < 6; i++) { 240 html += '<td class="ic__day-empty"> </td>'; 241 } 242 html += '</tr></table>'; 243 } 244 245 html += '</div>'; 246 247
248 placeCalendar(); 249 }; 250 251 var placeCalendar = function(){ 252 $calendar.html(html); 253 254 $prev = $calendar.find(".ic__prev"); 255 $next = $calendar.find(".ic__next"); 256 $month = $calendar.find(".ic__month-select"); 257 $year = $calendar.find(".ic__year-select"); 258 $day = $calendar.find(".ic__day"); 259 260 if(settings.hideArrows) { 261 $prev[0].style.display = "none"; 262 $next[0].style.display = "none"; 263 } else { 264 $prev.on("click", function(e){ 265 e.preventDefault(); 266 timeNowLocal.subtract("months", 1); 267 if(parseInt(timeNowLocal.format("YYYY")) < fromYear) { 268 timeNowLocal.add("months", 1); 269 } 270 removeHTML(); 271 }); 272 $next.on("click", function(e){ 273 e.preventDefault(); 274 timeNowLocal.add("months", 1); 275 if(parseInt(timeNowLocal.format("YYYY")) > toYear) { 276 timeNowLocal.subtract("months", 1); 277 } 278 removeHTML(); 279 }); 280 } 281 282 $month.on("change", function(e){ 283 e.preventDefault(); 284 var toMonth = $(this).prop("value"); 285 timeNowLocal.month(parseInt(toMonth)); 286 removeHTML(); 287 }); 288 $year.on("change", function(e){ 289 e.preventDefault(); 290 var toYear = $(this).prop("value"); 291 timeNowLocal.year(parseInt(toYear)); 292 removeHTML(); 293 }); 294 295 if(settings.clickable) { 296 $day.on("click", function(e){ 297 e.preventDefault(); 298 var toDay = $(this).text(); 299 timeNowLocal.date(parseInt(toDay)); 300 timeSelected = moment(timeNowLocal); 301 if(settings.format.indexOf("L") >= 0) { 302 settings.startDate = timeSelected.format("YYYY-MM-DD"); 303 } else { 304 settings.startDate = timeSelected.format(settings.format); 305 } 306 307 // trigger callback function 308 if(typeof settings.onClick === "function") { 309 if(settings.format) { 310 if(settings.format === "moment") { 311 settings.onClick.call(this, timeSelected); 312 } else { 313 settings.onClick.call(this, timeSelected.format(settings.format)); 314 } 315 } else { 316 settings.onClick.call(this, timeSelected.format()); 317 } 318 } 319 320 removeHTML(); 321 }); 322 } 323 324 // trigger onReady function 325 if(typeof settings.onReady === "function") { 326 if(settings.format) { 327 if(settings.format === "moment") { 328 settings.onReady.call(this, timeNowLocal); 329 } else { 330 settings.onReady.call(this, timeNowLocal.format(settings.format)); 331 } 332 } else { 333 settings.onReady.call(this, timeNowLocal.format()); 334 } 335 } 336 337 // go to startDate 338 if(settings.startDate && firstStart) { 339 firstStart = false;
340 timeNowLocal.year(parseInt(timeSelected.format("YYYY"))); 341 timeNowLocal.month(parseInt(timeSelected.format("M") - 1)); 342 removeHTML(); 343 } 344 }; 345 346 347 348 // yarrr! 349 prepareData(); 350 prepareCalendar(); 351 }); 352 }, 353 update: function(options){ 354 return this.each(function(){ 355 this.updateData(options); 356 }); 357 } 358 }; 359 360 $.fn.ionCalendar = function(method){ 361 if (methods[method]) { 362 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 363 } else if (typeof method === 'object' || !method) { 364 return methods.init.apply(this, arguments); 365 } else { 366 $.error('Method ' + method + ' does not exist for jQuery.ionCalendar'); 367 } 368 }; 369})(jQuery); 370 371 372 373// ===================================================================================================================== 374// Ion.DatePicker 375// support plugin for ion.calendar 376 377(function($){ 378 var pluginCount = 0, 379 html, 380 $body = $(document.body); 381 382 var closePopups = function(){ 383 $(".ic__datepicker").css("left", "-9999px").css("top", "-9999px"); 384 }; 385 386 var methods = { 387 init: function(options){ 388 var settings = $.extend({ 389 lang: "en", 390 sundayFirst: true, 391 years: "80", 392 clickable: true, 393 format: "" 394 }, options); 395 396 return this.each(function(){ 397 var $input = $(this), 398 $popup, 399 tempData = {}, 400 self = this, 401 x, y, w, 402 selectedDate, 403 currentDate, 404 testDate; 405 406 //prevent overwrite 407 if($input.data("isActive")) { 408 return; 409 } 410 $input.data("isActive", true); 411 412 pluginCount++; 413 this.pluginCount = pluginCount; 414 415 // change settings from data 416 tempData.lang = $input.data("lang") || settings.lang; 417 if($input.data("sundayfirst") === false) { 418 tempData.sundayFirst = $input.data("sundayfirst"); 419 } 420 tempData.years = $input.data("years") || settings.years; 421 tempData.format = $input.data("format") || settings.format; 422 $.extend(settings, tempData); 423 424 425 $body.on("mousedown", function(){ 426 closePopups(); 427 }); 428 429 430 settings.onClick = function(date){ 431 $input.prop("value", date); 432 selectedDate = date; 433 closePopups(); 434 }; 435 436 var preparePopup = function(){ 437 html = '<div class="ic__datepicker" id="ic__datepicker-' + self.pluginCount + '"></div>'; 438 $body.append(html); 439 $popup = $("#ic__datepicker-" + self.pluginCount); 440 $popup.ionCalendar(settings); 441 442 $popup.on("mousedown", function(e){ 443 e.stopPropagation(); 444 }); 445 $input.on("mousedown", function(e){ 446 e.stopPropagation(); 447 }); 448 $input.on("focusin", function(){ 449 closePopups(); 450 openPopup(); 451 }); 452 $input.on("keyup", function(){ 453 openPopup(); 454 }); 455 }; 456 457 var openPopup = function(){ 458 x = parseInt($input.offset().left); 459 y = parseInt($input.offset().top); 460 w = parseInt($input.outerWidth(true)); 461 462 $popup.css("left", (x + w + 10) + "px").css("top", (y - 10) + "px"); 463 464 465 currentDate = $input.prop("value"); 466 if(currentDate && currentDate !== selectedDate && settings.format.indexOf("L") < 0) { 467 testDate = moment(currentDate, settings.format); 468 if(testDate.isValid()) { 469 $popup.ionCalendar("update", { 470 startDate: currentDate 471 }); 472 } 473 } 474 475 }; 476 477 478 // yarrr! 479 preparePopup(); 480 }); 481 }, 482 close: function(){ 483 closePopups(); 484 } 485 }; 486 487 488 $.fn.ionDatePicker = function(method){ 489 if (methods[method]) { 490 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 491 } else if (typeof method === 'object' || !method) { 492 return methods.init.apply(this, arguments); 493 } else { 494 $.error('Method ' + method + ' does not exist for jQuery.ionDatePicker'); 495 } 496 }; 497})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.