Sabre Spark

DateInput

A date input container.

Option name Type Description
module components/date-input.js
Example
new DateInput(el, {
  // Optional. Callback for when the input value changes.
  onChange: function(inputInstance, value) {}
});

DateInput

function
 DateInput() 

DateInput constructor.

Option name Type Description
el Element
params Object
var DateInput = function(el, params) {

  if (!el) {
    return;
  }

  this._setParams(this.defaults, true);
  this._cacheElements(el);
  this._bindEventListenerCallbacks();
  this._setParams(params || {});
  this._parseParams();
  this._convertLabel();
  this._initializeInputs();
  this._updateClass();
  this._addEventListeners();
};

DateInput.prototype = {

_setParams

property
 _setParams 

Include common functionality.

_setParams: Base.setParams,
_toggleClass: Base.toggleClass,
_removeClass: Base.removeClass,
_addClass: Base.addClass,
_hasClass: Base.hasClass,
_getChildIndex: Base.getChildIndex,
_appendChildren: Base.appendChildren,
_triggerEvent: Base.triggerEvent,
_copyAttributes: Base.copyAttributes,
_getElementMatchingParent: Base.getElementMatchingParent,

setError

property
 setError 

Inherit functionality from TextInput.

setError: TextInput.prototype.setError,
clearError: TextInput.prototype.clearError,
setWarning: TextInput.prototype.setWarning,
clearWarning: TextInput.prototype.clearWarning,
setSuccess: TextInput.prototype.setSuccess,
clearSuccess: TextInput.prototype.clearSuccess,
clearMessages: TextInput.prototype.clearMessages,
setMessage: TextInput.prototype.setMessage,
_showMessage: TextInput.prototype._showMessage,
_hideMessage: TextInput.prototype._hideMessage,
_isMessageVisible: TextInput.prototype._isMessageVisible,

_whitelistedParams

property
 _whitelistedParams 

Whitelisted parameters which can be set on construction.

Option name Type Description
_whitelistedParams: ['onChange', 'onFocus', 'onBlur', 'isTypeahead', 'isSelect', 'format', 'textFormat', 'showDateAsText'],

defaults

property
 defaults 

Default values for internal properties we will be setting.
These are set on each construction so we don't leak properties
into the prototype chain.

Option name Type Description
defaults: {
  el: null,
  inputEl: null,
  messageEl: null,
  toggleEl: null,
  inFocus: null,
  isActive: null,
  isSelect: null,
  isTypeahead: null,
  typeaheads: null,
  typeaheadEls: null,
  selects: null,
  selectEls: null,
  format: null,
  parsedFormat: null,
  showDateAsText: null,
  runningTypeaheads: false,
  textFormat: null,
  onChange: null,
  onFocus: null,
  onBlur: null,
  _hasFocus: false,
  _pauseInputChange: false,
  _onClickBound: null,
  _onPieceChangeBound: null,
  _onTypeaheadFocusBound: null,
  _onTypeaheadBlurBound: null,
  _onTypeaheadBackspaceBound: null,
  _onTypeaheadEndBound: null,
  _onInputChangeBound: null
},

show

method
 show() 

Show the input by adding the active state and setting character counts (if necessary).

show: function() {

  if (!this.isActive) {
    this._runTypeaheads();
    this.isActive = true;
    this._updateClass();
  }
},

hide

method
 hide() 

Hide the input by removing the active state.

hide: function() {
  this.isActive = false;
  this._updateClass();
},

remove

method
 remove() 

Augment default remove call w/ helper cleanup.

remove: function() {

  Base.remove.apply(this, arguments);

  // Remove text input
  this.textInput.remove();
  delete this.textInput;

  // Remove typeaheads
  if (this.typeaheads) {
    for (var i in this.typeaheads) {
      this.typeaheads[i].remove();
    }
  }

  // Remove select inputs
  if (this.selectEls) {
    this.selectEls.forEach(this._removeSelectPiece.bind(this));
  }
},

setValue

method
 setValue() 

Given an object with day, month and year, set the value of the input.

Option name Type Description
values Object
setValue: function(values) {

  values = values || {
    day: '',
    month: '',
    year: ''
  };
  var i;
  var hadValue;

  for (i in this.typeaheads) {
    if (values[i] !== undefined) {
      this.typeaheads[i].setValue(values[i]);
      hadValue = hadValue || (values[i] ? true : false);
    }
  }

  for (i in this.selects) {
    if (values[i] !== undefined) {
      this.selects[i].setValue(values[i]);
      hadValue = hadValue || (values[i] ? true : false);
    }
  }

  if (!this.isActive && hadValue) {
    this.isActive = true;
  }

  this._padTypeaheads();
  this._updateClass();
  this.updateInput();
},

validate

method
 validate() 

Validate the date values.

validate: function() {

  if (this.isTypeahead) {
    this._validateTypeaheads();
  }
  else if (this.isSelect) {
    this._validateSelects();
  }
},

updateInput

method
 updateInput() 

Update the input values to match the typeaheads.

updateInput: function() {

  var inputs;

  if (this.isTypeahead && this.typeaheads) {
    inputs = this.typeaheads;
  }
  else if (this.isSelect) {
    inputs = this.selects;
  }

  if (inputs) {

    var day = (inputs.day && inputs.day.getValue(true)) || 0;
    var month = (inputs.month && inputs.month.getValue(true)) || 0;
    var year = (inputs.year && inputs.year.getValue(true)) || 0;

    var val = this.inputEl.value;

    this.inputEl.value = [day, month, year].indexOf(0) === -1 ? padNumber(year, 4) + '-' + padNumber(month, 2) + '-' + padNumber(day, 2) : '';

    if (val !== this.inputEl.value) {
      this._pauseInputChange = true;
      this._triggerEvent(this.inputEl, 'change');
      (this.onChange || noop)(this.inputEl.value, this.inputEl);
      this._pauseInputChange = false;
    }

  }
},

focus

method
 focus() 

Move the focus to a typeahead element.

Option name Type Description
i Number
character String

Optional A character to add

focus: function(i, character) {

  if (!this.isActive || !this.inFocus) {
    return;
  }

  var index = this.typeaheadEls.indexOf(this.inFocus.typeahead.el);
  var sib = this.typeaheadEls[index + i];
  var typeahead;

  // If we were passed a character to prepend, find the typeahead for this element
  if (character) {
    typeahead = this._getTypeaheadByElement(sib);
    if (typeahead) {
      typeahead.typeahead.addCharacterAtIndex(character, 0);
    }
  }

  if (!sib) {
    return false;
  }

  var sibInput = sib.querySelector('input');

  if (sibInput) {
    sibInput.focus();

    // If we have a typeahead (because we needed to prepend a character), move the caret.
    if (typeahead) {
      typeahead.typeahead.moveCaret(1);
    }
  }

  return true;
},

focusNext

method
 focusNext() 

Move the focus to the next element.

Option name Type Description
character String

Optional A character to add

focusNext: function(character) {
  if (this.focus(1, character)) {
    if (this.inFocus && !character)
      this.inFocus.typeahead.moveCaretToStart();
  }
},

focusPrevious

method
 focusPrevious() 

Move the focus to the next element.

Option name Type Description
character String

Optional A character to add

focusPrevious: function(character) {
  if (this.focus(-1, character)) {
    if (this.inFocus)
      this.inFocus.typeahead.moveCaretToEnd();
  }
},

hasPartialValue

method
 hasPartialValue() 

Do we have any values?

Option name Type Description
return Boolean
hasPartialValue: function() {

  var i;

  for (i in this.typeaheads) {
    if (this.typeaheads[i].getValue()) {
      return true;
    }
  }

  for (i in this.selects) {
    if (this.selects[i].getValue()) {
      return true;
    }
  }

  return false;
},

_cacheElements

method
 _cacheElements() 

Store a reference to the needed elements.

Option name Type Description
el Element
_cacheElements: function(el) {

  this.el = el;

  this.inputEl = this.el.querySelector('[type="date"]');

  if (!this.inputEl) {
    throw new Error('No <input type="date"> element present in date input container!', this.el);
  }

  this.toggleEl = this.el.querySelector('.spark-date__toggle');

  this.messageEl = this.el.querySelector('.spark-input__message') || document.createElement('span');
},

_parseParams

method
 _parseParams() 

Parse parameters from the elements.

_parseParams: function() {

  this.isActive = this.isActive === null ? (this.inputEl.value ? true : false) : this.isActive;
  this.isSelect = this.isSelect === null ? (this._hasClass(this.el, 'spark-date--select') ? true : false) : this.isSelect;
  this.isTypeahead = this.isTypeahead === null ? (!this.isSelect ? true : false) : this.isTypeahead;
  this.format = this.format === null ? (this.inputEl.getAttribute('data-format') ? this.inputEl.getAttribute('data-format') : 'MM-DD-YYYY') : this.format;
  this.textFormat = this.textFormat === null ? (this.inputEl.getAttribute('data-text-format') ? this.inputEl.getAttribute('data-text-format') : 'MM DD YYYY') : this.textFormat;
  this.showDateAsText = this.showDateAsText === null ? this.inputEl.getAttribute('data-show-date-as-text') !== null : this.showDateAsText;

  this.parsedFormat = parseDateFormat(this.format);
  this.parsedTextFormat = parseDateFormat(this.textFormat);
  this.min = this.inputEl.getAttribute('min') && parsedDomFormat.getValues(this.inputEl.getAttribute('min'));
  this.max = this.inputEl.getAttribute('max') && parsedDomFormat.getValues(this.inputEl.getAttribute('max'));
},

_initializeInputs

method
 _initializeInputs() 

Setup the proper inputs. This could mean creating a typeahead, or creating selects.

_initializeInputs: function() {

  // @todo: remove this when Android fixes its keyup/keypress/keydown bug
  // http://stackoverflow.com/questions/17139039/keycode-is-always-zero-in-chrome-for-android
  if (this.isTypeahead) {
    this._initializeInputPieces();
    this._runTypeaheads();
  }
  else if (this.isSelect) {
    this._removeClass(this.el, 'spark-input');
    this._initializeInputPieces();
  }
},

_initializeInputPieces

method
 _initializeInputPieces() 

Replace the date input with a group of typeaheads or select inputs.
Keep the date input around and store the typeahead data in there in an ISO date format.

_initializeInputPieces: function() {

  // Hide the original element. This will be updated as the typeahead values change
  this.inputEl.style.display = 'none';

  var els = [];
  var label;

  // Create a new typeahead for each part of the parsed format. Also add placeholder elements.
  this.parsedFormat.parts.forEach(function(part) {
    // Something weird with Node that makes us have to specify what `this` is here.
    (this.isTypeahead ? this._initializeTypeaheadPiece : this._initializeSelectPiece).call(this, els, part);
  }.bind(this));

  // Create a holder for all the pieces
  var piecesEl = document.createElement('span');
  piecesEl.className = this.isTypeahead ? 'spark-input__fields' : 'spark-select-group';

  // Add all the necessary elements
  this._appendChildren(piecesEl, els);

  // If this is a select group, move the label element.
  if (this.isSelect && (label = this.el.querySelector('.spark-label'))) {
    piecesEl.appendChild(label);
  }

  // Add the pieces holder
  this.el.insertBefore(piecesEl, this.inputEl);

  // Set the value
  if (this.inputEl.value) {
    this.setValue(parsedDomFormat.getValues(this.inputEl.value));
    this.isActive = true;
  }
},

_initializeTypeaheadPiece

method
 _initializeTypeaheadPiece() 

Create a typeahead or placeholder piece.

Option name Type Description
els Array
part Object
_initializeTypeaheadPiece: function(els, part) {

  this.typeaheads = this.typeaheads || {};
  this.typeaheadEls = this.typeaheadEls || [];

  var el;

  switch (part.name) {
    case 'day':
    case 'month':
    case 'year':
      this.typeaheads[part.name] = new DateTypeahead({
        type: part.name,
        length: part.length,
        placeholder: part.value,
        onFocus: this._onTypeaheadFocusBound,
        onBlur: this._onTypeaheadBlurBound,
        onChange: this._onPieceChangeBound,
        onBackspace: this._onTypeaheadBackspaceBound,
        onEnd: this._onTypeaheadEndBound
      });
      el = this.typeaheads[part.name].typeahead.el;
      this.typeaheadEls.push(el);
      break;
    default:
      el = document.createElement('span');
      el.innerHTML = part.value;
      el.className = 'spark-input__divider';
      break;
  }

  els.push(el);
},

_initializeSelectPiece

method
 _initializeSelectPiece() 

Replace the date input with three date dropdowns. Keep the date input around and store the
select data in there.

_initializeSelectPiece: function(els, part) {

  this.selects = this.selects || {};
  this.selectEls = this.selectEls || [];

  if (['day', 'month', 'year'].indexOf(part.name) === -1) {
    return;
  }

  var el;

  this.selects[part.name] = new DateSelect({
    type: part.name,
    onChange: this._onPieceChangeBound
  });
  el = this.selects[part.name].select.el;

  els.push(el);
  this.selectEls.push(el);
},

_convertLabel

method
 _convertLabel() 

If our element is a label, convert it to a div so that
we are semantically correct. Can't have more than one
input inside of a label!

_convertLabel: function() {

  if (this.isTypeahead || this.el.nodeName.toLowerCase() !== 'label') {
    return;
  }

  var newEl = document.createElement('fieldset');

  this._copyAttributes(this.el, newEl);
  this._appendChildren(newEl, this.el.children);

  if (this.el.parentNode) {
    this.el.parentNode.replaceChild(newEl, this.el);
  }

  this.el = newEl;
},

_validateTypeaheads

method
 _validateTypeaheads() 

Validate the typeahead values.

_validateTypeaheads: function() {

  if (!this.typeaheads) {
    return;
  }

  var month = this.typeaheads.month ? this.typeaheads.month.getValue(true) : null;
  var year = this.typeaheads.year ? this.typeaheads.year.getValue(true) : null;

  var maxDay = (month && new Date(year !== null ? year : new Date().getFullYear(), month, 0).getDate()) || this._getMaxDaysInMonth(month);
  var day = this.typeaheads.day ? this.typeaheads.day.getValue(true) : null;

  if (maxDay < day) {
    this.typeaheads.day.setValue(maxDay);
    this.updateInput();
  }
},

_validateTypeaheadBounds

method
 _validateTypeaheadBounds() 

Validate the boundaries of the typeahead values relative to the min and max values.

_validateTypeaheadBounds: function() {

  var year = this.typeaheads.year ? this.typeaheads.year.getValue(true) : null;
  var month = this.typeaheads.month ? this.typeaheads.month.getValue(true) : null;
  var day = this.typeaheads.day ? this.typeaheads.day.getValue(true) : null;

  if (!year || !month || !day) {
    return;
  }

  var date = new Date(year, month - 1, day);
  var set = '';

  if (this.min && date < new Date(this.min.year, this.min.month - 1, this.min.day)) {
    set = 'min';
  }
  else if (this.max && date > new Date(this.max.year, this.max.month - 1, this.max.day)) {
    set = 'max';
  }

  if (set) {
    this.typeaheads.year.setValue(padNumber(this[set].year, this.typeaheads.year.typeahead.format.length));
    this.typeaheads.month.setValue(padNumber(this[set].month, this.typeaheads.month.typeahead.format.length));
    this.typeaheads.day.setValue(padNumber(this[set].day, this.typeaheads.day.typeahead.format.length));
    this.updateInput();
  }
},

_padTypeaheads

method
 _padTypeaheads() 

Pad the typeahead input values.

_padTypeaheads: function() {

  if (this._pauseInputChange) return;

  this._pauseInputChange = true;

  for (var i in this.typeaheads) {
    this._padTypeahead(this.typeaheads[i]);
  }

  this._pauseInputChange = false;
},

_padTypeahead

method
 _padTypeahead() 

Pad the typeahead input values.

Option name Type Description
typeahead Typeahead
_padTypeahead: function(typeahead) {

  var value = typeahead.getValue();

  if (value) {
    var padded = padNumber(value, typeahead.typeahead.format.length);
    if (value !== padded) typeahead.setValue(padNumber(value, typeahead.typeahead.format.length));
  }
},

_hasTypeaheadValue

method
 _hasTypeaheadValue() 

Do any of the typeaheads have a value?

Option name Type Description
return Boolean
_hasTypeaheadValue: function() {

  for (var i in this.typeaheads) {
    if (this.typeaheads[i].getValue(true)) {
      return true;
    }
  }

  return false;
},

_validateSelects

method
 _validateSelects() 

Validate select input values.

_validateSelects: function() {

  if (!this.selects) {
    return;
  }

  var month = this.selects.month ? this.selects.month.getValue(true) : null;
  var year = this.selects.year ? this.selects.year.getValue(true) : null;

  var maxDay = (month && new Date(year !== null ? year : new Date().getFullYear(), month, 0).getDate()) || this._getMaxDaysInMonth(month);
  var day = this.selects.day ? this.selects.day.getValue(true) : null;

  this.selects.day.setOptions({
    max: maxDay
  });
  if (maxDay < day) {
    this.selects.day.setValue(maxDay);
  }

  this.updateInput();
},

_getMaxDaysInMonth

method
 _getMaxDaysInMonth() 

Get the maximum number of days for a given month.

Option name Type Description
month Number

The month's number. 1-12.

return Number

The maximum number of days. 28-31.

_getMaxDaysInMonth: function(month) {
  if (month === 2) return 29;
  else if ([4, 6, 9, 11].indexOf(month) !== -1) return 30;
  return 31;
},

_bindEventListenerCallbacks

method
 _bindEventListenerCallbacks() 

Create bound versions of event listener callbacks and store them.
Otherwise we can't unbind from these events later because the
function signatures won't match.

_bindEventListenerCallbacks: function() {
  this._onClickBound = this._onClick.bind(this);
  this._onTypeaheadFocusBound = this._onTypeaheadFocus.bind(this);
  this._onTypeaheadBlurBound = this._onTypeaheadBlur.bind(this);
  this._onPieceChangeBound = this._onPieceChange.bind(this);
  this._onTypeaheadBackspaceBound = this._onTypeaheadBackspace.bind(this);
  this._onTypeaheadEndBound = this._onTypeaheadEnd.bind(this);
  this._onInputChangeBound = this._onInputChange.bind(this);
  this._onVisibleChildrenBound = this._onVisibleChildren.bind(this);
},

_addEventListeners

method
 _addEventListeners() 

Add event listeners.

_addEventListeners: function() {
  this.el.addEventListener('click', this._onClickBound);
  this.inputEl.addEventListener('change', this._onInputChangeBound);
  document.addEventListener('spark.visible-children', this._onVisibleChildrenBound, true);
},

_removeEventListeners

method
 _removeEventListeners() 

Remove event listeners.

_removeEventListeners: function() {
  this.el.removeEventListener('click', this._onClickBound);
  this.inputEl.removeEventListener('change', this._onInputChangeBound);
  document.removeEventListener('spark.visible-children', this._onVisibleChildrenBound, true);
},

_onVisibleChildren

method
 _onVisibleChildren() 

Handle the spark.visible-children event

Option name Type Description
e Object
_onVisibleChildren: function(e) {
  if (e.target.contains(this.el)) {
    window.setTimeout(function() {
      this.update();
    }.bind(this), 0);
  }
},

update

method
 update() 

Resize the elements, to account for any changed display property

update: function() {
  this._runTypeaheads();
},

_runTypeaheads

method
 _runTypeaheads() 

Run all typeaheads so they have placeholder values.

_runTypeaheads: function() {

  // Make sure we don't get into an infinite loop. Even though the logic
  // in the typeaheads should be stopping this from happening, there is
  // something in Safari where the focus and blur events fire in different
  // order than other browsers so those failsafes do not work.
  if (this.runningTypeaheads) {
    return;
  }

  this.runningTypeaheads = true;

  if (this.inFocus) {
    this.inFocus.pause();
  }

  for (var i in this.typeaheads) {
    if (this.typeaheads[i] !== this.inFocus) {
      this.typeaheads[i].run();
    }
  }

  if (this.inFocus) {
    this.inFocus.resume();
    this.inFocus.run();
  }

  this.runningTypeaheads = false;
},

_updateClass

method
 _updateClass() 

Update the active and focus classes.

_updateClass: function() {
  this._toggleClass(this.el, 'active', this.isActive);
  this._toggleClass(this.el, 'has-partial-value', this.hasPartialValue());
  this._toggleClass(this.el, 'focus', this.inFocus ? true : false);
},

_getTypeaheadByElement

method
 _getTypeaheadByElement() 

Get the typeahead that corresponds to the given element.

Option name Type Description
el Element
return Object
_getTypeaheadByElement: function(el) {
  for (var i in this.typeaheads) {
    if (this.typeaheads[i].typeahead.el === el) {
      return this.typeaheads[i];
    }
  }
},

_showDateText

method
 _showDateText() 

Show the date as text.

_showDateText: function() {

  var text = this._getDateText();

  if (!text || !this.showDateAsText) {
    return;
  }

  if (!this.dateTextEl) {
    this._createDateTextEl();
  }

  this.dateTextEl.innerHTML = text;
  this.dateTextEl.style.display = '';
},

_hideDateText

method
 _hideDateText() 

Hide the date as text.

_hideDateText: function() {

  if (!this.showDateAsText || !this.dateTextEl) {
    return;
  }

  this.dateTextEl.style.display = 'none';
},

_createDateTextEl

method
 _createDateTextEl() 

Create the date text element.

_createDateTextEl: function() {

  var el = document.createElement('div');
  el.className = 'spark-input__overlay';
  el.style.display = 'none';

  this.el.appendChild(el);
  this.dateTextEl = el;
},

_getDateText

method
 _getDateText() 

Get the date as text.

_getDateText: function() {

  var parts = this.parsedTextFormat.parts;
  var i = 0;
  var len = parts.length;
  var str = '';
  var isValid = true;
  var val;

  for(; i < len; i++) {

    val = this.typeaheads[parts[i].name] && this.typeaheads[parts[i].name].getValue();

    switch(parts[i].name) {
      case 'month':
        str += date.getMonthNameShort(val);
        if (!val) {
          isValid = false;
          break;
        }
        break;
      case 'day':
      case 'year':
        str += val;
        if (!val) {
          isValid = false;
          break;
        }
        break;
      default:
        str += parts[i].value;
        break;
    }
  }

  return (isValid ? str : false);
},

_onPieceChange

method
 _onPieceChange() 

When the value of a typeahead or select changes, validate.

Option name Type Description
val Number
typeahead Object
_onPieceChange: function() {

  this.validate();

  if (this.isTypeahead && this.showDateAsText && !this._hasFocus) {

    if (this._showTextTimer) {
      clearTimeout(this._showTextTimer);
    }

    this._showTextTimer = setTimeout(function() {
      this._showDateText();
    }.bind(this), 0);
  }
},

_onTypeaheadFocus

method
 _onTypeaheadFocus() 

When the typeahead gains focus.

Option name Type Description
val Number
typeahead Object
_onTypeaheadFocus: function(val, typeahead) {

  if (this.runningTypeaheads) return;

  this._hideDateText();

  if (!this._hasFocus) {
    this._hasFocus = true;
    (this.onFocus || noop)(this, this.inputEl.value);
  }

  this._triggerEvent(this.inputEl, 'focus');
  this.inFocus = typeahead;
  this.show();
  this._updateClass();

  if (this._blurTimer) {
    clearTimeout(this._blurTimer);
    this._blurTimer = null;
  }
},

_onTypeaheadBlur

method
 _onTypeaheadBlur() 

When the typeahead loses focus, make sure numbers are padded properly.

Option name Type Description
val Number
typeahead Object
_onTypeaheadBlur: function(val, typeahead) {

  if (this.runningTypeaheads) return;

  this.inFocus = null;

  this._padTypeahead(typeahead);
  this.updateInput();
  this._updateClass();

  if (!this.inputEl.value && !this._hasTypeaheadValue()) {
    this.hide();
  }
  else {
    this._validateTypeaheadBounds();
  }

  this._blurTimer = setTimeout(function() {
    this._hasFocus = false;
    (this.onBlur || noop)(this, this.inputEl.value);
    this._showDateText();
  }.bind(this), 1);
},

_onTypeaheadBackspace

method
 _onTypeaheadBackspace() 

When the typeahead fires a backspace event, move back to the previous input.

Option name Type Description
val Number
typeahead Object
_onTypeaheadBackspace: function() {
  this.focusPrevious();
},

_onTypeaheadEnd

method
 _onTypeaheadEnd() 

When the typeahead is at its maximum length and the caret is at the end,
focus on the next input field.

Option name Type Description
typeahead Object
character String

Optional

_onTypeaheadEnd: function(typeahead, character) {
  this.focusNext(character);
},

_onInputChange

method
 _onInputChange() 

When the input that corresponds to this instance changes. Allows us to listen
and respond to changes made by other components (Calendar Popover, for example).

Option name Type Description
e Object
_onInputChange: function(e) {

  if (this.isTypeahead) {
    this.isActive = e.target.value ? true : false;
    this._updateClass();
  }

  if (this._pauseInputChange) return;
  this.setValue(parsedDomFormat.getValues(e.target.value));
  (this.onChange || noop)(this.inputEl.value, this.inputEl);
},

_onClick

method
 _onClick() 

When the input group is clicked, focus on the first typeahead
if we don't already have focus.

Option name Type Description
e Object
_onClick: function(

e

{

if (this.isTypeahead || this.inFocus || this.isActive || this._getElementMatchingParent(e.target, '.spark-input__addon')) {
return;
}

  var input = this.typeaheadEls[0].querySelector('input');

  if (input) {
    input.focus();
  }
}
  };

  Base.exportjQuery(DateInput, 'DateInput');

  return DateInput;
}));