1// Pre-requisites for litepicker.js 2 3var globalLanguage = null; 4var globalFormat = null; 5var debug = false; 6 7function GetLanguage() { 8 var language = "auto"; 9 10 try { 11 if (navigator.languages !== undefined) 12 language = navigator.languages[0].toLowerCase(); 13 else 14 language = navigator.language.toLowerCase(); 15 16 if (debug) 17 console.info("GetLanguage() => " + language); 18 } 19 catch (err) { 20 language = "en-US"; 21 22 if (debug) 23 console.info("GetLanguage() => " + language + " [FALLBACK]"); 24 } 25 26 globalLanguage = language; 27 return language; 28} 29 30function GetFormat(language) { 31 var format = "MM/DD/YYYY"; 32 33 try { 34 // Convert a known date and see how it is formatted 35 var dateTest = new Intl.DateTimeFormat(language).format(new Date(2000, 4, 3)); 36 37 // Find components 38 dateTest = (dateTest.replace("2000", "YYYY")).replace("00", "YY"); 39 dateTest = (dateTest.replace("05", "MM")).replace("5", "M"); 40 dateTest = (dateTest.replace("03", "DD")).replace("3", "D"); 41 dateTest = (dateTest.replace(/[^ -~]+/g, "")); // Remove non-printable ASCII characters (IE11 issue with Intl) 42 43 format = dateTest; 44 45 if (debug) 46 console.info("GetFormat(" + language + ") => " + format); 47 } 48 catch (err) { 49 // Fallback logic 50 switch (language.toLowerCase()) { 51 case "en-ca": 52 format = "YYYY-MM-DD"; 53 break; 54 case "ca-es": 55 case "de-ch": 56 case "de-de": 57 case "de": 58 case "en-au": 59 case "en-gb": 60 case "en-ie": 61 case "en-my": 62 case "en-nz": 63 case "en-sg": 64 case "es-es": 65 case "fr-fr": 66 case "fr": 67 format = "DD/MM/YYYY"; 68 break; 69 case "en-us": 70 default: 71 format = "MM/DD/YYYY"; 72 } 73 74 if (debug) 75 console.info("GetFormat(" + language + ") => " + format + " [FALLBACK]"); 76 } 77 78 globalFormat = format; 79 return format; 80} 81 82// Shared functions 83 84function BindFutureDatePicker(tbDate, form, showResetBtn) { 85 var language = globalLanguage ? globalLanguage : GetLanguage(); 86 var dateFormat = globalFormat ? globalFormat : GetFormat(language); 87 88 var elDate = document.getElementById(tbDate); 89 var elForm = document.getElementById(form); 90 91 if (showResetBtn !== true) 92 showResetBtn = false; 93 94 // Get existing value 95 var dateValue = elDate.value; 96 97 // Calculate minimum date 98 var minimumDate = new Date(); // Today 99 minimumDate.setHours(0, 0, 0, 0); // Remove time 100 101 var picker = new Litepicker({ 102 element: elDate, 103 dropdowns: { 104 minYear: new Date().getFullYear(), 105 maxYear: new Date().getFullYear() + 20, 106 months: true, 107 years: 'asc' // true, but with ascending sort 108 }, 109 minDate: minimumDate, 110 lang: language, 111 format: dateFormat, 112 allowRepick: true, 113 autoApply: true, 114 singleMode: true, 115 useResetBtn: showResetBtn, 116 moduleNavKeyboard: true 117 }); 118 119 // Preserve value 120 if ((dateValue !== "") && HasDateChanged(picker, dateValue)) 121 picker.setDate(dateValue); 122 123 // Override onSelect (if needed) 124 // Must be done after setting the value. 125 if (elForm !== null) { 126 picker.setOptions({ 127 onSelect: function (date1, date2) { 128 if ((date1 !== null) && (date1 !== undefined)) 129 elForm.submit(); 130 } 131 }); 132 } 133 134 // Bind listener for textbox level entry 135 elDate.addEventListener("change", function () { 136 if (HasDateChanged(picker, this.value)) { 137 if (AttemptDateChange(picker, this.value, this) && (elForm !== null)) { 138 elForm.submit(); 139 } 140 } 141 }); 142 143 return picker; 144} 145 146function BindDatePicker(tbDate) { 147 var language = globalLanguage ? globalLanguage : GetLanguage(); 148 var dateFormat = globalFormat ? globalFormat : GetFormat(language); 149 150 var elDate = document.getElementById(tbDate); 151 152 // Get existing value 153 var dateValue = elDate.value; 154 155 var picker = new Litepicker({ 156 element: elDate, 157 dropdowns: { 158 minYear: new Date().getFullYear() - 100, 159 maxYear: new Date().getFullYear() + 20, 160 months: true, 161 years: 'asc' // true, but with ascending sort 162 }, 163 minDate: new Date(1753, 0, 1), // Minimum value of SQL DATETIME type 164 lang: language, 165 format: dateFormat, 166 allowRepick: true, 167 autoApply: true, 168 singleMode: true, 169 moduleNavKeyboard: true 170 }); 171 172 // Preserve value
173 if ((dateValue !== "") && HasDateChanged(picker, dateValue)) 174 picker.setDate(dateValue); 175 176 // Bind listener for textbox level entry 177 elDate.addEventListener("change", function () { 178 if (HasDateChanged(picker, this.value)) 179 AttemptDateChange(picker, this.value, this); 180 }); 181 182 return picker; 183} 184 185function BindMultipleDatePickers(className) { 186 var language = globalLanguage ? globalLanguage : GetLanguage(); 187 var dateFormat = globalFormat ? globalFormat : GetFormat(language); 188 189 var elements = document.getElementsByClassName(className); 190 191 if (elements.length == 0) 192 return; 193 194 elements.forEach(function () { 195 // Get existing value 196 var dateValue = this.value; 197 198 var picker = new Litepicker({ 199 element: this, 200 dropdowns: { 201 minYear: new Date().getFullYear() - 100, 202 maxYear: new Date().getFullYear() + 20, 203 months: true, 204 years: 'asc' // true, but with ascending sort 205 }, 206 minDate: new Date(1753, 0, 1), // Minimum value of SQL DATETIME type 207 lang: language, 208 format: dateFormat, 209 allowRepick: true, 210 autoApply: true, 211 singleMode: true, 212 moduleNavKeyboard: true 213 }); 214 215 // Preserve value
216 if ((dateValue !== "") && HasDateChanged(picker, dateValue)) 217 picker.setDate(dateValue); 218 219 // Bind listener for textbox level entry 220 this.addEventListener("change", function () { 221 if (HasDateChanged(picker, this.value)) 222 AttemptDateChange(picker, this.value, this); 223 }); 224 }); 225} 226 227// Validation 228 229function HasDateChanged(picker, dateValue) { 230 var language = globalLanguage ? globalLanguage : GetLanguage(); 231 var existingDate = picker.getDate(); 232 if ((existingDate !== "") && (existingDate !== null)) 233 if (dateValue == existingDate.toLocaleDateString(language)) 234 return false; 235 236 return true; 237} 238 239function AttemptDateChange(picker, dateValue, elDate) { 240 var language = globalLanguage ? globalLanguage : GetLanguage(); 241 if (dateValue !== "") { 242 var existingDate = picker.getDate(); 243 if ((existingDate !== null) && (dateValue == existingDate.toLocaleDateString(language))) { 244 return false; // Unchanged 245 } 246 247 picker.setDate(dateValue); 248 249 var compareDate = picker.getDate(); 250 251 if (debug) 252 console.info("'" + dateValue + "' vs. '" + compareDate.toLocaleDateString(language) + "'"); 253 254 if (dateValue == compareDate.toLocaleDateString(language)) { 255 if (debug) 256 console.info("[SUCCESS] Valid Date!"); 257 258 return true; 259 } 260 261 alert("Invalid date format!"); 262 if (debug) 263 console.info("[ALERT] Invalid date format!"); 264 265 picker.clearSelection(); 266 picker.gotoDate(new Date()); 267 elDate.value = ""; 268 } 269 270 return false; 271} 272 273// Convert a date string to a Date() object given the expected date format. 274function ParseDate(dateValue, dateFormat) { 275 dateFormat = dateFormat.toUpperCase(); 276 277 var separator = dateFormat.match(/[^MDY]/i)[0]; 278 var dateStartIndex, formatStartIndex = 0; 279 var dateEndIndex, formatEndIndex = -1; 280 281 try { 282 var formatValue; 283 var year = null; 284 var month = null; 285 var day = null; 286 287 do { 288 // Determine format's date component 289 formatEndIndex = dateFormat.indexOf(separator, formatStartIndex); 290 if (formatEndIndex < 0) 291 formatEndIndex = dateFormat.length; 292 293 formatValue = dateFormat.substring(formatStartIndex, formatEndIndex); 294 295 // Get date component 296 dateEndIndex = dateValue.indexOf(separator, dateStartIndex + 1); 297 298 if (dateEndIndex < 0) 299 dateEndIndex = dateValue.length; 300 301 switch (formatValue[0]) { 302 case "D": 303 day = dateValue.substring(dateStartIndex, dateEndIndex); 304 break; 305 case "M": 306 month = dateValue.substring(dateStartIndex, dateEndIndex); 307 month--; // Months are 0-11 308 break; 309 case "Y": 310 year = dateValue.substring(dateStartIndex, dateEndIndex); 311 break; 312 default: 313 return null; // Unexpected date format 314 } 315 316 dateStartIndex = dateEndIndex + 1; 317 formatStartIndex = formatEndIndex + 1; 318 } while ((year == null) || (month == null) || (day == null) || (dateStartIndex < dateValue.length - 1)); 319 320 // Return date object 321 return new Date(year, month, day); 322 } 323 catch (err) { 324 // Parsing error 325 if (debug) 326 console.error("ParseDate(" + dateValue + ", " + dateFormat + "); Failed to parse."); 327 } 328 329 return null; 330} 331 332// Compare two dates (locale-aware) 333function DateCompare(startValue, endValue) { 334 var dateFormat = GetFormat(GetLanguage()); 335 336 var startDate = ParseDate(startValue, dateFormat); 337 var endDate = ParseDate(endValue, dateFormat); 338 339 if ((startDate == null) || (endDate == null)) 340 return false; 341 342 if (startDate <= endDate) 343 return true; 344 345 return false; 346} 347 348// Is the given date (locale-aware) today or later? 349function IsFutureDate(dateValue) { 350 var dateFormat = GetFormat(GetLanguage()); 351 352 var compareDate = ParseDate(dateValue, dateFormat); 353 354 if (compareDate == null) 355 return false; 356 357 var tmpDate = new Date(); // Today (with time) 358 var todaysDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate()); 359 360 if (todaysDate <= compareDate) 361 return true; 362 363 return false; 364}
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.