123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- (function ($) {
- Drupal.behaviors.dateYearRange = {};
- Drupal.behaviors.dateYearRange.attach = function (context, settings) {
- var $textfield, $textfields, i;
- // Turn the years back and forward fieldsets into dropdowns.
- $textfields = $('input.select-list-with-custom-option', context).once('date-year-range');
- for (i = 0; i < $textfields.length; i++) {
- $textfield = $($textfields[i]);
- new Drupal.dateYearRange.SelectListWithCustomOption($textfield);
- }
- };
- Drupal.dateYearRange = {};
- /**
- * Constructor for the SelectListWithCustomOption object.
- *
- * This object is responsible for turning the years back and forward textfields
- * into dropdowns with an 'other' option that lets the user enter a custom
- * value.
- */
- Drupal.dateYearRange.SelectListWithCustomOption = function ($textfield) {
- this.$textfield = $textfield;
- this.$description = $textfield.next('div.description');
- this.defaultValue = $textfield.val();
- this.$dropdown = this.createDropdown();
- this.$dropdown.insertBefore($textfield);
- };
- /**
- * Get the value of the textfield as it existed on page load.
- *
- * @param {String} type
- * The type of the variable to be returned. Defaults to string.
- * @return
- * The original value of the textfield. Returned as an integer, if the type
- * parameter was 'int'.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.getOriginal = function (type) {
- var original;
- if (type === 'int') {
- original = parseInt(this.defaultValue, 10);
- if (window.isNaN(original)) {
- original = 0;
- }
- }
- else {
- original = this.defaultValue;
- }
- return original;
- };
- /**
- * Get the correct first value for the dropdown.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.getStartValue = function () {
- var direction = this.getDirection();
- var start;
- switch (direction) {
- case 'back':
- // For the 'years back' dropdown, the first option should be -10, unless
- // the default value of the textfield is even smaller than that.
- start = Math.min(this.getOriginal('int'), -10);
- break;
- case 'forward':
- start = 0;
- break;
- }
- return start;
- };
- /**
- * Get the correct last value for the dropdown.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.getEndValue = function () {
- var direction = this.getDirection();
- var end;
- var originalString = this.getOriginal();
- switch (direction) {
- case 'back':
- end = 0;
- break;
- case 'forward':
- // If the original value of the textfield is an absolute year such as
- // 2020, don't try to include it in the dropdown.
- if (originalString.indexOf('+') === -1) {
- end = 10;
- }
- // If the original value is a relative value (+x), we want it to be
- // included in the possible dropdown values.
- else {
- end = Math.max(this.getOriginal('int'), 10);
- }
- break;
- }
- return end;
- };
- /**
- * Create a dropdown select list with the correct options for this textfield.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.createDropdown = function () {
- var $dropdown = $('<select>').addClass('form-select date-year-range-select');
- var $option, i, value;
- var start = this.getStartValue();
- var end = this.getEndValue();
- var direction = this.getDirection();
- for (i = start; i <= end; i++) {
- // Make sure we include the +/- sign in the option value.
- value = i;
- if (i > 0) {
- value = '+' + i;
- }
- // Zero values must have a + or - in front.
- if (i === 0) {
- if (direction === 'back') {
- value = '-' + i;
- }
- else {
- value = '+' + i;
- }
- }
- $option = $('<option>' + Drupal.formatPlural(value, '@count year from now', '@count years from now') + '</option>').val(value);
- $dropdown.append($option);
- }
- // Create an 'Other' option.
- $option = $('<option class="custom-option">' + Drupal.t('Other') + '</option>').val('');
- $dropdown.append($option);
- // When the user changes the selected option in the dropdown, perform
- // appropriate actions (such as showing or hiding the textfield).
- $dropdown.bind('change', $.proxy(this.handleDropdownChange, this));
- // Set the initial value of the dropdown.
- this._setInitialDropdownValue($dropdown);
- return $dropdown;
- };
- Drupal.dateYearRange.SelectListWithCustomOption.prototype._setInitialDropdownValue = function ($dropdown) {
- var textfieldValue = this.getOriginal();
- // Determine whether the original textfield value exists in the dropdown.
- var possible = $dropdown.find('option[value="' + textfieldValue + '"]');
- // If the original textfield value is one of the dropdown options, preselect
- // it and hide the 'other' textfield.
- if (possible.length) {
- $dropdown.val(textfieldValue);
- this.hideTextfield();
- }
- // If the original textfield value isn't one of the dropdown options, choose
- // the 'Other' option in the dropdown.
- else {
- $dropdown.val('');
- }
- };
- /**
- * Determine whether this is the "years back" or "years forward" textfield.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.getDirection = function () {
- if (this.direction) {
- return this.direction;
- }
- var direction;
- if (this.$textfield.hasClass('back')) {
- direction = 'back';
- }
- else if (this.$textfield.hasClass('forward')) {
- direction = 'forward';
- }
- this.direction = direction;
- return direction;
- };
- /**
- * Change handler for the dropdown, to modify the textfield as appropriate.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.handleDropdownChange = function () {
- // Since the dropdown changed, we need to make the content of the textfield
- // match the (new) selected option.
- this.syncTextfield();
- // Show the textfield if the 'Other' option was selected, and hide it if one
- // of the preset options was selected.
- if ($(':selected', this.$dropdown).hasClass('custom-option')) {
- this.revealTextfield();
- }
- else {
- this.hideTextfield();
- }
- };
- /**
- * Display the textfield and its description.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.revealTextfield = function () {
- this.$textfield.show();
- this.$description.show();
- };
- /**
- * Hide the textfield and its description.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.hideTextfield = function () {
- this.$textfield.hide();
- this.$description.hide();
- };
- /**
- * Copy the selected value of the dropdown to the textfield.
- *
- * FAPI doesn't know about the JS-only dropdown, so the textfield needs to
- * reflect the value of the dropdown.
- */
- Drupal.dateYearRange.SelectListWithCustomOption.prototype.syncTextfield = function () {
- var value = this.$dropdown.val();
- this.$textfield.val(value);
- };
- })(jQuery);
|