1/* =FormUtils */ 2var FormUtilsClass = (function (parent) { 3 // Constructor 4 var cobj = (function () { 5 return (parent != null) ? parent : (function () { }).prototype; 6 })(this); 7 8 9 // Public 10 cobj.GetFormWrapper = function ($item) { 11 return $item.closest('[data-form]'); 12 } 13 14 cobj.GetLocationId = function ($form) { 15 return $(':input[data-locationprovider]:first', $form).val(); 16 } 17 18 cobj.GetWorktimeGroupItems = function ($item) { 19 // Validate source item. 20 if (typeof ($item) === 'undefined' || (!($item instanceof jQuery) || !$item.length)) { 21 return null; 22 } 23 24 // Get data elements group id. 25 var groupId = null; 26 $.each(['calendar', 'timeinput', 'meridian'], function (i, v) { 27 var id = $item.data(v); 28 if (typeof (id) !== 'undefined' && id) { 29 groupId = id; 30 return false; 31 } 32 }); 33 34 // Check if group ID exists. 35 if (!groupId) { 36 return null; 37 } 38 39 // Collect data elements. 40 var $form = FormUtils.GetFormWrapper($item); 41 var $date = $('[data-calendar="' + groupId + '"]:first', $form); 42 var $time = $('[data-timeinput="' + groupId + '"]:first', $form); 43 var $meridian = $('[data-meridian="' + groupId + '"]:first', $form); 44 45 if (!$date.length || !$time.length || !$meridian.length) { 46 // Element is missing. 47 return null; 48 } 49 else { 50 // Return an object with all worktime parts. 51 return { 52 Form: $form, 53 Date: $date, 54 Time: $time, 55 Meridian: $meridian 56 }; 57 } 58 } 59 60 61 // Illation 62 return cobj; 63}); 64var FormUtils = new FormUtilsClass(); 65 66 67/* =WorktimeUtils */ 68var WorktTimeUtilsClass = (function (parent) { 69 // Constructor 70 var cobj = (function () { 71 return (parent != null) ? parent : (function () { }).prototype; 72 })(this); 73 74 75 // Private 76 var calendarMinDate = null; 77 var calendarDisabledDates = null; 78 79 80 // Public 81 cobj.GetCalendarMinDate = function () { 82 if (calendarMinDate == null) { 83 var minDate = new Date(); 84 minDate.setHours(0, 0, 0, 0); 85 86 if (typeof (dsCalendarDaysOffset) !== 'undefined' && (/^\+?(0|[1-9]\d*)$/).test(dsCalendarDaysOffset)) { 87 minDate.setDate(minDate.getDate() + parseInt(dsCalendarDaysOffset)); 88 } 89 else { 90 minDate.setDate(minDate.getDate() + 1); 91 } 92 93 calendarMinDate = minDate; 94 } 95 96 return calendarMinDate; 97 } 98 99 cobj.GetCalendarMinHours = function () { 100 if (typeof (dsCalendarHoursOffset) !== 'undefined' && (/^\+?(0|[1-9]\d*)$/).test(dsCalendarHoursOffset)) { 101 return dsCalendarHoursOffset; 102 } 103 104 return null; 105 } 106 107 cobj.GetCalendarDisabledDates = function () { 108 if (calendarDisabledDates == null) { 109 if (typeof (dsCalendarDisabledDates) !== 'undefined' && dsCalendarDisabledDates) { 110 calendarDisabledDates = $.map(dsCalendarDisabledDates, function (v, i) { 111 var date = new Date(v); 112 if (!isNaN(date)) { 113 date.setHours(0, 0, 0, 0); 114 return date; 115 } 116 }); 117 } 118 else { 119 calendarDisabledDates = []; 120 } 121 } 122 123 return calendarDisabledDates; 124 } 125 126 cobj.GetLocationWorktime = function ($form) { 127 if (typeof (dsWorktime) !== 'undefined' && dsWorktime) { 128 if (dsWorktime.length == 1) { 129 return dsWorktime[0].Value; 130 } 131 else if (($form instanceof jQuery) && $form.length) { 132 var locationId = FormUtils.GetLocationId($form); 133 if (typeof (locationId) !== 'undefined' && locationId) { 134 for (var i = 0; i < dsWorktime.length; i++) { 135 if (dsWorktime[i].Key == locationId) { 136 return dsWorktime[i].Value; 137 } 138 } 139 } 140 } 141 } 142 143 return null; 144 } 145 146 // Illation 147 return cobj; 148}); 149var WorktTimeUtils = new WorktTimeUtilsClass(); 150 151 152/* =Form Addendums */ 153$(document).ready(function () { 154 var $forms = $('[data-form]'); 155 156 /* =Placeholders - default value for input tags */ 157 $forms.on({ 158 focus: function () { 159 var $this = $(this);
160 if ($this.data('placeholder') == $this.val()) { 161 $this.val(''); 162 } 163 }, 164 blur: function () { 165 var $this = $(this); 166 if (!$.trim($this.val()).length) { 167 $this.val($this.data('placeholder')); 168 } 169 } 170 }, ':input[data-placeholder]'); 171 172 173 /* =Calendars - jQuery UI calendar */ 174 // Hide calendars on window resize. 175 $(window).on('resize', '#ui-datepicker-div:visible', function () { 176 $(':focus').datepicker('hide').blur(); 177 }); 178 179 // Bind jQuery calendar to all tags. 180 $(':input[data-calendar]', $forms) 181 .prop('readonly', true) 182 .datepicker({ 183 beforeShowDay: function (date) { 184 // Enable/disable calendar day. 185 var isValid = false; 186 if (date < WorktTimeUtils.GetCalendarMinDate()) { 187 isValid = false; 188 } 189 else { 190 var locationWorktime = WorktTimeUtils.GetLocationWorktime(FormUtils.GetFormWrapper($(this))); 191 if (locationWorktime == null) { 192 // If location worktime hasn't been specified. 193 isValid = $.datepicker.noWeekends(date)[0]; 194 } 195 else { 196 // Check if the current date is in the available business days. 197 var dayOfWeek = date.getDay(); 198 for (var i = 0; i < locationWorktime.length; i++) { 199 if (dayOfWeek == locationWorktime[i].day) { 200 isValid = true; 201 } 202 } 203 } 204 205 if (isValid) { 206 // Check for disabled dates. 207 isValid = ($.grep(WorktTimeUtils.GetCalendarDisabledDates(), function (v, i) { return !(date - v); }).length == 0); 208 } 209 } 210 211 return [isValid, '']; 212 } 213 }); 214 215 // Listen for jQuery calendar triggers. 216 $forms.on('click', '[data-calendartrigger]', function (e) { 217 var calendar = $(':input[data-calendar="' + $(this).data('calendartrigger') + '"]', e.delegateTarget); 218 if (calendar.datepicker('widget').is(':hidden')) { 219 calendar.datepicker('show'); 220 } 221 }); 222 223 224 /* =Time inputs */ 225 $forms.on('keyup', ':input[data-timeinput]', function (e) { 226 var sender = this; 227 var event = e; 228 229 // Get already entered value. 230 var soFarEntered = sender.value.replace(/[^\d]/g, ''); 231 if (event.which == 8) { // Check if keycode is backspace. 232 soFarEntered = soFarEntered.substring(0, soFarEntered.length - 1); 233 } 234 else if (soFarEntered.length > 5) { 235 soFarEntered = soFarEntered.substring(0, 4); 236 } 237 238 // Generate autocomlete value. 239 var autoComplete; 240 switch (soFarEntered.length) { 241 case 1: { 242 autoComplete = ':00'; 243 break; 244 } 245 case 2: { 246 if (soFarEntered <= 12) { 247 autoComplete = ':00'; 248 } 249 else { 250 if (soFarEntered.substring(1, 2) <= 5) { 251 soFarEntered = soFarEntered.substring(0, 1) + ':' + soFarEntered.substring(1); 252 autoComplete = '0'; 253 } 254 else { 255 soFarEntered = soFarEntered.substring(0, 1) + ':0' + soFarEntered.substring(1); 256 autoComplete = ''; 257 } 258 } 259 break; 260 } 261 case 3: { 262 if (soFarEntered.substring(2, 3) <= 5 || soFarEntered.substring(0, 2) > 12) { 263 soFarEntered = soFarEntered.substring(0, 1) + ':' + soFarEntered.substring(1); 264 autoComplete = ''; 265 } 266 else { 267 soFarEntered = soFarEntered.substring(0, 2) + ':0' + soFarEntered.substring(2); 268 autoComplete = ''; 269 } 270 break; 271 } 272 case 4: { 273 if (soFarEntered.substring(0, 2) <= 12 && soFarEntered.substring(2) <= 59) { 274 soFarEntered = soFarEntered.substring(0, 2) + ':' + soFarEntered.substring(2); 275 autoComplete = ''; 276 } 277 else { 278 sender.value = sender.value.substring(0, sender.value.length - 1); 279 autoComplete = ''; 280 return; 281 } 282 break; 283 } 284 case 5: { 285 if (soFarEntered.indexOf(':') === -1) { 286 sender.value = soFarEntered.substring(0, 2) + ':' + soFarEntered.substring(3, 5); 287 return; 288 } 289 } 290 default: { 291 autoComplete = ''; 292 } 293 } 294 sender.value = soFarEntered + autoComplete; 295 296 // Make partial selection in the sender. 297 var selectionStart = soFarEntered.length; 298 var selectionEnd = sender.value.length; 299 if (sender.createTextRange) { 300 var selectionRange = sender.createTextRange(); 301 selectionRange.collapse(true); 302 selectionRange.moveStart('character', selectionStart); 303 selectionRange.moveEnd('character', selectionEnd); 304 selectionRange.select(); 305 } else if (sender.setSelectionRange) { 306 sender.setSelectionRange(selectionStart, selectionEnd); 307 } else if (sender.selectionStart) { 308 sender.selectionStart = selectionStart; 309 sender.selectionEnd = selectionEnd; 310 } 311
312 sender.focus(); 313 }); 314 315 316 /* =Validation */ 317 // Validation Summary 318 if (typeof (window.ValidationSummaryOnSubmit) !== 'undefined' && window.ValidationSummaryOnSubmit !== null) { 319 var originalValidationSummaryOnSubmit = window.ValidationSummaryOnSubmit; 320 window.ValidationSummaryOnSubmit = function (validationGroup) { 321 var originalScrollTo = window.scrollTo; 322 window.scrollTo = function () { }; 323 originalValidationSummaryOnSubmit(validationGroup); 324 window.scrollTo = originalScrollTo; 325 } 326 } 327 328 // Validation failure highlight for data tags. 329 $forms.on('change', ':input[data-validationerror]', function () { 330 var $this = $(this); 331 if (typeof (this.Validators) !== 'undefined' && $.isArray(this.Validators)) { 332 if ($(this.Validators).filter(function () { return (typeof (this.isvalid) !== 'undefined' && !this.isvalid); }).length) { 333 $this.addClass($this.data('validationerror')); 334 } 335 else { 336 $this.removeClass($this.data('validationerror')); 337 } 338 } 339 else { 340 $this.removeClass($this.data('validationerror')); 341 } 342 }); 343 344 // Validation failure highlight on trigger activation and trigger disabling. 345 $forms.on('click', ':input[data-validationtrigger]', function (e) { 346 if (typeof (Page_Validators) === 'undefined' || !$.isArray(Page_Validators)) { 347 return; 348 } 349 350 var $this = $(this); 351 var $form = $(e.delegateTarget); 352 353 // Collect invalid tags. 354 var validationGroup = $this.data('validationtrigger'); 355 var invalidControls = $(':input', $form) 356 // Filter controls with validators. 357 .filter(function () { return (typeof (this.Validators) !== 'undefined' && $.isArray(this.Validators)); }) 358 // Filter the actual invalid controls. 359 .filter(function () { 360 var $this = $(this); 361 var failedValidators = $.grep(this.Validators, function (v, i) { 362 return ( 363 ((typeof (validationGroup) === 'undefined' || !validationGroup) || validationGroup.indexOf(v.validationGroup) >= 0) && 364 (typeof (v.validationGroup) !== 'undefined' && v.validationGroup) && 365 (typeof (v.isvalid) !== 'undefined' && !v.isvalid) 366 ); 367 }); 368 369 var validationerror = $this.data('validationerror'); 370 if (typeof (validationerror) !== 'undefined' && validationerror) { 371 if (failedValidators.length) { 372 $this.addClass(validationerror); 373 } 374 else { 375 $this.removeClass(validationerror); 376 } 377 } 378 379 return failedValidators.length; 380 }); 381 382 // Disable the submit trigger target if validation succeed. 383 if (!invalidControls.length && $this.is(':input')) { 384 $this.closest('form').on('submit', function (e) { 385 $this.prop('disabled', true); 386 e.stopPropagation(); 387 e.preventDefault(); 388 }); 389 } 390 }); 391}); 392 393 394/* =Cutstom Validators */ 395function CFVLocationWorktime(sender, args) { 396 var $control = $('#' + sender.controltovalidate); 397 398 // Check if location is available. 399 var locationWorktime = WorktTimeUtils.GetLocationWorktime(FormUtils.GetFormWrapper($control)); 400 if (locationWorktime == null) { 401 args.IsValid = true; 402 return; 403 } 404 405 // Check if data element is missing. 406 var dataElms = FormUtils.GetWorktimeGroupItems($control); 407 if (dataElms === null) { 408 args.IsValid = true; 409 return; 410 } 411 412 // Check if a timestamp can be extracted. 413 var timestamp = Date.parse(dataElms.Date.val() + ' ' + dataElms.Time.val() + ' ' + dataElms.Meridian.val()); 414 if (isNaN(timestamp)) { 415 args.IsValid = true; 416 return; 417 } 418 419 // Validate the actual datetime. 420 var date = new Date(timestamp); 421 for (var i = 0; i < locationWorktime.length; i++) { 422 if (date.getDay() == locationWorktime[i].day) { 423 var open = new Date(dataElms.Date.val() + ' ' + locationWorktime[i].openTime); 424 var close = new Date(dataElms.Date.val() + ' ' + locationWorktime[i].closeTime); 425 if (date >= open && date <= close) { 426 var hoursOffset = WorktTimeUtils.GetCalendarMinHours(); 427 if (hoursOffset == null || date >= new Date((new Date()).getTime() + hoursOffset * 3600 * 1000)){ 428 args.IsValid = true; 429 return; 430 } 431 else { 432 args.IsValid = false; 433 return; 434 } 435 } 436 else { 437 args.IsValid = false; 438 return; 439 } 440 } 441 } 442 443 args.IsValid = false; 444} 445
446function CFVLocationOptionalWorktime(sender, args) { 447 var $control = $('#' + sender.controltovalidate); 448 449 // Check if validator already failed. 450 if ($($control.get(0).Validators).filter(function () { return (typeof (this.isvalid) !== 'undefined' && !this.isvalid); }).length) { 451 args.IsValid = true; 452 return; 453 } 454 455 // Check if data element is missing. 456 var dataElms = FormUtils.GetWorktimeGroupItems($control); 457 if (dataElms === null) { 458 args.IsValid = true; 459 return; 460 } 461 462 // Validate pair requirement. 463 var dateValue = (new Date(dataElms.Date.val() + ' 00:00 AM')).getTime(); 464 var timeValue = (new Date('1/1/2000 ' + dataElms.Time.val() + ' ' + dataElms.Meridian.val())).getTime(); 465 if ((!isNaN(dateValue) && !isNaN(timeValue)) || (isNaN(dateValue) && isNaN(timeValue))) { 466 args.IsValid = true; 467 return; 468 } 469 470 args.IsValid = false; 471}
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.