Option name | Type | Description |
---|---|---|
el | Element | Optional |
params | Object | Optional |
DateTypeahead constructor
function DateTypeahead(el, params) {
// If only one arg passed, assume it was a parameters
// object since the user MUST provide those but the element
// is optional. Doing it this way to keep the arity the same
// as other components.
if (arguments.length < 2) {
params = el || {};
el = this._createDefaultElement();
}
this._setParams(this.defaults, true);
this._setParams(params);
this._bindEventListenerCallbacks();
this._createTypeahead(el, params);
}
DateTypeahead.prototype = {
Include common functionality.
_setParams: Base.setParams,
remove: Base.remove,
Whitelisted parameters which can be set on construction.
_whitelistedParams: ['type', 'onChange', 'onFocus', 'onBlur', 'onBackspace', 'onEnd'],
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.
defaults: {
type: null,
typeahead: null,
onChange: null,
onFocus: null,
onBlur: null,
onBackspace: null,
onEnd: null,
_onTypeaheadChangeBound: null,
_onTypeaheadFocusBound: null,
_onTypeaheadBlurBound: null,
_onTypeaheadBackspaceBound: null,
_onTypeaheadEndBound: null
},
Option name | Type | Description |
---|---|---|
asInt | Boolean | Get the value as a parsed integer. |
return | Mixed |
Get the value.
getValue: function(asInt) {
return this.typeahead.getValue(asInt);
},
Option name | Type | Description |
---|---|---|
val | Mixed |
Set the value.
setValue: function(val) {
return this.typeahead.setValue(val);
},
Run the typeahead calculations.
run: function() {
return this.typeahead.run();
},
Pause the typeahead events.
pause: function() {
return this.typeahead.pause();
},
Reseume typeahead events.
resume: function() {
return this.typeahead.resume();
},
Create the default input element.
_createDefaultElement: function() {
var el = document.createElement('span');
el.className = 'spark-input';
return el;
},
Option name | Type | Description |
---|---|---|
el | Object | |
params | Object |
Create a typeahead with the given format.
_createTypeahead: function(el, params) {
params = params || {};
if (!params.placeholder) {
throw new Error('You must provide a placeholder value for a DateTypeahead.');
}
if (params.length !== undefined) {
params.format = this._lengthToFormat(params.length);
}
if (!params.format) {
throw new Error('You must provide a format value for a DateTypeahead.');
}
this.typeahead = new Typeahead(el, {
placeholder: params.placeholder,
format: params.format,
matchPlaceholderSize: true,
onChange: this._onTypeaheadChangeBound,
onFocus: this._onTypeaheadFocusBound,
onBlur: this._onTypeaheadBlurBound,
onBackspace: this._onTypeaheadBackspaceBound,
onEnd: this._onTypeaheadEndBound
});
// Ensure we have an ARIA label
var input = el.querySelector('input');
if (input && !input.getAttribute('aria-label')) {
input.setAttribute('aria-label', this.type);
}
},
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._onTypeaheadChangeBound = this._onTypeaheadChange.bind(this);
this._onTypeaheadFocusBound = this._onTypeaheadFocus.bind(this);
this._onTypeaheadBlurBound = this._onTypeaheadBlur.bind(this);
this._onTypeaheadBackspaceBound = this._onTypeaheadBackspace.bind(this);
this._onTypeaheadEndBound = this._onTypeaheadEnd.bind(this);
},
Option name | Type | Description |
---|---|---|
length | Number | |
return | String |
Take a length and return a format string with that many digits.
_lengthToFormat: function(length) {
var i = 0;
var ret = '';
for (; i < length; i++) {
ret += '\\d';
}
return ret;
},
Option name | Type | Description |
---|---|---|
val | Mixed | |
allowEmpty | Boolean | All the value to be empty instead of 0. |
Check to see if an input value is valid.
_checkValidity: function(val, allowEmpty) {
val = parseInt(val, 10);
var origVal = val;
var isNumber = !isNaN(val);
// If we were passed an empty string or something, don't try to validate.
// Treat zeros as a non-entry for days and months.
if (isNumber) {
if (this.type === 'day') {
val = val ? Math.min(Math.max(val, 1), 31) : (allowEmpty ? '' : 0);
} else if (this.type === 'month') {
val = val ? Math.min(Math.max(val, 1), 12) : (allowEmpty ? '' : 0);
} else {
val = val === 0 ? (allowEmpty ? '' : 0) : Math.max(val, 0);
}
}
// Need to make sure we aren't looping forever on these updates.
if (isNumber && val !== origVal) {
this.typeahead.setValue(val + '');
return false;
}
return true;
},
Option name | Type | Description |
---|---|---|
val | String | The value of the input |
oldVal | String | The previous value |
When the typeahead changes, make sure the value is valid. This
is very basic validation. More complex validation like the number
of days in a specific month should be handled by the callback.
And run our callback.
_onTypeaheadChange: function(val) {
if (this._checkValidity(val)) {
(this.onChange || noop)(val, this);
}
},
Option name | Type | Description |
---|---|---|
val | String |
When the typeahead gains focus, let anyone who is interested know.
_onTypeaheadFocus: function(val) {
(this.onFocus || noop)(val, this);
},
Option name | Type | Description |
---|---|---|
val | String |
When the typeahead loses focus, let anyone who is interested know.
_onTypeaheadBlur: function(val) {
this._checkValidity(val, true);
(this.onBlur || noop)(val, this);
},
Option name | Type | Description |
---|---|---|
val | String |
When the typeahead fires a backspace event because it's empty and
the user is hitting backspace, let anyone who is interested know.
_onTypeaheadBackspace: function(val) {
(this.onBackspace || noop)(val, this);
},
Option name | Type | Description |
---|---|---|
typeahead | Object | |
character | String | Optional The character to pass to the next input. |
When the typeahead is full and at its end, let anyone who is interested know.
_onTypeaheadEnd: function(typeahead, character) {
(this.onEnd || noop)(this, character);
}
};
Base.exportjQuery(DateTypeahead, 'DateTypeahead');
return DateTypeahead;
}));