Skip to content

Instantly share code, notes, and snippets.

@kevindb
Last active August 29, 2015 14:06
Show Gist options
  • Save kevindb/734af2be6c5ad9d72f89 to your computer and use it in GitHub Desktop.
Save kevindb/734af2be6c5ad9d72f89 to your computer and use it in GitHub Desktop.
jquery.ajaxSelect.js
(function( $ ) {
// Plugin definition
$.fn.ajaxSelect = function(settings) {
// Extend this object from Deferred, allowing for promises
var defer = $.extend(this, $.Deferred());
// Extend our default options with those provided.
// Note that the first argument to extend is an empty
// object – this is to keep from overriding our "defaults" object
var settings = $.extend(true, {}, $.fn.ajaxSelect.defaults, settings);
// Our plugin implementation code goes here.
// Iterate each matched element.
this.each(function() {
if(fnIsElementSelect(this)){
var element = $(this);
var thisSettings = fnGetSettingsFromAttributes(element, settings);
if(thisSettings.data != null){
fnReplaceOptions(element, thisSettings);
} else {
fnReplaceOptionsFromAjax(element, thisSettings);
}
}
});
$.when.apply($, deferredList).done(function() {
defer.resolve();
});
return defer;
}
// Plugin defaults – added as a property on our plugin function
$.fn.ajaxSelect.defaults = {
optionElem: $('<option></option>'),
params: {},
prependBlankOption: false
};
// Private functions
var deferredList = [];
var fnGetSettingsFromAttributes = function(selectElem, settings) {
var attributeSettings = ['url','method'];
var thisSettings = $.extend(true, {}, settings);
$.each(attributeSettings, function(i, e){
if(thisSettings[e] == null){
thisSettings[e] = selectElem.data(e);
}
});
return thisSettings;
};
var fnMethodIntoParam = function(settings) {
// Collect method and paramaters into one object
if(settings.method != null){
if(settings.params.method == null){
settings.params.method = settings.method;
}
}
return settings;
};
var fnRequiredParamsExist = function(settings) {
return (settings.url != null && settings.params.method != null);
};
var fnIsElementSelect = function(element) {
var response = false;
var type = element.tagName || element.type;
if (type != null){
type = type.toLowerCase();
if (type == 'select' || type == 'select-one' || type == 'select-multiple'){
response = true;
}
}
return response;
};
var fnAddOptions = function(selectElem, settings){
if(settings.prependBlankOption){
selectElem.append(settings.optionElem.clone());
}
$.each(settings.data, function(i, obj){
var optionElem = settings.optionElem.clone();
optionElem.val(obj.id);
optionElem.text(obj.name);
selectElem.append(optionElem);
});
};
var fnReplaceOptions = function(selectElem, settings){
$('option', selectElem).remove();
fnAddOptions(selectElem, settings);
};
var fnReplaceOptionsFromAjax = function(selectElem, settings){
settings = fnMethodIntoParam(settings);
if(fnRequiredParamsExist(settings)){
// Make AJAX call
deferredList.push($.ajax({
url: settings.url,
dataType: 'json',
data: settings.params,
success: function(data, textStatus, jqXHR){
settings.data = data.data;
fnReplaceOptions(selectElem, settings);
},
beforeSend: function(jqXHR, textStatus, errorThrown){
$body.addClass('loading');
},
complete: function(jqXHR, textStatus, errorThrown){
$body.removeClass('loading');
}
}));
}
};
}( jQuery ));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment