fit-ui 3.0.0 → 3.2.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: 3, Minor: 0, Patch: 0 } // Do NOT modify format - version numbers are programmatically changed when releasing new versions - MUST be on a separate line!
685
+ VersionInfo: { Major: 3, Minor: 2, 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
 
@@ -5758,6 +5758,40 @@ Fit.Color.HexToRgb = function(hex)
5758
5758
  return "rgb(" + rgb.Red + ", " + rgb.Green + ", " + rgb.Blue + ")";
5759
5759
  }
5760
5760
 
5761
+ /// <function container="Fit.Color" name="GetContrastColor" access="public" static="true" returns="string">
5762
+ /// <description> Get "black" or "white" depending on which is best suited in combination with specified color </description>
5763
+ /// <param name="hex" type="string"> HEX color string, e.g. #C0C0C0 (hash symbol is optional) </param>
5764
+ /// <param name="threshold" type="number" default="undefined">
5765
+ /// Returns "black" when brightness is above threshold, "white" otherwise.
5766
+ /// 0 = all black, 255 = all white. Value defaults to 128.
5767
+ /// </param>
5768
+ /// </function>
5769
+ Fit.Color.GetContrastColor = function(hex, threshold)
5770
+ {
5771
+ Fit.Validation.ExpectString(hex);
5772
+ Fit.Validation.ExpectInteger(threshold, true);
5773
+
5774
+ // Validate input
5775
+ if (/^#?[A-Za-z0-9]{6}$/.test(hex) === false)
5776
+ {
5777
+ throw "Invalid HEX color";
5778
+ }
5779
+
5780
+ // Remove hash from color code
5781
+ hex = hex.replace(/^#/, "");
5782
+
5783
+ // Convert HEX to RGB
5784
+ var r = parseInt(hex.substring(0, 2), 16);
5785
+ var g = parseInt(hex.substring(2, 4), 16);
5786
+ var b = parseInt(hex.substring(4, 6), 16);
5787
+
5788
+ // Calculate luminance (perceived brightness)
5789
+ var luminance = (0.299 * r + 0.587 * g + 0.114 * b); // 0 = all black, 255 = all white
5790
+
5791
+ // Return black if the color is light, white otherwise
5792
+ return luminance > (threshold || 128) ? "black" : "white";
5793
+ }
5794
+
5761
5795
  /// <container name="Fit.ColorTypeDefs.RgbColor">
5762
5796
  /// <description> RGB color object </description>
5763
5797
  /// <member name="Red" type="integer"> </member>
@@ -12449,6 +12483,223 @@ Fit.Controls.CheckBox = function(ctlId)
12449
12483
  init();
12450
12484
  }
12451
12485
 
12486
+ /// <container name="Fit.Controls.ColorPicker" extends="Fit.Controls.ControlBase">
12487
+ /// ColorPicker control which allows for color selection.
12488
+ /// Extending from Fit.Controls.ControlBase.
12489
+ /// </container>
12490
+
12491
+ /// <function container="Fit.Controls.ColorPicker" name="ColorPicker" access="public">
12492
+ /// <description> Create instance of ColorPicker control </description>
12493
+ /// <param name="ctlId" type="string" default="undefined"> Unique control ID that can be used to access control using Fit.Controls.Find(..) </param>
12494
+ /// </function>
12495
+ Fit.Controls.ColorPicker = function(ctlId)
12496
+ {
12497
+ Fit.Validation.ExpectStringValue(ctlId, true);
12498
+ Fit.Core.Extend(this, Fit.Controls.ControlBase).Apply(ctlId);
12499
+
12500
+ var me = this;
12501
+ var colorPicker = null; // Native color picker control: <input type="color">
12502
+ var lblValue = null; // Label showing selected HEX color code
12503
+ var orgColor = ""; // Holds initial value used to determine IsDirty state
12504
+ var prevColor = ""; // Holds latest change made by user - used to determine whether OnChange needs to be fired
12505
+ var cmdClear = null; // Clear button to remove color selection (transparency)
12506
+ var defaultColor = "#FFD6D6"; // Color (use upper case!) that is unlikely to be used - OnChange won't fire if we click on the initially selected color, so this color cannot be selected without selecting another color first
12507
+
12508
+ // ============================================
12509
+ // Init
12510
+ // ============================================
12511
+
12512
+ function init()
12513
+ {
12514
+ me.AddCssClass("FitUiControlColorPicker");
12515
+ transparent(true);
12516
+
12517
+ colorPicker = document.createElement("input");
12518
+ colorPicker.type = "color";
12519
+ colorPicker.value = defaultColor;
12520
+ colorPicker.oninput = function() // Contrary to OnChange, OnInput fires continuously
12521
+ {
12522
+ if (me === null)
12523
+ {
12524
+ // Fix for Chrome which fires OnChange and OnBlur (in both capturering and bubbling phase)
12525
+ // if control has focus while being removed from DOM, e.g. if used in a dialog closed using ESC.
12526
+ // More details here: https://bugs.chromium.org/p/chromium/issues/detail?id=866242
12527
+ return;
12528
+ }
12529
+
12530
+ transparent(false);
12531
+ fireOnChange();
12532
+ }
12533
+ me._internal.AddDomElement(colorPicker);
12534
+
12535
+ lblValue = document.createElement("span");
12536
+ lblValue.tabIndex = -1;
12537
+ lblValue.onclick = function(e)
12538
+ {
12539
+ if (window.getSelection().isCollapsed === true) // No selection - open picker - otherwise user is likely trying to copy color which color picker will prevent
12540
+ {
12541
+ colorPicker.click();
12542
+ }
12543
+ }
12544
+ me._internal.AddDomElement(lblValue);
12545
+
12546
+ cmdClear = document.createElement("span");
12547
+ cmdClear.tabIndex = -1;
12548
+ cmdClear.innerHTML = "&times;";
12549
+ cmdClear.onclick = function()
12550
+ {
12551
+ colorPicker.focus(); // Move focus to color picker - clear button will be hidden when transparent
12552
+ transparent(true);
12553
+
12554
+ colorPicker.value = defaultColor;
12555
+ prevColor = defaultColor;
12556
+
12557
+ fireOnChange();
12558
+ }
12559
+ me._internal.AddDomElement(cmdClear);
12560
+ }
12561
+
12562
+ // ============================================
12563
+ // Public - overrides
12564
+ // ============================================
12565
+
12566
+ // See documentation on ControlBase
12567
+ this.Focused = function(focus)
12568
+ {
12569
+ Fit.Validation.ExpectBoolean(focus, true);
12570
+
12571
+ if (Fit.Validation.IsSet(focus) === true && focus !== me.Focused())
12572
+ {
12573
+ if (focus === true)
12574
+ {
12575
+ colorPicker.focus();
12576
+ }
12577
+ else
12578
+ {
12579
+ Fit.Dom.GetFocused().blur(); // Multiple elements can hold focus - we have ensured control is the one having focus (me.Focused() above)
12580
+ }
12581
+ }
12582
+
12583
+ return Fit.Dom.Contained(me.GetDomElement(), Fit.Dom.GetFocused());
12584
+ }
12585
+
12586
+ // See documentation on ControlBase
12587
+ this.Value = function(val, preserveDirtyState)
12588
+ {
12589
+ Fit.Validation.ExpectString(val, true);
12590
+ Fit.Validation.ExpectBoolean(preserveDirtyState, true);
12591
+
12592
+ if (Fit.Validation.IsSet(val) === true)
12593
+ {
12594
+ val = val.toUpperCase();
12595
+
12596
+ if (me.Value() !== val)
12597
+ {
12598
+ var changed = false;
12599
+
12600
+ if (val === "")
12601
+ {
12602
+ transparent(true);
12603
+ changed = true;
12604
+ }
12605
+ else if (isValidColor(val) === true)
12606
+ {
12607
+ transparent(false);
12608
+ colorPicker.value = val;
12609
+ changed = true;
12610
+ }
12611
+
12612
+ if (changed === true)
12613
+ {
12614
+ orgColor = (preserveDirtyState !== true ? val : orgColor);
12615
+ fireOnChange();
12616
+ }
12617
+ }
12618
+ }
12619
+
12620
+ return (transparent() ? "" : colorPicker.value.toUpperCase());
12621
+ }
12622
+
12623
+ // See documentation on ControlBase
12624
+ this.IsDirty = function()
12625
+ {
12626
+ return (orgColor !== me.Value());
12627
+ }
12628
+
12629
+ // See documentation on ControlBase
12630
+ this.Clear = function()
12631
+ {
12632
+ me.Value("");
12633
+ }
12634
+
12635
+ // See documentation on ControlBase
12636
+ this.Dispose = Fit.Core.CreateOverride(this.Dispose, function()
12637
+ {
12638
+ me = colorPicker = lblValue = orgColor = prevColor = cmdClear = defaultColor = null;
12639
+ base();
12640
+ });
12641
+
12642
+ // ============================================
12643
+ // Public
12644
+ // ============================================
12645
+
12646
+ this.ShowValue = function(val)
12647
+ {
12648
+ Fit.Validation.ExpectBoolean(val, true);
12649
+
12650
+ if (Fit.Validation.IsSet(val) === true)
12651
+ {
12652
+ lblValue.style.display = (val === false ? "none" : "");
12653
+ }
12654
+
12655
+ return lblValue.style.display === "";
12656
+ }
12657
+
12658
+ // ============================================
12659
+ // Private
12660
+ // ============================================
12661
+
12662
+ function transparent(val)
12663
+ {
12664
+ if (Fit.Validation.IsSet(val) === true)
12665
+ {
12666
+ me._internal.Data("transparent", val ? "true" : "false");
12667
+ }
12668
+
12669
+ return me._internal.Data("transparent") === "true";
12670
+ }
12671
+
12672
+ function isValidColor(val)
12673
+ {
12674
+ return /^#[A-F0-9]{6}$/.test(val);
12675
+ }
12676
+
12677
+ function fireOnChange()
12678
+ {
12679
+ var newVal = me.Value();
12680
+ var compareValue = prevColor.toUpperCase(); // Value() returns uppercase value for color picker - preVal might be in lower case if assigned before input type was changed
12681
+
12682
+ if (newVal !== compareValue)
12683
+ {
12684
+ prevColor = newVal;
12685
+ me._internal.FireOnChange();
12686
+
12687
+ var contrastColor = me.Value() !== "" ? Fit.Color.GetContrastColor(me.Value(), 120) : "black";
12688
+
12689
+ // Update control's background color
12690
+ me.GetDomElement().style.background = me.Value();
12691
+
12692
+ // Update label showing color code
12693
+ lblValue.innerHTML = me.Value();
12694
+ lblValue.style.color = contrastColor;
12695
+
12696
+ // Update clear button's contract color
12697
+ cmdClear.style.color = contrastColor;
12698
+ }
12699
+ }
12700
+
12701
+ init();
12702
+ }
12452
12703
  /// <container name="Fit.Controls.ContextMenu" extends="Fit.Controls.Component">
12453
12704
  /// ContextMenu control allowing for quick access to select features.
12454
12705
  /// </container>
@@ -13728,6 +13979,7 @@ Fit.Controls.DatePicker = function(ctlId)
13728
13979
  var me = this;
13729
13980
  var input = null; // Input field for date
13730
13981
  var inputTime = null; // Input field for time (Null if not enabled)
13982
+ var icon = null; // Calendar icon which opens calendar widget without focusing input (which brings up virtual keyboard on touch devices)
13731
13983
  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
13984
  var preVal = ""; // Previous valid date value as string (without time portion)
13733
13985
  var prevTimeVal = ""; // Previous valid time value as string (without date portion)
@@ -13744,6 +13996,8 @@ Fit.Controls.DatePicker = function(ctlId)
13744
13996
  var datePickerYears = "c-10:c+10"; // Calendar widget's year range (from current year, going 10 years back and 10 years forward)
13745
13997
  var datepickerDate = null; // Which date to display in the calendar widget when no date is selected - null or Date
13746
13998
  var startDate = null; // Which year/month to display in calendar widget if view needs to be restored (related to restoreView variable)
13999
+ var selectWeek = false; // Whether to select an entire week when a day is selected
14000
+ var middleOfWeek = null; // Wednesday in selected week when selectWeek is enabled - used to select correct week when changing locale
13747
14001
  var open = false; // Whether calendar widget is currently open
13748
14002
  var focused = false; // Whether control is currently focused
13749
14003
  var restoreView = false; // Whether to keep calendar widget on given year/month when temporarily closing and opening it again
@@ -13752,7 +14006,7 @@ Fit.Controls.DatePicker = function(ctlId)
13752
14006
  var detectBoundariesRelToViewPort = false; // Flag indicating whether calendar widget should be positioned relative to viewport (true) or scroll parent (false)
13753
14007
 
13754
14008
  //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;
14009
+ var isMobile = Fit.Device.OptimizeForTouch === true && Fit._internal.Controls.DatePicker.UseNativePickerOnTouch === true;
13756
14010
  var inputMobile = null; // Native date picker on mobile devices - value selected is synchronized to input field defined above (remains Null on desktop devices)
13757
14011
  var inputTimeMobile = null; // Native time picker on mobile devices - value selected is synchronized to inputTime field defined above (remains Null on desktop devices)
13758
14012
 
@@ -13769,6 +14023,12 @@ Fit.Controls.DatePicker = function(ctlId)
13769
14023
  input.placeholder = getDatePlaceholder();
13770
14024
  input.tabIndex = ((isMobile === true) ? -1 : 0);
13771
14025
 
14026
+ // Prevent jQuery UI from focusing input field when calendar is opened (brings up virtual keyboard on touch devices).
14027
+ // https://github.com/Jemt/Fit.UI/blob/5e8f2183d75ae17ddb8086ebbe39025a7a7c98bb/Resources/JqueryUI-1.11.4.custom/jquery-ui.js#L1090
14028
+ // => https://github.com/Jemt/Fit.UI/blob/5e8f2183d75ae17ddb8086ebbe39025a7a7c98bb/Resources/JqueryUI-1.11.4.custom/external/jquery/jquery.js#L5268
14029
+ input._focus = input.focus;
14030
+ input.focus = function() { console.debug("focus() disabled for this input field"); };
14031
+
13772
14032
  input.onkeydown = function(e)
13773
14033
  {
13774
14034
  // Open calendar when arrow down key is pressed
@@ -13790,6 +14050,16 @@ Fit.Controls.DatePicker = function(ctlId)
13790
14050
  if (input.value !== "" && curDateTime === null)
13791
14051
  return; // Invalid value
13792
14052
 
14053
+ if (selectWeek === true)
14054
+ {
14055
+ middleOfWeek = getMiddleOfWeek(curDateTime);
14056
+
14057
+ 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
14058
+ {
14059
+ return; // OnChange fired from selectFirstDayOfWeek() above
14060
+ }
14061
+ }
14062
+
13793
14063
  var curDateStr = ((curDateTime !== null) ? Fit.Date.Format(curDateTime, me.Format()) : ""); // Not using Value() which includes time if enabled
13794
14064
 
13795
14065
  if (curDateStr !== preVal)
@@ -13843,7 +14113,11 @@ Fit.Controls.DatePicker = function(ctlId)
13843
14113
 
13844
14114
  input.onclick = function()
13845
14115
  {
13846
- me.Show();
14116
+ // Open calendar widget when input is clicked on Desktop, or if TriggerIcon is disabled
14117
+ if (Fit.Device.OptimizeForTouch === false || me.TriggerIcon() === false)
14118
+ {
14119
+ me.Show();
14120
+ }
13847
14121
  }
13848
14122
 
13849
14123
  // Prevent OnFocus from firing when user interacts with calendar widget which
@@ -13930,6 +14204,20 @@ Fit.Controls.DatePicker = function(ctlId)
13930
14204
  me._internal.AddDomElement(input);
13931
14205
  me.AddCssClass("FitUiControlDatePicker");
13932
14206
 
14207
+ icon = document.createElement("span");
14208
+ icon.className = "fa fa-calendar";
14209
+ icon.tabIndex = -1;
14210
+ icon.onclick = function(e)
14211
+ {
14212
+ me.Show();
14213
+
14214
+ if (me.TriggerIcon() === false) // Focus input if icon is hidden
14215
+ {
14216
+ input._focus();
14217
+ }
14218
+ }
14219
+ me._internal.AddDomElement(icon);
14220
+
13933
14221
  me._internal.Data("weeks", "false");
13934
14222
  me._internal.Data("time", "false");
13935
14223
 
@@ -13949,7 +14237,7 @@ Fit.Controls.DatePicker = function(ctlId)
13949
14237
 
13950
14238
  me.OnChange(function(sender)
13951
14239
  {
13952
- if (me.Value() === "") // Value reset
14240
+ if (me.Value() === "" && datepickerDate !== null) // Value reset
13953
14241
  {
13954
14242
  selectDateInMobileDatePicker(datepickerDate);
13955
14243
  }
@@ -13991,7 +14279,14 @@ Fit.Controls.DatePicker = function(ctlId)
13991
14279
  {
13992
14280
  if (focus === true && me.Focused() === false)
13993
14281
  {
13994
- ((inputMobile === null) ? input : inputMobile).focus();
14282
+ if (inputMobile === null)
14283
+ {
14284
+ input._focus();
14285
+ }
14286
+ else
14287
+ {
14288
+ inputMobile.focus();
14289
+ }
13995
14290
  }
13996
14291
  else if (focus === false && me.Focused() === true)
13997
14292
  {
@@ -14084,6 +14379,19 @@ Fit.Controls.DatePicker = function(ctlId)
14084
14379
 
14085
14380
  if (Fit.Validation.IsSet(val) === true)
14086
14381
  {
14382
+ if (selectWeek === true && val !== "")
14383
+ {
14384
+ // Move date to start of week
14385
+
14386
+ var curDate = getDateFromString(val + (val.indexOf(":") === -1 ? " 00:00" : ""), inputTime !== null); // Returns null if val is empty or invalid
14387
+ var startOfWeek = curDate && getStartOfWeek(curDate);
14388
+
14389
+ if (curDate !== null && curDate.getTime() !== startOfWeek.getTime())
14390
+ {
14391
+ val = Fit.Date.Format(startOfWeek, "YYYY-MM-DD" + (inputTime !== null ? " hh:mm" : ""));
14392
+ }
14393
+ }
14394
+
14087
14395
  var fireOnChange = (me.Value() !== val);
14088
14396
  var wasOpen = open;
14089
14397
 
@@ -14121,6 +14429,11 @@ Fit.Controls.DatePicker = function(ctlId)
14121
14429
 
14122
14430
  if (inputTimeMobile !== null)
14123
14431
  inputTimeMobile.value = inputTime.value;
14432
+
14433
+ if (selectWeek === true)
14434
+ {
14435
+ middleOfWeek = getMiddleOfWeek(date);
14436
+ }
14124
14437
  }
14125
14438
  else
14126
14439
  {
@@ -14143,6 +14456,11 @@ Fit.Controls.DatePicker = function(ctlId)
14143
14456
 
14144
14457
  if (inputTimeMobile !== null)
14145
14458
  inputTimeMobile.value = "";
14459
+
14460
+ if (selectWeek === true)
14461
+ {
14462
+ middleOfWeek = null;
14463
+ }
14146
14464
  }
14147
14465
 
14148
14466
  if (wasOpen === true)
@@ -14274,7 +14592,7 @@ Fit.Controls.DatePicker = function(ctlId)
14274
14592
 
14275
14593
  Fit.Internationalization.RemoveOnLocaleChanged(localize);
14276
14594
 
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;
14595
+ 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
14596
  base();
14279
14597
  });
14280
14598
 
@@ -14299,7 +14617,7 @@ Fit.Controls.DatePicker = function(ctlId)
14299
14617
  if (val !== undefined) // Allow Null
14300
14618
  {
14301
14619
  if (val !== null)
14302
- me.Value(val.getFullYear() + "-" + (val.getMonth() + 1) + "-" + val.getDate() + " " + val.getHours() + ":" + val.getMinutes());
14620
+ me.Value(Fit.Date.Format(val, "YYYY-MM-DD hh:mm"));
14303
14621
  else
14304
14622
  me.Clear();
14305
14623
  }
@@ -14307,30 +14625,7 @@ Fit.Controls.DatePicker = function(ctlId)
14307
14625
  // Get current value
14308
14626
 
14309
14627
  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
- }
14628
+ var date = getDateFromString(value, inputTime !== null);
14334
14629
 
14335
14630
  return date;
14336
14631
  }
@@ -14366,6 +14661,11 @@ Fit.Controls.DatePicker = function(ctlId)
14366
14661
  {
14367
14662
  localeEnforced = true;
14368
14663
  setLocale(val);
14664
+
14665
+ if (selectWeek === true)
14666
+ {
14667
+ selectFirstDayOfWeek(middleOfWeek);
14668
+ }
14369
14669
  }
14370
14670
 
14371
14671
  return locale;
@@ -14443,6 +14743,66 @@ Fit.Controls.DatePicker = function(ctlId)
14443
14743
  return placeholderTime;
14444
14744
  }
14445
14745
 
14746
+ /// <function container="Fit.Controls.DatePicker" name="TriggerIcon" access="public" returns="boolean">
14747
+ /// <description> Get/set value indicating whether a DatePicker trigger icon is shown </description>
14748
+ /// <param name="val" type="boolean" default="undefined"> If defined, True enables trigger icon (default), False disables it </param>
14749
+ /// </function>
14750
+ this.TriggerIcon = function(val)
14751
+ {
14752
+ Fit.Validation.ExpectBoolean(val, true);
14753
+
14754
+ if (Fit.Validation.IsSet(val) === true)
14755
+ {
14756
+ // Using opacity to hide icon as this allows us to still focus it on touch devices,
14757
+ // rather than focusing the input field, which will bring up the virtual keyboard.
14758
+ icon.style.opacity = val === false ? "0" : "";
14759
+ }
14760
+
14761
+ return icon.style.opacity === "";
14762
+ }
14763
+
14764
+ /// <function container="Fit.Controls.DatePicker" name="SelectWeek" access="public" returns="boolean">
14765
+ /// <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>
14766
+ /// <param name="val" type="boolean" default="undefined"> If defined, True enables week selection, False disables it (default) </param>
14767
+ /// </function>
14768
+ this.SelectWeek = function(val)
14769
+ {
14770
+ Fit.Validation.ExpectBoolean(val, true);
14771
+
14772
+ if (Fit.Validation.IsSet(val) === true)
14773
+ {
14774
+ if (val !== selectWeek)
14775
+ {
14776
+ var wasOpen = open;
14777
+
14778
+ // data-select-week attribute is added or removed when shared picker is opened,
14779
+ // so we need to close it and reopen it, for change to take effect - see Show().
14780
+
14781
+ if (wasOpen === true)
14782
+ {
14783
+ restoreView = true;
14784
+ me.Hide();
14785
+ }
14786
+
14787
+ middleOfWeek = val === true ? getMiddleOfWeek(me.Date()) : null;
14788
+ selectWeek = val;
14789
+
14790
+ if (val === true)
14791
+ {
14792
+ selectFirstDayOfWeek();
14793
+ }
14794
+
14795
+ if (wasOpen === true)
14796
+ {
14797
+ me.Show();
14798
+ restoreView = false;
14799
+ }
14800
+ }
14801
+ }
14802
+
14803
+ return selectWeek;
14804
+ }
14805
+
14446
14806
  this.WeekNumbers = function(val) // Not supported on mobile, and jQuery calendar is buggy: https://bugs.jqueryui.com/ticket/14907
14447
14807
  {
14448
14808
  Fit.Validation.ExpectBoolean(val, true);
@@ -14720,6 +15080,8 @@ Fit.Controls.DatePicker = function(ctlId)
14720
15080
  // by detecting the presence of a data-disable-light-dismiss="true" attribute.
14721
15081
  Fit.Dom.Data(calendarWidget, "disable-light-dismiss", "true");
14722
15082
 
15083
+ Fit.Dom.Data(calendarWidget, "select-week", selectWeek ? "true" : "false");
15084
+
14723
15085
  moveCalenderWidgetLocally();
14724
15086
 
14725
15087
  if (focused === inputTime)
@@ -14731,6 +15093,7 @@ Fit.Controls.DatePicker = function(ctlId)
14731
15093
  {
14732
15094
  if (inputMobile.showPicker !== undefined) // Chrome 99+, Safari 16+, Firefox 101+, Edge 99+
14733
15095
  {
15096
+ inputMobile.focus(); // This is what opens the picker in Safari on touch devices
14734
15097
  inputMobile.showPicker();
14735
15098
  }
14736
15099
  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 +15200,39 @@ Fit.Controls.DatePicker = function(ctlId)
14837
15200
  }
14838
15201
  }
14839
15202
 
15203
+ function getDateFromString(value, includeTime) // E.g. "2024-10-19" or "2024-10-19 16:38"
15204
+ {
15205
+ Fit.Validation.ExpectString(value);
15206
+ Fit.Validation.ExpectBoolean(includeTime);
15207
+
15208
+ var date = null;
15209
+
15210
+ if (value !== "")
15211
+ {
15212
+ try
15213
+ {
15214
+ date = Fit.Date.Parse(value, "YYYY-MM-DD" + (value.indexOf(":") !== -1 ? " hh:mm" : ""));
15215
+ }
15216
+ catch (err)
15217
+ {
15218
+ }
15219
+ }
15220
+
15221
+ if (date !== null)
15222
+ {
15223
+ if (includeTime === false)
15224
+ {
15225
+ date.setHours(0);
15226
+ date.setMinutes(0);
15227
+ }
15228
+
15229
+ date.setSeconds(0);
15230
+ date.setMilliseconds(0);
15231
+ }
15232
+
15233
+ return date;
15234
+ }
15235
+
14840
15236
  function createDatePicker()
14841
15237
  {
14842
15238
  var jq = jquery;
@@ -14847,8 +15243,8 @@ Fit.Controls.DatePicker = function(ctlId)
14847
15243
  showAnim: false,
14848
15244
  showWeek: weeks, // Buggy - does not work if week starts on sunday: https://bugs.jqueryui.com/ticket/14907
14849
15245
  //firstDay: 1,
14850
- changeMonth: true,
14851
- changeYear: true,
15246
+ 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
15247
+ 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
15248
  dateFormat: getJqueryUiDatePickerFormat(me.Format()),
14853
15249
  defaultDate: null,
14854
15250
  onChangeMonthYear: function(year, month, dp) // Fires when changing year/month but also when simply opening calendar widget
@@ -14857,7 +15253,14 @@ Fit.Controls.DatePicker = function(ctlId)
14857
15253
  // widget, which causes its DOM to be removed and replaced.
14858
15254
  // Focus is later returned to DatePicker, but not in time for
14859
15255
  // 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.
15256
+ if (Fit.Device.OptimizeForTouch === true && me.TriggerIcon() === true)
15257
+ {
15258
+ icon.focus(); // Focusing icon to prevent virtual keyboard from being shown on touch devices
15259
+ }
15260
+ else
15261
+ {
15262
+ input._focus(); // Do not use Focused(true) as it will not re-focus input, since control is already considered focused
15263
+ }
14861
15264
 
14862
15265
  if (open === true) // Remember which year and month the user navigated to
14863
15266
  {
@@ -14874,7 +15277,16 @@ Fit.Controls.DatePicker = function(ctlId)
14874
15277
  onSelect: function(dateText, dp) // Notice: jQuery UI DatePicker no longer fires input.OnChange when OnSelect is registered
14875
15278
  {
14876
15279
  startDate = null;
14877
- input.focus(); // Do not use Focused(true) as it will not re-focus input, since control is already considered focused
15280
+
15281
+ if (Fit.Device.OptimizeForTouch === true && me.TriggerIcon() === true)
15282
+ {
15283
+ icon.focus(); // Focusing icon to prevent virtual keyboard from being shown on touch devices
15284
+ }
15285
+ else
15286
+ {
15287
+ input._focus(); // Do not use Focused(true) as it will not re-focus input, since control is already considered focused
15288
+ }
15289
+
14878
15290
  input.onchange();
14879
15291
  },
14880
15292
  beforeShow: function(elm, dp)
@@ -14926,6 +15338,8 @@ Fit.Controls.DatePicker = function(ctlId)
14926
15338
  datepicker.datepicker("option", "dateFormat", getJqueryUiDatePickerFormat(me.Format()));
14927
15339
  datepicker.datepicker("option", "showWeek", weeks);
14928
15340
  datepicker.datepicker("option", "yearRange", datePickerYears);
15341
+ datepicker.datepicker("option", "showOtherMonths", true);
15342
+ datepicker.datepicker("option", "selectOtherMonths", true);
14929
15343
  }
14930
15344
 
14931
15345
  if (me.Value() === "" && datepickerDate !== null) // Apply initial year and month selection
@@ -14969,7 +15383,9 @@ Fit.Controls.DatePicker = function(ctlId)
14969
15383
 
14970
15384
  me._internal.ExecuteWithNoOnChange(function()
14971
15385
  {
14972
- me.Value(val);
15386
+ var middleOfWeekBefore = middleOfWeek;
15387
+ me.Value(val); // Changes middleOfWeek (restored below)
15388
+ middleOfWeek = middleOfWeekBefore;
14973
15389
  });
14974
15390
  }
14975
15391
  },
@@ -14994,7 +15410,7 @@ Fit.Controls.DatePicker = function(ctlId)
14994
15410
  // with something else on the page.
14995
15411
  // If the user decides to return focus to the control, it will not cause OnFocus to fire again,
14996
15412
  // without firing OnBlur in-between, thanks to the 'focused' flag.
14997
- if (focused === true && Fit.Dom.GetFocused() !== input)
15413
+ if (focused === true && Fit.Dom.GetFocused() !== input && Fit.Dom.GetFocused() !== icon)
14998
15414
  {
14999
15415
  me._internal.FireOnBlur();
15000
15416
  }
@@ -15148,7 +15564,7 @@ Fit.Controls.DatePicker = function(ctlId)
15148
15564
 
15149
15565
  if (focusFix)
15150
15566
  {
15151
- input.focus();
15567
+ input._focus();
15152
15568
  }
15153
15569
 
15154
15570
  inputMobile.valueAsDate = date;
@@ -15159,6 +15575,145 @@ Fit.Controls.DatePicker = function(ctlId)
15159
15575
  }
15160
15576
  }
15161
15577
 
15578
+ function getMiddleOfWeek(date)
15579
+ {
15580
+ Fit.Validation.ExpectDate(date, true);
15581
+
15582
+ if (!date)
15583
+ {
15584
+ return null;
15585
+ }
15586
+
15587
+ var firstDay = getJqueryDateFormatFromLocale(locale).firstDay; // 0 = sunday, 1 = monday
15588
+ var day = date.getDay(); // 0 = sunday, ... 6 = saturday
15589
+
15590
+ if (firstDay === 0) // Sunday is start of week
15591
+ {
15592
+ // S M T W T F S
15593
+ // 0 1 2 3 4 5 6
15594
+ // ^
15595
+ var daysFromWednesday = 3 - day; // 3 = wednesday
15596
+
15597
+ var middle = new Date(date.getTime());
15598
+ middle.setDate(date.getDate() + daysFromWednesday);
15599
+ return middle;
15600
+ }
15601
+ else if (firstDay === 1) // Monday is start of week
15602
+ {
15603
+ // Adjust day so it matches a calendar going from monday to sunday
15604
+ // M T W T F S S
15605
+ // 0 1 2 3 4 5 6
15606
+ // ^
15607
+ day = day === 0 ? 6 : day - 1; // 0 = monday, 6 = sunday
15608
+ var daysFromWednesday = 2 - day; // 2 = wednesday
15609
+
15610
+ var middle = new Date(date.getTime());
15611
+ middle.setDate(date.getDate() + daysFromWednesday);
15612
+ return middle;
15613
+ }
15614
+ else if (firstDay === 6) // Saturday is start of week (locale "fa" (Persian), ar-DZ (Arabic - Algeria))
15615
+ {
15616
+ // Adjust day so it matches a calendar going from saturday to friday
15617
+ // S S M T W T F
15618
+ // 0 1 2 3 4 5 6
15619
+ // ^
15620
+ day = day === 0 ? 1 : day === 6 ? 0 : day + 1; // 0 = saturday, 6 = friday
15621
+ var daysFromWednesday = 4 - day; // 4 = wednesday
15622
+
15623
+ var middle = new Date(date.getTime());
15624
+ middle.setDate(date.getDate() + daysFromWednesday);
15625
+ return middle;
15626
+ }
15627
+
15628
+ throw "Unable to determine middle of week - locale with unsupported calendar"; // This should never happen
15629
+ }
15630
+
15631
+ function getStartOfWeek(date)
15632
+ {
15633
+ Fit.Validation.ExpectDate(date);
15634
+
15635
+ var firstDay = getJqueryDateFormatFromLocale(locale).firstDay;
15636
+
15637
+ if (date.getDay() !== firstDay)
15638
+ {
15639
+ var selectedDay = date.getDay(); // 0 = sunday, ... 6 = saturday
15640
+ var daysFromWeekStart = -1;
15641
+
15642
+ if (firstDay === 0) // Sunday is start of week
15643
+ {
15644
+ // S M T W T F S
15645
+ // 0 1 2 3 4 5 6
15646
+ daysFromWeekStart = selectedDay;
15647
+ }
15648
+ else if (firstDay === 1) // Monday is start of week
15649
+ {
15650
+ // M T W T F S S
15651
+ // 1 2 3 4 5 6 0
15652
+ daysFromWeekStart = date.getDay() === 0 ? 6 : date.getDay() - 1;
15653
+ }
15654
+ else if (firstDay === 6) // Saturday is start of week (locale "fa" (Persian), ar-DZ (Arabic - Algeria))
15655
+ {
15656
+ // S S M T W T F
15657
+ // 6 0 1 2 3 4 5
15658
+ daysFromWeekStart = date.getDay() === 6 ? 0 : date.getDay() + 1;
15659
+ }
15660
+
15661
+ if (daysFromWeekStart === -1)
15662
+ {
15663
+ throw "Unable to determine number of days from week start - locale with unsupported calendar"; // This should never happen
15664
+ }
15665
+
15666
+ var weekStart = new Date(date.getTime() - (daysFromWeekStart * (24 * 60 * 60 * 1000)));
15667
+
15668
+ // Prevent adjustment for summer/winter time - keep (restore) time
15669
+ weekStart.setHours(date.getHours());
15670
+ weekStart.setMinutes(date.getMinutes());
15671
+
15672
+ return weekStart;
15673
+ }
15674
+ else
15675
+ {
15676
+ return new Date(date.getTime()); // Return new instance like code above
15677
+ }
15678
+ }
15679
+
15680
+ function selectFirstDayOfWeek(forceDate)
15681
+ {
15682
+ Fit.Validation.ExpectDate(forceDate, true);
15683
+
15684
+ var curDateTime = forceDate || me.Date();
15685
+ var startOfWeek = curDateTime && getStartOfWeek(curDateTime);
15686
+
15687
+ if (curDateTime !== null && curDateTime.getTime() !== startOfWeek.getTime())
15688
+ {
15689
+ var selectWeekStart = function()
15690
+ {
15691
+ var middleOfWeekBefore = middleOfWeek;
15692
+ me.Date(startOfWeek); // Changes middleOfWeek (restored below) - also fires OnChange
15693
+ middleOfWeek = middleOfWeekBefore;
15694
+ };
15695
+
15696
+ if (Fit.Date.Format(startOfWeek, me.Format()) === preVal)
15697
+ {
15698
+ // New date is the same as the one previously selected, meaning user selected a day in the week already
15699
+ // selected, resulting in start of week being selected again - OnChange should not fire in this case.
15700
+ me._internal.ExecuteWithNoOnChange(function()
15701
+ {
15702
+ selectWeekStart();
15703
+ });
15704
+ }
15705
+ else
15706
+ {
15707
+ // A new start of week selected - OnChange must fire
15708
+ selectWeekStart();
15709
+ }
15710
+
15711
+ return true; // Indicate that value was changed
15712
+ }
15713
+
15714
+ return false; // Indicate that no change was made
15715
+ }
15716
+
15162
15717
  function getLocales()
15163
15718
  {
15164
15719
  // List of locales was generated this way:
@@ -15184,7 +15739,8 @@ Fit.Controls.DatePicker = function(ctlId)
15184
15739
  // # });
15185
15740
  // 4) Insert JSON written to console into variable below.
15186
15741
 
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"};
15742
+ //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"};
15743
+ 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
15744
  }
15189
15745
 
15190
15746
  function getDatePlaceholder()
@@ -15201,11 +15757,13 @@ Fit.Controls.DatePicker = function(ctlId)
15201
15757
  {
15202
15758
  Fit.Validation.ExpectString(val);
15203
15759
 
15204
- var newFormat = getJqueryDateFormatFromLocale(val); // Null if locale does not exist
15760
+ var loc = getJqueryDateFormatFromLocale(val); // Null if locale does not exist
15205
15761
 
15206
- if (newFormat === null)
15762
+ if (loc === null)
15207
15763
  Fit.Validation.ThrowError("Unknown locale '" + val + "'");
15208
15764
 
15765
+ var newFormat = loc.format;
15766
+
15209
15767
  var wasOpen = open;
15210
15768
 
15211
15769
  if (wasOpen === true)
@@ -15326,6 +15884,7 @@ Fit.Controls.DatePicker = function(ctlId)
15326
15884
 
15327
15885
  Fit._internal.Controls.DatePicker = {};
15328
15886
 
15887
+ Fit._internal.Controls.DatePicker.UseNativePickerOnTouch = false;
15329
15888
  /// <container name="Fit.Controls.Dialog" extends="Fit.Controls.Component">
15330
15889
  /// Simple Dialog control with support for Fit.UI buttons.
15331
15890
  /// </container>