fit-ui 2.20.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Fit.UI.js CHANGED
@@ -682,7 +682,7 @@ Fit._internal =
682
682
  {
683
683
  Core:
684
684
  {
685
- VersionInfo: { Major: 2, Minor: 20, Patch: 2 } // Do NOT modify format - version numbers are programmatically changed when releasing new versions - MUST be on a separate line!
685
+ VersionInfo: { Major: 3, Minor: 1, Patch: 0 } // Do NOT modify format - version numbers are programmatically changed when releasing new versions - MUST be on a separate line!
686
686
  }
687
687
  };
688
688
 
@@ -13728,6 +13728,7 @@ Fit.Controls.DatePicker = function(ctlId)
13728
13728
  var me = this;
13729
13729
  var input = null; // Input field for date
13730
13730
  var inputTime = null; // Input field for time (Null if not enabled)
13731
+ var icon = null; // Calendar icon which opens calendar widget without focusing input (which brings up virtual keyboard on touch devices)
13731
13732
  var orgVal = null; // Date object containing control value set using Value(..) or Date(..) - used to determine Dirty state (holds both date and time portion)
13732
13733
  var preVal = ""; // Previous valid date value as string (without time portion)
13733
13734
  var prevTimeVal = ""; // Previous valid time value as string (without date portion)
@@ -13744,6 +13745,8 @@ Fit.Controls.DatePicker = function(ctlId)
13744
13745
  var datePickerYears = "c-10:c+10"; // Calendar widget's year range (from current year, going 10 years back and 10 years forward)
13745
13746
  var datepickerDate = null; // Which date to display in the calendar widget when no date is selected - null or Date
13746
13747
  var startDate = null; // Which year/month to display in calendar widget if view needs to be restored (related to restoreView variable)
13748
+ var selectWeek = false; // Whether to select an entire week when a day is selected
13749
+ var middleOfWeek = null; // Wednesday in selected week when selectWeek is enabled - used to select correct week when changing locale
13747
13750
  var open = false; // Whether calendar widget is currently open
13748
13751
  var focused = false; // Whether control is currently focused
13749
13752
  var restoreView = false; // Whether to keep calendar widget on given year/month when temporarily closing and opening it again
@@ -13752,7 +13755,7 @@ Fit.Controls.DatePicker = function(ctlId)
13752
13755
  var detectBoundariesRelToViewPort = false; // Flag indicating whether calendar widget should be positioned relative to viewport (true) or scroll parent (false)
13753
13756
 
13754
13757
  //var isMobile = Fit.Browser.GetInfo().IsMobile || (Fit.Browser.GetInfo().IsTouchEnabled && Fit.Browser.GetInfo().Name === "Safari"); // More recent versions of Safari on iPad identifies as a Mac computer by default ("Request desktop website" is enabled by default)
13755
- var isMobile = Fit.Device.OptimizeForTouch;
13758
+ var isMobile = Fit.Device.OptimizeForTouch === true && Fit._internal.Controls.DatePicker.UseNativePickerOnTouch === true;
13756
13759
  var inputMobile = null; // Native date picker on mobile devices - value selected is synchronized to input field defined above (remains Null on desktop devices)
13757
13760
  var inputTimeMobile = null; // Native time picker on mobile devices - value selected is synchronized to inputTime field defined above (remains Null on desktop devices)
13758
13761
 
@@ -13769,6 +13772,12 @@ Fit.Controls.DatePicker = function(ctlId)
13769
13772
  input.placeholder = getDatePlaceholder();
13770
13773
  input.tabIndex = ((isMobile === true) ? -1 : 0);
13771
13774
 
13775
+ // Prevent jQuery UI from focusing input field when calendar is opened (brings up virtual keyboard on touch devices).
13776
+ // https://github.com/Jemt/Fit.UI/blob/5e8f2183d75ae17ddb8086ebbe39025a7a7c98bb/Resources/JqueryUI-1.11.4.custom/jquery-ui.js#L1090
13777
+ // => https://github.com/Jemt/Fit.UI/blob/5e8f2183d75ae17ddb8086ebbe39025a7a7c98bb/Resources/JqueryUI-1.11.4.custom/external/jquery/jquery.js#L5268
13778
+ input._focus = input.focus;
13779
+ input.focus = function() { console.debug("focus() disabled for this input field"); };
13780
+
13772
13781
  input.onkeydown = function(e)
13773
13782
  {
13774
13783
  // Open calendar when arrow down key is pressed
@@ -13790,6 +13799,16 @@ Fit.Controls.DatePicker = function(ctlId)
13790
13799
  if (input.value !== "" && curDateTime === null)
13791
13800
  return; // Invalid value
13792
13801
 
13802
+ if (selectWeek === true)
13803
+ {
13804
+ middleOfWeek = getMiddleOfWeek(curDateTime);
13805
+
13806
+ if (selectFirstDayOfWeek() === true) // Returns true if date was changed and OnChange was fired - will not change if date selected is start of week or within currently selected week
13807
+ {
13808
+ return; // OnChange fired from selectFirstDayOfWeek() above
13809
+ }
13810
+ }
13811
+
13793
13812
  var curDateStr = ((curDateTime !== null) ? Fit.Date.Format(curDateTime, me.Format()) : ""); // Not using Value() which includes time if enabled
13794
13813
 
13795
13814
  if (curDateStr !== preVal)
@@ -13843,7 +13862,11 @@ Fit.Controls.DatePicker = function(ctlId)
13843
13862
 
13844
13863
  input.onclick = function()
13845
13864
  {
13846
- me.Show();
13865
+ // Open calendar widget when input is clicked on Desktop, or if TriggerIcon is disabled
13866
+ if (Fit.Device.OptimizeForTouch === false || me.TriggerIcon() === false)
13867
+ {
13868
+ me.Show();
13869
+ }
13847
13870
  }
13848
13871
 
13849
13872
  // Prevent OnFocus from firing when user interacts with calendar widget which
@@ -13930,6 +13953,20 @@ Fit.Controls.DatePicker = function(ctlId)
13930
13953
  me._internal.AddDomElement(input);
13931
13954
  me.AddCssClass("FitUiControlDatePicker");
13932
13955
 
13956
+ icon = document.createElement("span");
13957
+ icon.className = "fa fa-calendar";
13958
+ icon.tabIndex = -1;
13959
+ icon.onclick = function(e)
13960
+ {
13961
+ me.Show();
13962
+
13963
+ if (me.TriggerIcon() === false) // Focus input if icon is hidden
13964
+ {
13965
+ input._focus();
13966
+ }
13967
+ }
13968
+ me._internal.AddDomElement(icon);
13969
+
13933
13970
  me._internal.Data("weeks", "false");
13934
13971
  me._internal.Data("time", "false");
13935
13972
 
@@ -13949,7 +13986,7 @@ Fit.Controls.DatePicker = function(ctlId)
13949
13986
 
13950
13987
  me.OnChange(function(sender)
13951
13988
  {
13952
- if (me.Value() === "") // Value reset
13989
+ if (me.Value() === "" && datepickerDate !== null) // Value reset
13953
13990
  {
13954
13991
  selectDateInMobileDatePicker(datepickerDate);
13955
13992
  }
@@ -13991,7 +14028,14 @@ Fit.Controls.DatePicker = function(ctlId)
13991
14028
  {
13992
14029
  if (focus === true && me.Focused() === false)
13993
14030
  {
13994
- ((inputMobile === null) ? input : inputMobile).focus();
14031
+ if (inputMobile === null)
14032
+ {
14033
+ input._focus();
14034
+ }
14035
+ else
14036
+ {
14037
+ inputMobile.focus();
14038
+ }
13995
14039
  }
13996
14040
  else if (focus === false && me.Focused() === true)
13997
14041
  {
@@ -14084,6 +14128,19 @@ Fit.Controls.DatePicker = function(ctlId)
14084
14128
 
14085
14129
  if (Fit.Validation.IsSet(val) === true)
14086
14130
  {
14131
+ if (selectWeek === true && val !== "")
14132
+ {
14133
+ // Move date to start of week
14134
+
14135
+ var curDate = getDateFromString(val + (val.indexOf(":") === -1 ? " 00:00" : ""), inputTime !== null); // Returns null if val is empty or invalid
14136
+ var startOfWeek = curDate && getStartOfWeek(curDate);
14137
+
14138
+ if (curDate !== null && curDate.getTime() !== startOfWeek.getTime())
14139
+ {
14140
+ val = Fit.Date.Format(startOfWeek, "YYYY-MM-DD" + (inputTime !== null ? " hh:mm" : ""));
14141
+ }
14142
+ }
14143
+
14087
14144
  var fireOnChange = (me.Value() !== val);
14088
14145
  var wasOpen = open;
14089
14146
 
@@ -14121,6 +14178,11 @@ Fit.Controls.DatePicker = function(ctlId)
14121
14178
 
14122
14179
  if (inputTimeMobile !== null)
14123
14180
  inputTimeMobile.value = inputTime.value;
14181
+
14182
+ if (selectWeek === true)
14183
+ {
14184
+ middleOfWeek = getMiddleOfWeek(date);
14185
+ }
14124
14186
  }
14125
14187
  else
14126
14188
  {
@@ -14143,6 +14205,11 @@ Fit.Controls.DatePicker = function(ctlId)
14143
14205
 
14144
14206
  if (inputTimeMobile !== null)
14145
14207
  inputTimeMobile.value = "";
14208
+
14209
+ if (selectWeek === true)
14210
+ {
14211
+ middleOfWeek = null;
14212
+ }
14146
14213
  }
14147
14214
 
14148
14215
  if (wasOpen === true)
@@ -14274,7 +14341,7 @@ Fit.Controls.DatePicker = function(ctlId)
14274
14341
 
14275
14342
  Fit.Internationalization.RemoveOnLocaleChanged(localize);
14276
14343
 
14277
- me = input = inputTime = orgVal = preVal = prevTimeVal = locale = localeEnforced = format = formatEnforced = placeholderDate = placeholderTime = weeks = jquery = datepicker = datepickerElm = startDate = open = focused = restoreView = updateCalConf = detectBoundaries = detectBoundariesRelToViewPort = isMobile = inputMobile = inputTimeMobile = null;
14344
+ me = input = inputTime = icon = orgVal = preVal = prevTimeVal = locale = localeEnforced = format = formatEnforced = placeholderDate = placeholderTime = weeks = jquery = datepicker = datepickerElm = startDate = selectWeek = middleOfWeek = open = focused = restoreView = updateCalConf = detectBoundaries = detectBoundariesRelToViewPort = isMobile = inputMobile = inputTimeMobile = null;
14278
14345
  base();
14279
14346
  });
14280
14347
 
@@ -14299,7 +14366,7 @@ Fit.Controls.DatePicker = function(ctlId)
14299
14366
  if (val !== undefined) // Allow Null
14300
14367
  {
14301
14368
  if (val !== null)
14302
- me.Value(val.getFullYear() + "-" + (val.getMonth() + 1) + "-" + val.getDate() + " " + val.getHours() + ":" + val.getMinutes());
14369
+ me.Value(Fit.Date.Format(val, "YYYY-MM-DD hh:mm"));
14303
14370
  else
14304
14371
  me.Clear();
14305
14372
  }
@@ -14307,30 +14374,7 @@ Fit.Controls.DatePicker = function(ctlId)
14307
14374
  // Get current value
14308
14375
 
14309
14376
  var value = me.Value();
14310
- var date = null;
14311
-
14312
- if (value !== "")
14313
- {
14314
- try
14315
- {
14316
- date = Fit.Date.Parse(value, "YYYY-MM-DD" + ((inputTime !== null) ? " hh:mm" : ""));
14317
- }
14318
- catch (err)
14319
- {
14320
- }
14321
- }
14322
-
14323
- if (date !== null)
14324
- {
14325
- if (inputTime === null)
14326
- {
14327
- date.setHours(0);
14328
- date.setMinutes(0);
14329
- }
14330
-
14331
- date.setSeconds(0);
14332
- date.setMilliseconds(0);
14333
- }
14377
+ var date = getDateFromString(value, inputTime !== null);
14334
14378
 
14335
14379
  return date;
14336
14380
  }
@@ -14366,6 +14410,11 @@ Fit.Controls.DatePicker = function(ctlId)
14366
14410
  {
14367
14411
  localeEnforced = true;
14368
14412
  setLocale(val);
14413
+
14414
+ if (selectWeek === true)
14415
+ {
14416
+ selectFirstDayOfWeek(middleOfWeek);
14417
+ }
14369
14418
  }
14370
14419
 
14371
14420
  return locale;
@@ -14443,6 +14492,66 @@ Fit.Controls.DatePicker = function(ctlId)
14443
14492
  return placeholderTime;
14444
14493
  }
14445
14494
 
14495
+ /// <function container="Fit.Controls.DatePicker" name="TriggerIcon" access="public" returns="boolean">
14496
+ /// <description> Get/set value indicating whether a DatePicker trigger icon is shown </description>
14497
+ /// <param name="val" type="boolean" default="undefined"> If defined, True enables trigger icon (default), False disables it </param>
14498
+ /// </function>
14499
+ this.TriggerIcon = function(val)
14500
+ {
14501
+ Fit.Validation.ExpectBoolean(val, true);
14502
+
14503
+ if (Fit.Validation.IsSet(val) === true)
14504
+ {
14505
+ // Using opacity to hide icon as this allows us to still focus it on touch devices,
14506
+ // rather than focusing the input field, which will bring up the virtual keyboard.
14507
+ icon.style.opacity = val === false ? "0" : "";
14508
+ }
14509
+
14510
+ return icon.style.opacity === "";
14511
+ }
14512
+
14513
+ /// <function container="Fit.Controls.DatePicker" name="SelectWeek" access="public" returns="boolean">
14514
+ /// <description> Get/set value indicating whether an entire week is selected, in which case the first day of the week is returned as control value </description>
14515
+ /// <param name="val" type="boolean" default="undefined"> If defined, True enables week selection, False disables it (default) </param>
14516
+ /// </function>
14517
+ this.SelectWeek = function(val)
14518
+ {
14519
+ Fit.Validation.ExpectBoolean(val, true);
14520
+
14521
+ if (Fit.Validation.IsSet(val) === true)
14522
+ {
14523
+ if (val !== selectWeek)
14524
+ {
14525
+ var wasOpen = open;
14526
+
14527
+ // data-select-week attribute is added or removed when shared picker is opened,
14528
+ // so we need to close it and reopen it, for change to take effect - see Show().
14529
+
14530
+ if (wasOpen === true)
14531
+ {
14532
+ restoreView = true;
14533
+ me.Hide();
14534
+ }
14535
+
14536
+ middleOfWeek = val === true ? getMiddleOfWeek(me.Date()) : null;
14537
+ selectWeek = val;
14538
+
14539
+ if (val === true)
14540
+ {
14541
+ selectFirstDayOfWeek();
14542
+ }
14543
+
14544
+ if (wasOpen === true)
14545
+ {
14546
+ me.Show();
14547
+ restoreView = false;
14548
+ }
14549
+ }
14550
+ }
14551
+
14552
+ return selectWeek;
14553
+ }
14554
+
14446
14555
  this.WeekNumbers = function(val) // Not supported on mobile, and jQuery calendar is buggy: https://bugs.jqueryui.com/ticket/14907
14447
14556
  {
14448
14557
  Fit.Validation.ExpectBoolean(val, true);
@@ -14720,6 +14829,8 @@ Fit.Controls.DatePicker = function(ctlId)
14720
14829
  // by detecting the presence of a data-disable-light-dismiss="true" attribute.
14721
14830
  Fit.Dom.Data(calendarWidget, "disable-light-dismiss", "true");
14722
14831
 
14832
+ Fit.Dom.Data(calendarWidget, "select-week", selectWeek ? "true" : "false");
14833
+
14723
14834
  moveCalenderWidgetLocally();
14724
14835
 
14725
14836
  if (focused === inputTime)
@@ -14731,6 +14842,7 @@ Fit.Controls.DatePicker = function(ctlId)
14731
14842
  {
14732
14843
  if (inputMobile.showPicker !== undefined) // Chrome 99+, Safari 16+, Firefox 101+, Edge 99+
14733
14844
  {
14845
+ inputMobile.focus(); // This is what opens the picker in Safari on touch devices
14734
14846
  inputMobile.showPicker();
14735
14847
  }
14736
14848
  else // This will bring up calendar widget in older browsers on mobile devices - doesn't work on desktop browsers running on hybrid computers (laptops with a touch screen)
@@ -14837,6 +14949,39 @@ Fit.Controls.DatePicker = function(ctlId)
14837
14949
  }
14838
14950
  }
14839
14951
 
14952
+ function getDateFromString(value, includeTime) // E.g. "2024-10-19" or "2024-10-19 16:38"
14953
+ {
14954
+ Fit.Validation.ExpectString(value);
14955
+ Fit.Validation.ExpectBoolean(includeTime);
14956
+
14957
+ var date = null;
14958
+
14959
+ if (value !== "")
14960
+ {
14961
+ try
14962
+ {
14963
+ date = Fit.Date.Parse(value, "YYYY-MM-DD" + (value.indexOf(":") !== -1 ? " hh:mm" : ""));
14964
+ }
14965
+ catch (err)
14966
+ {
14967
+ }
14968
+ }
14969
+
14970
+ if (date !== null)
14971
+ {
14972
+ if (includeTime === false)
14973
+ {
14974
+ date.setHours(0);
14975
+ date.setMinutes(0);
14976
+ }
14977
+
14978
+ date.setSeconds(0);
14979
+ date.setMilliseconds(0);
14980
+ }
14981
+
14982
+ return date;
14983
+ }
14984
+
14840
14985
  function createDatePicker()
14841
14986
  {
14842
14987
  var jq = jquery;
@@ -14847,8 +14992,8 @@ Fit.Controls.DatePicker = function(ctlId)
14847
14992
  showAnim: false,
14848
14993
  showWeek: weeks, // Buggy - does not work if week starts on sunday: https://bugs.jqueryui.com/ticket/14907
14849
14994
  //firstDay: 1,
14850
- changeMonth: true,
14851
- changeYear: true,
14995
+ changeMonth: navigator.platform.toLowerCase().indexOf("iphone") === -1 ? true : false, // We are unable to retain focus on iPhone due to this bug: https://bugs.webkit.org/show_bug.cgi?id=281525 - focus is always returned to <body> when a select value is changed
14996
+ changeYear: navigator.platform.toLowerCase().indexOf("iphone") === -1 ? true : false, // We are unable to retain focus on iPhone due to this bug: https://bugs.webkit.org/show_bug.cgi?id=281525 - focus is always returned to <body> when a select value is changed
14852
14997
  dateFormat: getJqueryUiDatePickerFormat(me.Format()),
14853
14998
  defaultDate: null,
14854
14999
  onChangeMonthYear: function(year, month, dp) // Fires when changing year/month but also when simply opening calendar widget
@@ -14857,7 +15002,14 @@ Fit.Controls.DatePicker = function(ctlId)
14857
15002
  // widget, which causes its DOM to be removed and replaced.
14858
15003
  // Focus is later returned to DatePicker, but not in time for
14859
15004
  // OnFocusOut. Related issue: https://github.com/Jemt/Fit.UI/issues/194
14860
- input.focus(); // Do not use Focused(true) as it will not re-focus input, since control is already considered focused.
15005
+ if (Fit.Device.OptimizeForTouch === true && me.TriggerIcon() === true)
15006
+ {
15007
+ icon.focus(); // Focusing icon to prevent virtual keyboard from being shown on touch devices
15008
+ }
15009
+ else
15010
+ {
15011
+ input._focus(); // Do not use Focused(true) as it will not re-focus input, since control is already considered focused
15012
+ }
14861
15013
 
14862
15014
  if (open === true) // Remember which year and month the user navigated to
14863
15015
  {
@@ -14874,7 +15026,16 @@ Fit.Controls.DatePicker = function(ctlId)
14874
15026
  onSelect: function(dateText, dp) // Notice: jQuery UI DatePicker no longer fires input.OnChange when OnSelect is registered
14875
15027
  {
14876
15028
  startDate = null;
14877
- input.focus(); // Do not use Focused(true) as it will not re-focus input, since control is already considered focused
15029
+
15030
+ if (Fit.Device.OptimizeForTouch === true && me.TriggerIcon() === true)
15031
+ {
15032
+ icon.focus(); // Focusing icon to prevent virtual keyboard from being shown on touch devices
15033
+ }
15034
+ else
15035
+ {
15036
+ input._focus(); // Do not use Focused(true) as it will not re-focus input, since control is already considered focused
15037
+ }
15038
+
14878
15039
  input.onchange();
14879
15040
  },
14880
15041
  beforeShow: function(elm, dp)
@@ -14926,6 +15087,8 @@ Fit.Controls.DatePicker = function(ctlId)
14926
15087
  datepicker.datepicker("option", "dateFormat", getJqueryUiDatePickerFormat(me.Format()));
14927
15088
  datepicker.datepicker("option", "showWeek", weeks);
14928
15089
  datepicker.datepicker("option", "yearRange", datePickerYears);
15090
+ datepicker.datepicker("option", "showOtherMonths", true);
15091
+ datepicker.datepicker("option", "selectOtherMonths", true);
14929
15092
  }
14930
15093
 
14931
15094
  if (me.Value() === "" && datepickerDate !== null) // Apply initial year and month selection
@@ -14969,7 +15132,9 @@ Fit.Controls.DatePicker = function(ctlId)
14969
15132
 
14970
15133
  me._internal.ExecuteWithNoOnChange(function()
14971
15134
  {
14972
- me.Value(val);
15135
+ var middleOfWeekBefore = middleOfWeek;
15136
+ me.Value(val); // Changes middleOfWeek (restored below)
15137
+ middleOfWeek = middleOfWeekBefore;
14973
15138
  });
14974
15139
  }
14975
15140
  },
@@ -14994,7 +15159,7 @@ Fit.Controls.DatePicker = function(ctlId)
14994
15159
  // with something else on the page.
14995
15160
  // If the user decides to return focus to the control, it will not cause OnFocus to fire again,
14996
15161
  // without firing OnBlur in-between, thanks to the 'focused' flag.
14997
- if (focused === true && Fit.Dom.GetFocused() !== input)
15162
+ if (focused === true && Fit.Dom.GetFocused() !== input && Fit.Dom.GetFocused() !== icon)
14998
15163
  {
14999
15164
  me._internal.FireOnBlur();
15000
15165
  }
@@ -15148,7 +15313,7 @@ Fit.Controls.DatePicker = function(ctlId)
15148
15313
 
15149
15314
  if (focusFix)
15150
15315
  {
15151
- input.focus();
15316
+ input._focus();
15152
15317
  }
15153
15318
 
15154
15319
  inputMobile.valueAsDate = date;
@@ -15159,6 +15324,145 @@ Fit.Controls.DatePicker = function(ctlId)
15159
15324
  }
15160
15325
  }
15161
15326
 
15327
+ function getMiddleOfWeek(date)
15328
+ {
15329
+ Fit.Validation.ExpectDate(date, true);
15330
+
15331
+ if (!date)
15332
+ {
15333
+ return null;
15334
+ }
15335
+
15336
+ var firstDay = getJqueryDateFormatFromLocale(locale).firstDay; // 0 = sunday, 1 = monday
15337
+ var day = date.getDay(); // 0 = sunday, ... 6 = saturday
15338
+
15339
+ if (firstDay === 0) // Sunday is start of week
15340
+ {
15341
+ // S M T W T F S
15342
+ // 0 1 2 3 4 5 6
15343
+ // ^
15344
+ var daysFromWednesday = 3 - day; // 3 = wednesday
15345
+
15346
+ var middle = new Date(date.getTime());
15347
+ middle.setDate(date.getDate() + daysFromWednesday);
15348
+ return middle;
15349
+ }
15350
+ else if (firstDay === 1) // Monday is start of week
15351
+ {
15352
+ // Adjust day so it matches a calendar going from monday to sunday
15353
+ // M T W T F S S
15354
+ // 0 1 2 3 4 5 6
15355
+ // ^
15356
+ day = day === 0 ? 6 : day - 1; // 0 = monday, 6 = sunday
15357
+ var daysFromWednesday = 2 - day; // 2 = wednesday
15358
+
15359
+ var middle = new Date(date.getTime());
15360
+ middle.setDate(date.getDate() + daysFromWednesday);
15361
+ return middle;
15362
+ }
15363
+ else if (firstDay === 6) // Saturday is start of week (locale "fa" (Persian), ar-DZ (Arabic - Algeria))
15364
+ {
15365
+ // Adjust day so it matches a calendar going from saturday to friday
15366
+ // S S M T W T F
15367
+ // 0 1 2 3 4 5 6
15368
+ // ^
15369
+ day = day === 0 ? 1 : day === 6 ? 0 : day + 1; // 0 = saturday, 6 = friday
15370
+ var daysFromWednesday = 4 - day; // 4 = wednesday
15371
+
15372
+ var middle = new Date(date.getTime());
15373
+ middle.setDate(date.getDate() + daysFromWednesday);
15374
+ return middle;
15375
+ }
15376
+
15377
+ throw "Unable to determine middle of week - locale with unsupported calendar"; // This should never happen
15378
+ }
15379
+
15380
+ function getStartOfWeek(date)
15381
+ {
15382
+ Fit.Validation.ExpectDate(date);
15383
+
15384
+ var firstDay = getJqueryDateFormatFromLocale(locale).firstDay;
15385
+
15386
+ if (date.getDay() !== firstDay)
15387
+ {
15388
+ var selectedDay = date.getDay(); // 0 = sunday, ... 6 = saturday
15389
+ var daysFromWeekStart = -1;
15390
+
15391
+ if (firstDay === 0) // Sunday is start of week
15392
+ {
15393
+ // S M T W T F S
15394
+ // 0 1 2 3 4 5 6
15395
+ daysFromWeekStart = selectedDay;
15396
+ }
15397
+ else if (firstDay === 1) // Monday is start of week
15398
+ {
15399
+ // M T W T F S S
15400
+ // 1 2 3 4 5 6 0
15401
+ daysFromWeekStart = date.getDay() === 0 ? 6 : date.getDay() - 1;
15402
+ }
15403
+ else if (firstDay === 6) // Saturday is start of week (locale "fa" (Persian), ar-DZ (Arabic - Algeria))
15404
+ {
15405
+ // S S M T W T F
15406
+ // 6 0 1 2 3 4 5
15407
+ daysFromWeekStart = date.getDay() === 6 ? 0 : date.getDay() + 1;
15408
+ }
15409
+
15410
+ if (daysFromWeekStart === -1)
15411
+ {
15412
+ throw "Unable to determine number of days from week start - locale with unsupported calendar"; // This should never happen
15413
+ }
15414
+
15415
+ var weekStart = new Date(date.getTime() - (daysFromWeekStart * (24 * 60 * 60 * 1000)));
15416
+
15417
+ // Prevent adjustment for summer/winter time - keep (restore) time
15418
+ weekStart.setHours(date.getHours());
15419
+ weekStart.setMinutes(date.getMinutes());
15420
+
15421
+ return weekStart;
15422
+ }
15423
+ else
15424
+ {
15425
+ return new Date(date.getTime()); // Return new instance like code above
15426
+ }
15427
+ }
15428
+
15429
+ function selectFirstDayOfWeek(forceDate)
15430
+ {
15431
+ Fit.Validation.ExpectDate(forceDate, true);
15432
+
15433
+ var curDateTime = forceDate || me.Date();
15434
+ var startOfWeek = curDateTime && getStartOfWeek(curDateTime);
15435
+
15436
+ if (curDateTime !== null && curDateTime.getTime() !== startOfWeek.getTime())
15437
+ {
15438
+ var selectWeekStart = function()
15439
+ {
15440
+ var middleOfWeekBefore = middleOfWeek;
15441
+ me.Date(startOfWeek); // Changes middleOfWeek (restored below) - also fires OnChange
15442
+ middleOfWeek = middleOfWeekBefore;
15443
+ };
15444
+
15445
+ if (Fit.Date.Format(startOfWeek, me.Format()) === preVal)
15446
+ {
15447
+ // New date is the same as the one previously selected, meaning user selected a day in the week already
15448
+ // selected, resulting in start of week being selected again - OnChange should not fire in this case.
15449
+ me._internal.ExecuteWithNoOnChange(function()
15450
+ {
15451
+ selectWeekStart();
15452
+ });
15453
+ }
15454
+ else
15455
+ {
15456
+ // A new start of week selected - OnChange must fire
15457
+ selectWeekStart();
15458
+ }
15459
+
15460
+ return true; // Indicate that value was changed
15461
+ }
15462
+
15463
+ return false; // Indicate that no change was made
15464
+ }
15465
+
15162
15466
  function getLocales()
15163
15467
  {
15164
15468
  // List of locales was generated this way:
@@ -15184,7 +15488,8 @@ Fit.Controls.DatePicker = function(ctlId)
15184
15488
  // # });
15185
15489
  // 4) Insert JSON written to console into variable below.
15186
15490
 
15187
- return {"":"mm/dd/yy","en":"mm/dd/yy","en-US":"mm/dd/yy","da":"dd-mm-yy","af":"dd/mm/yy","ar-DZ":"dd/mm/yy","ar":"dd/mm/yy","az":"dd.mm.yy","be":"dd.mm.yy","bg":"dd.mm.yy","bs":"dd.mm.yy","ca":"dd/mm/yy","cs":"dd.mm.yy","cy-GB":"dd/mm/yy","de":"dd.mm.yy","el":"dd/mm/yy","en-AU":"dd/mm/yy","en-GB":"dd/mm/yy","en-NZ":"dd/mm/yy","eo":"dd/mm/yy","es":"dd/mm/yy","et":"dd.mm.yy","eu":"yy-mm-dd","fa":"yy/mm/dd","fi":"d.m.yy","fo":"dd-mm-yy","fr-CA":"yy-mm-dd","fr-CH":"dd.mm.yy","fr":"dd/mm/yy","gl":"dd/mm/yy","he":"dd/mm/yy","hi":"dd/mm/yy","hr":"dd.mm.yy.","hu":"yy.mm.dd.","hy":"dd.mm.yy","id":"dd/mm/yy","is":"dd.mm.yy","it-CH":"dd.mm.yy","it":"dd/mm/yy","ja":"yy/mm/dd","ka":"dd-mm-yy","kk":"dd.mm.yy","km":"dd-mm-yy","ko":"yy. m. d.","ky":"dd.mm.yy","lb":"dd.mm.yy","lt":"yy-mm-dd","lv":"dd.mm.yy","mk":"dd.mm.yy","ml":"dd/mm/yy","ms":"dd/mm/yy","nb":"dd.mm.yy","nl-BE":"dd/mm/yy","nl":"dd-mm-yy","nn":"dd.mm.yy","no":"dd.mm.yy","pl":"dd.mm.yy","pt-BR":"dd/mm/yy","pt":"dd/mm/yy","rm":"dd/mm/yy","ro":"dd.mm.yy","ru":"dd.mm.yy","sk":"dd.mm.yy","sl":"dd.mm.yy","sq":"dd.mm.yy","sr":"dd.mm.yy","sr-SR":"dd.mm.yy","sv":"yy-mm-dd","ta":"dd/mm/yy","th":"dd/mm/yy","tj":"dd.mm.yy","tr":"dd.mm.yy","uk":"dd.mm.yy","vi":"dd/mm/yy","zh-CN":"yy-mm-dd","zh-HK":"dd-mm-yy","zh-TW":"yy/mm/dd"};
15491
+ //return {"":"mm/dd/yy","en":"mm/dd/yy","en-US":"mm/dd/yy","da":"dd-mm-yy","af":"dd/mm/yy","ar-DZ":"dd/mm/yy","ar":"dd/mm/yy","az":"dd.mm.yy","be":"dd.mm.yy","bg":"dd.mm.yy","bs":"dd.mm.yy","ca":"dd/mm/yy","cs":"dd.mm.yy","cy-GB":"dd/mm/yy","de":"dd.mm.yy","el":"dd/mm/yy","en-AU":"dd/mm/yy","en-GB":"dd/mm/yy","en-NZ":"dd/mm/yy","eo":"dd/mm/yy","es":"dd/mm/yy","et":"dd.mm.yy","eu":"yy-mm-dd","fa":"yy/mm/dd","fi":"d.m.yy","fo":"dd-mm-yy","fr-CA":"yy-mm-dd","fr-CH":"dd.mm.yy","fr":"dd/mm/yy","gl":"dd/mm/yy","he":"dd/mm/yy","hi":"dd/mm/yy","hr":"dd.mm.yy.","hu":"yy.mm.dd.","hy":"dd.mm.yy","id":"dd/mm/yy","is":"dd.mm.yy","it-CH":"dd.mm.yy","it":"dd/mm/yy","ja":"yy/mm/dd","ka":"dd-mm-yy","kk":"dd.mm.yy","km":"dd-mm-yy","ko":"yy. m. d.","ky":"dd.mm.yy","lb":"dd.mm.yy","lt":"yy-mm-dd","lv":"dd.mm.yy","mk":"dd.mm.yy","ml":"dd/mm/yy","ms":"dd/mm/yy","nb":"dd.mm.yy","nl-BE":"dd/mm/yy","nl":"dd-mm-yy","nn":"dd.mm.yy","no":"dd.mm.yy","pl":"dd.mm.yy","pt-BR":"dd/mm/yy","pt":"dd/mm/yy","rm":"dd/mm/yy","ro":"dd.mm.yy","ru":"dd.mm.yy","sk":"dd.mm.yy","sl":"dd.mm.yy","sq":"dd.mm.yy","sr":"dd.mm.yy","sr-SR":"dd.mm.yy","sv":"yy-mm-dd","ta":"dd/mm/yy","th":"dd/mm/yy","tj":"dd.mm.yy","tr":"dd.mm.yy","uk":"dd.mm.yy","vi":"dd/mm/yy","zh-CN":"yy-mm-dd","zh-HK":"dd-mm-yy","zh-TW":"yy/mm/dd"};
15492
+ return {"":{"format":"mm/dd/yy","firstDay":0},"en":{"format":"mm/dd/yy","firstDay":0},"en-US":{"format":"mm/dd/yy","firstDay":0},"af":{"format":"dd/mm/yy","firstDay":1},"ar-DZ":{"format":"dd/mm/yy","firstDay":6},"ar":{"format":"dd/mm/yy","firstDay":0},"az":{"format":"dd.mm.yy","firstDay":1},"be":{"format":"dd.mm.yy","firstDay":1},"bg":{"format":"dd.mm.yy","firstDay":1},"bs":{"format":"dd.mm.yy","firstDay":1},"ca":{"format":"dd/mm/yy","firstDay":1},"cs":{"format":"dd.mm.yy","firstDay":1},"cy-GB":{"format":"dd/mm/yy","firstDay":1},"da":{"format":"dd-mm-yy","firstDay":1},"de":{"format":"dd.mm.yy","firstDay":1},"el":{"format":"dd/mm/yy","firstDay":1},"en-AU":{"format":"dd/mm/yy","firstDay":1},"en-GB":{"format":"dd/mm/yy","firstDay":1},"en-NZ":{"format":"dd/mm/yy","firstDay":1},"eo":{"format":"dd/mm/yy","firstDay":0},"es":{"format":"dd/mm/yy","firstDay":1},"et":{"format":"dd.mm.yy","firstDay":1},"eu":{"format":"yy-mm-dd","firstDay":1},"fa":{"format":"yy/mm/dd","firstDay":6},"fi":{"format":"d.m.yy","firstDay":1},"fo":{"format":"dd-mm-yy","firstDay":1},"fr-CA":{"format":"yy-mm-dd","firstDay":0},"fr-CH":{"format":"dd.mm.yy","firstDay":1},"fr":{"format":"dd/mm/yy","firstDay":1},"gl":{"format":"dd/mm/yy","firstDay":1},"he":{"format":"dd/mm/yy","firstDay":0},"hi":{"format":"dd/mm/yy","firstDay":1},"hr":{"format":"dd.mm.yy.","firstDay":1},"hu":{"format":"yy.mm.dd.","firstDay":1},"hy":{"format":"dd.mm.yy","firstDay":1},"id":{"format":"dd/mm/yy","firstDay":0},"is":{"format":"dd.mm.yy","firstDay":0},"it-CH":{"format":"dd.mm.yy","firstDay":1},"it":{"format":"dd/mm/yy","firstDay":1},"ja":{"format":"yy/mm/dd","firstDay":0},"ka":{"format":"dd-mm-yy","firstDay":1},"kk":{"format":"dd.mm.yy","firstDay":1},"km":{"format":"dd-mm-yy","firstDay":1},"ko":{"format":"yy. m. d.","firstDay":0},"ky":{"format":"dd.mm.yy","firstDay":1},"lb":{"format":"dd.mm.yy","firstDay":1},"lt":{"format":"yy-mm-dd","firstDay":1},"lv":{"format":"dd.mm.yy","firstDay":1},"mk":{"format":"dd.mm.yy","firstDay":1},"ml":{"format":"dd/mm/yy","firstDay":1},"ms":{"format":"dd/mm/yy","firstDay":0},"nb":{"format":"dd.mm.yy","firstDay":1},"nl-BE":{"format":"dd/mm/yy","firstDay":1},"nl":{"format":"dd-mm-yy","firstDay":1},"nn":{"format":"dd.mm.yy","firstDay":1},"no":{"format":"dd.mm.yy","firstDay":1},"pl":{"format":"dd.mm.yy","firstDay":1},"pt-BR":{"format":"dd/mm/yy","firstDay":0},"pt":{"format":"dd/mm/yy","firstDay":0},"rm":{"format":"dd/mm/yy","firstDay":1},"ro":{"format":"dd.mm.yy","firstDay":1},"ru":{"format":"dd.mm.yy","firstDay":1},"sk":{"format":"dd.mm.yy","firstDay":1},"sl":{"format":"dd.mm.yy","firstDay":1},"sq":{"format":"dd.mm.yy","firstDay":1},"sr-SR":{"format":"dd.mm.yy","firstDay":1},"sr":{"format":"dd.mm.yy","firstDay":1},"sv":{"format":"yy-mm-dd","firstDay":1},"ta":{"format":"dd/mm/yy","firstDay":1},"th":{"format":"dd/mm/yy","firstDay":0},"tj":{"format":"dd.mm.yy","firstDay":1},"tr":{"format":"dd.mm.yy","firstDay":1},"uk":{"format":"dd.mm.yy","firstDay":1},"vi":{"format":"dd/mm/yy","firstDay":0},"zh-CN":{"format":"yy-mm-dd","firstDay":1},"zh-HK":{"format":"dd-mm-yy","firstDay":0},"zh-TW":{"format":"yy/mm/dd","firstDay":1}};
15188
15493
  }
15189
15494
 
15190
15495
  function getDatePlaceholder()
@@ -15201,11 +15506,13 @@ Fit.Controls.DatePicker = function(ctlId)
15201
15506
  {
15202
15507
  Fit.Validation.ExpectString(val);
15203
15508
 
15204
- var newFormat = getJqueryDateFormatFromLocale(val); // Null if locale does not exist
15509
+ var loc = getJqueryDateFormatFromLocale(val); // Null if locale does not exist
15205
15510
 
15206
- if (newFormat === null)
15511
+ if (loc === null)
15207
15512
  Fit.Validation.ThrowError("Unknown locale '" + val + "'");
15208
15513
 
15514
+ var newFormat = loc.format;
15515
+
15209
15516
  var wasOpen = open;
15210
15517
 
15211
15518
  if (wasOpen === true)
@@ -15326,6 +15633,7 @@ Fit.Controls.DatePicker = function(ctlId)
15326
15633
 
15327
15634
  Fit._internal.Controls.DatePicker = {};
15328
15635
 
15636
+ Fit._internal.Controls.DatePicker.UseNativePickerOnTouch = false;
15329
15637
  /// <container name="Fit.Controls.Dialog" extends="Fit.Controls.Component">
15330
15638
  /// Simple Dialog control with support for Fit.UI buttons.
15331
15639
  /// </container>