PageSourceSearch

https://nybc.net/administrator/components/com_civicrm/civicrm/js/crm.datepicker.js?r=IQeWUen_US

js nybc.net collected 2026-10-02 10:09:06 UTC 8,451 bytes, 192 lines download raw bytes

1(function($, CRM, _) {
2  "use strict";
3
4  /**
5   * @see https://docs.civicrm.org/dev/en/latest/framework/ui/#date-picker
6   */
7  $.fn.crmDatepicker = function(options) {
8    return $(this).each(function() {
9      if ($(this).is('.crm-form-date-wrapper .crm-hidden-date')) {
10        // Already initialized - destroy
11        $(this)
12          .off('.crmDatepicker')
13          .css('display', '')
14          .removeClass('crm-hidden-date')
15          .siblings().remove();
16        $(this).unwrap();
17      }
18      if (options === 'destroy') {
19        return;
20      }
21      var
22        $dataField = $(this).wrap('<span class="crm-form-date-wrapper" />'),
23        settings = _.cloneDeep(options || {}),
24        $dateField = $(),
25        $timeField = $(),
26        $clearLink = $(),
27        placeholder,
28        hasDatepicker = settings.date !== false && settings.date !== 'yy',
29        type = hasDatepicker ? 'text' : 'number';
30
31      if (settings.allowClear !== undefined ? settings.allowClear : !$dataField.is('.required, [required]')) {
32        $clearLink = $('<a class="crm-hover-button crm-clear-link" title="'+ _.escape(ts('Clear')) +'"><i class="crm-i fa-times" role="img" aria-hidden="true"></i></a>')
33          .insertAfter($dataField);
34      }
35      if (settings.time !== false) {
36        $timeField = $('<input>').insertAfter($dataField);
37        placeholder = settings.timePlaceholder || $dataField.attr('time-placeholder');
38        CRM.utils.copyAttributes($dataField, $timeField, ['class', 'disabled', 'required']);
39        $timeField.removeClass(stripNgClasses);
40        $timeField
41          .removeClass('two four eight twelve twenty medium big huge crm-auto-width')
42          .addClass('crm-form-text crm-form-time six')
43          // Set default placeholder as clock icon (`fa-clock` is Unicode f017)
44          .attr('placeholder', placeholder === undefined ? '\uf017' : placeholder)
45          .attr('aria-label', placeholder === undefined ? ts('Time') : placeholder)
46          .change(updateDataField)
47          .timeEntry({
48            spinnerImage: '',
49            useMouseWheel: false,
50            defaultTime: new Date(new Date().setMinutes(0)),
51            show24Hours: settings.time === true || settings.time === undefined ? CRM.config.timeIs24Hr : settings.time == '24'
52          });
53        if (!placeholder) {
54          $timeField.addClass('crm-placeholder-icon');
55        }
56      }
57      if (settings.date !== false) {
58        // Render "number" field for year-only format, calendar popup for all other formats
59        $dateField = $('<input type="' + type + '">').insertAfter($dataField);
60        CRM.utils.copyAttributes($dataField, $dateField, ['style', 'class', 'disabled', 'aria-label', 'required']);
61        $dateField.removeClass(stripNgClasses);
62        placeholder = settings.placeholder || $dataField.attr('placeholder');
63        $dateField.addClass('crm-form-' + type);
64        if (!settings.minDate && isInt(settings.start_date_years)) {
65          settings.minDate = '' + (new Date().getFullYear() - settings.start_date_years) + '-01-01';
66        }
67        if (!settings.maxDate && isInt(settings.end_date_years)) {
68          settings.maxDate = '' + (new Date().getFullYear() + settings.end_date_years) + '-12-31';
69        }
70        if (hasDatepicker) {
71          settings.minDate = settings.minDate ? CRM.utils.makeDate(settings.minDate) : null;
72          settings.maxDate = settings.maxDate ? CRM.utils.makeDate(settings.maxDate) : null;
73          settings.dateFormat = typeof settings.date === 'string' ? settings.date : CRM.config.dateInputFormat;
74          settings.changeMonth = _.includes(settings.dateFormat, 'm');
75          settings.changeYear = _.includes(settings.dateFormat, 'y');
76          if (!settings.yearRange && settings.minDate !== null && settings.maxDate !== null) {
77            settings.yearRange = '' + CRM.utils.formatDate(settings.minDate, 'yy') + ':' + CRM.utils.formatDate(settings.maxDate, 'yy');
78          }
79          settings.onSelect = function (dateText, inst) {
80            updateDataField();
81            if (settings.time !== false) {
82              $timeField.focus();
83            } else {
84              $(this).focus();
85            }
86          };
87          $dateField.addClass('crm-form-date').datepicker(settings);
88        } else {
89          $dateField.attr('min', settings.minDate ? CRM.utils.formatDate(settings.minDate, 'yy') : '1000');
90          $dateField.attr('max', settings.maxDate ? CRM.utils.formatDate(settings.maxDate, 'yy') : '4000');
91          placeholder = null;
92        }
93        // Set placeholder as calendar icon (`fa-calendar` is Unicode f073)
94        $dateField.attr({placeholder: placeholder === undefined ? '\uF073' : placeholder}).change(updateDataField);
95        if (!placeholder) {
96          $dateField.addClass('crm-placeholder-icon').attr('aria-label', ts('Select Date'));
97        }
98        else {
99          $dateField.attr('aria-label', placeholder);
100        }
101      }
102      // Rudimentary validation. TODO: Roll into use of jQUery validate and ui.datepicker.validation
103      function isValidDate() {
104        // FIXME: parseDate doesn't work with incomplete date formats; skip validation if no month, day or year in format
105        var lowerFormat = settings.dateFormat.toLowerCase();
106        if (lowerFormat.indexOf('y') < 0 || lowerFormat.indexOf('m') < 0 || !dateHasDay()) {
107          return true;
108        }
109        try {
110          $.datepicker.parseDate(settings.dateFormat, $dateField.val());
111          return true;
112        } catch (e) {
113          return false;
114        }
115      }
116
117      /**
118       * Does the date format contain the day.
119       *
120       * @returns {boolean}
121       */
122      function dateHasDay() {
123        var lowerFormat = settings.dateFormat.toLowerCase();
124        return lowerFormat.indexOf('d') >= 0;
125      }
126      function updateInputFields(e, context) {
127        var val = $dataField.val(),
128          time = null;
129        if (context !== 'userInput' && context !== 'crmClear') {
130          if (hasDatepicker) {
131            $dateField.datepicker('setDate', _.includes(val, '-') ? $.datepicker.parseDate('yy-mm-dd', val) : null);
132          } else if ($dateField.length) {
133            $dateField.val(val.slice(0, 4));
134          }
135          if ($timeField.length) {
136            if (val.length === 8) {
137              time = val;
138            } else if (val.length === 19) {
139              time = val.split(' ')[1];
140            }
141            $timeField.timeEntry('setTime', time);
142          }
143        }
144        $clearLink.css('visibility', val ? 'visible' : 'hidden');
145      }
146      function updateDataField(e, context) {
147        // The crmClear event wipes all the field values anyway, so no need to respond
148        if (context !== 'crmClear') {
149          var val = '';
150          if ($dateField.val()) {
151            if (hasDatepicker && isValidDate() && dateHasDay()) {
152              val = $.datepicker.formatDate('yy-mm-dd', $dateField.datepicker('getDate'));
153              $dateField.removeClass('crm-error');
154            } else if (!hasDatepicker) {
155              val = $dateField.val() + '-01-01';
156            }
157            else if (!dateHasDay()) {
158              // This would be a Year-month date (yyyy-mm)
159              // it could be argued it should not use a datepicker....
160              val = $dateField.val() + '-01';
161            } else {
162              $dateField.addClass('crm-error');
163            }
164          }
165          if ($timeField.val()) {
166            val += (val ? ' ' : '') + $timeField.timeEntry('getTime').toTimeString().substr(0, 8);
167          }
168          $dataField.val(val).trigger('change', ['userInput']);
169        }
170      }
171      $dataField.hide().addClass('crm-hidden-date').on('change.crmDatepicker', updateInputFields);
172      updateInputFields();
173    });
174  };
175
176  function isInt(value) {
177    if (isNaN(value)) {
178      return false;
179    }
180    var x = parseFloat(value);
181    return (x | 0) === x;
182  }
183
184  // jQuery removeClass callback: strips Angular's transient state classes (ng-*).
185  // copyAttributes() snapshots the source field's `class` verbatim onto the generated
186  // display inputs, which are NOT ng-model-bound, so any ng-invalid/ng-pristine/etc. froze
187  // there as a "phantom" that shadowed real invalid fields during afForm validation.
188  function stripNgClasses(i, cls) {
189    return cls.split(/\s+/).filter(function(c) { return c.indexOf('ng-') === 0; }).join(' ');
190  }
191
192})(jQuery, CRM, CRM._);

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.