Changeset View
Changeset View
Standalone View
Standalone View
webroot/rsrc/js/application/herald/PathTypeahead.js
/** | /** | ||||
* @requires javelin-install | * @requires javelin-install | ||||
* javelin-typeahead | * javelin-typeahead | ||||
* javelin-dom | * javelin-dom | ||||
* javelin-request | * javelin-request | ||||
* javelin-typeahead-ondemand-source | * javelin-typeahead-ondemand-source | ||||
* javelin-util | * javelin-util | ||||
* @provides path-typeahead | * @provides path-typeahead | ||||
* @javelin | * @javelin | ||||
*/ | */ | ||||
JX.install('PathTypeahead', { | JX.install('PathTypeahead', { | ||||
construct : function(config) { | construct : function(config) { | ||||
this._repositorySelect = config.repo_select; | this._repositoryTokenizer = config.repositoryTokenizer; | ||||
this._hardpoint = config.hardpoint; | this._hardpoint = config.hardpoint; | ||||
this._input = config.path_input; | this._input = config.path_input; | ||||
this._completeURI = config.completeURI; | this._completeURI = config.completeURI; | ||||
this._validateURI = config.validateURI; | this._validateURI = config.validateURI; | ||||
this._errorDisplay = config.error_display; | this._errorDisplay = config.error_display; | ||||
this._textInputValues = {}; | this._textInputValues = {}; | ||||
this._icons = config.icons; | |||||
this._initializeDatasource(); | this._initializeDatasource(); | ||||
this._initializeTypeahead(this._input); | this._initializeTypeahead(this._input); | ||||
}, | }, | ||||
members : { | members : { | ||||
/* | _repositoryTokenizer : null, | ||||
* DOM <select> elem for choosing the repository of a path. | |||||
*/ | |||||
_repositorySelect : null, | |||||
/* | /* | ||||
* DOM parent div "hardpoint" to be passed to the JX.Typeahead. | * DOM parent div "hardpoint" to be passed to the JX.Typeahead. | ||||
*/ | */ | ||||
_hardpoint : null, | _hardpoint : null, | ||||
/* | /* | ||||
* DOM element to display errors. | * DOM element to display errors. | ||||
*/ | */ | ||||
_errorDisplay : null, | _errorDisplay : null, | ||||
Show All 36 Lines | members : { | ||||
_validationInflight : null, | _validationInflight : null, | ||||
/* | /* | ||||
* Installs path-specific behaviors and then starts the underlying | * Installs path-specific behaviors and then starts the underlying | ||||
* typeahead. | * typeahead. | ||||
*/ | */ | ||||
start : function() { | start : function() { | ||||
if (this._typeahead.getValue()) { | if (this._typeahead.getValue()) { | ||||
this._textInputValues[this._repositorySelect.value] = | var phid = this._getRepositoryPHID(); | ||||
this._typeahead.getValue(); | if (phid) { | ||||
this._textInputValues[phid] = this._typeahead.getValue(); | |||||
} | |||||
} | } | ||||
this._typeahead.listen( | this._typeahead.listen( | ||||
'change', | 'change', | ||||
JX.bind(this, function(value) { | JX.bind(this, function(value) { | ||||
this._textInputValues[this._repositorySelect.value] = value; | var phid = this._getRepositoryPHID(); | ||||
this._validate(); | if (phid) { | ||||
})); | this._textInputValues[phid] = value; | ||||
} | |||||
this._typeahead.listen( | this._validate(); | ||||
'choose', | |||||
JX.bind(this, function() { | |||||
setTimeout(JX.bind(this._typeahead, this._typeahead.refresh), 0); | |||||
})); | })); | ||||
var repo_set_input = JX.bind(this, this._onrepochange); | var repo_set_input = JX.bind(this, this._onrepochange); | ||||
this._typeahead.listen('start', repo_set_input); | this._typeahead.listen('start', repo_set_input); | ||||
JX.DOM.listen( | |||||
this._repositorySelect, | this._repositoryTokenizer.listen('change', repo_set_input); | ||||
'change', | |||||
null, | |||||
repo_set_input); | |||||
this._typeahead.start(); | this._typeahead.start(); | ||||
this._validate(); | this._validate(); | ||||
}, | }, | ||||
_onrepochange : function() { | _onrepochange : function() { | ||||
this._setPathInputBasedOnRepository( | this._setPathInputBasedOnRepository( | ||||
this._typeahead, | this._typeahead, | ||||
this._textInputValues); | this._textInputValues); | ||||
this._datasource.setAuxiliaryData( | this._datasource.setAuxiliaryData( | ||||
{repositoryPHID : this._repositorySelect.value} | { | ||||
); | repositoryPHID: this._getRepositoryPHID() | ||||
}); | |||||
// Since we've changed the repository, reset the results. | |||||
this._datasource.resetResults(); | |||||
}, | }, | ||||
_setPathInputBasedOnRepository : function(typeahead, lookup) { | _setPathInputBasedOnRepository : function(typeahead, lookup) { | ||||
if (lookup[this._repositorySelect.value]) { | var phid = this._getRepositoryPHID(); | ||||
typeahead.setValue(lookup[this._repositorySelect.value]); | if (phid && lookup[phid]) { | ||||
typeahead.setValue(lookup[phid]); | |||||
} else { | } else { | ||||
typeahead.setValue('/'); | typeahead.setValue('/'); | ||||
} | } | ||||
}, | }, | ||||
_initializeDatasource : function() { | _initializeDatasource : function() { | ||||
this._datasource = new JX.TypeaheadOnDemandSource(this._completeURI); | this._datasource = new JX.TypeaheadOnDemandSource(this._completeURI); | ||||
this._datasource.setNormalizer(this._datasourceNormalizer); | this._datasource.setNormalizer(this._datasourceNormalizer); | ||||
Show All 9 Lines | _initializeTypeahead : function(path_input) { | ||||
this._datasource.setMaximumResultCount(15); | this._datasource.setMaximumResultCount(15); | ||||
this._typeahead.setDatasource(this._datasource); | this._typeahead.setDatasource(this._datasource); | ||||
}, | }, | ||||
_datasourceNormalizer : function(str) { | _datasourceNormalizer : function(str) { | ||||
return ('' + str).replace(/[\/]+/g, '\/'); | return ('' + str).replace(/[\/]+/g, '\/'); | ||||
}, | }, | ||||
_getRepositoryPHID: function() { | |||||
var tokens = this._repositoryTokenizer.getTokens(); | |||||
var keys = JX.keys(tokens); | |||||
if (keys.length) { | |||||
return keys[0]; | |||||
} | |||||
return null; | |||||
}, | |||||
_validate : function() { | _validate : function() { | ||||
var repo_phid = this._getRepositoryPHID(); | |||||
if (!repo_phid) { | |||||
return; | |||||
} | |||||
var input = this._input; | var input = this._input; | ||||
var repo_id = this._repositorySelect.value; | |||||
var input_value = input.value; | var input_value = input.value; | ||||
var error_display = this._errorDisplay; | var error_display = this._errorDisplay; | ||||
if (!input_value.length) { | if (!input_value.length) { | ||||
input.value = '/'; | input.value = '/'; | ||||
input_value = '/'; | input_value = '/'; | ||||
} | } | ||||
if (this._validationInflight) { | if (this._validationInflight) { | ||||
this._validationInflight.abort(); | this._validationInflight.abort(); | ||||
this._validationInflight = null; | this._validationInflight = null; | ||||
} | } | ||||
var validation_request = new JX.Request( | var validation_request = new JX.Request( | ||||
this._validateURI, | this._validateURI, | ||||
function(payload) { | JX.bind(this, function(payload) { | ||||
// Don't change validation display state if the input has been | // Don't change validation display state if the input has been | ||||
// changed since we started validation | // changed since we started validation | ||||
if (input.value === input_value) { | if (input.value !== input_value) { | ||||
return; | |||||
} | |||||
if (payload.valid) { | if (payload.valid) { | ||||
JX.DOM.alterClass(error_display, 'invalid', false); | JX.DOM.setContent(error_display, JX.$H(this._icons.okay)); | ||||
JX.DOM.alterClass(error_display, 'valid', true); | |||||
} else { | } else { | ||||
JX.DOM.alterClass(error_display, 'invalid', true); | JX.DOM.setContent(error_display, JX.$H(this._icons.fail)); | ||||
JX.DOM.alterClass(error_display, 'valid', false); | |||||
} | } | ||||
JX.DOM.setContent(error_display, payload.message); | })); | ||||
} | |||||
}); | |||||
validation_request.listen('finally', function() { | validation_request.listen('finally', function() { | ||||
JX.DOM.alterClass(error_display, 'validating', false); | |||||
this._validationInflight = null; | this._validationInflight = null; | ||||
}); | }); | ||||
validation_request.setData( | validation_request.setData( | ||||
{ | { | ||||
repositoryPHID : repo_id, | repositoryPHID : repo_phid, | ||||
path : input_value | path : input_value | ||||
}); | }); | ||||
this._validationInflight = validation_request; | this._validationInflight = validation_request; | ||||
JX.DOM.setContent(error_display, JX.$H(this._icons.test)); | |||||
validation_request.setTimeout(750); | validation_request.setTimeout(750); | ||||
validation_request.send(); | validation_request.send(); | ||||
} | } | ||||
} | } | ||||
}); | }); |