Skip to content

Commit

Permalink
Merge pull request gbicou#1 from Jobvite/master
Browse files Browse the repository at this point in the history
Merged a fix from a timing bug and added an 'initialQuery' feature
  • Loading branch information
bicouy0 committed Feb 15, 2012
2 parents 80152fd + 1d0746f commit eb00693
Show file tree
Hide file tree
Showing 4 changed files with 306 additions and 299 deletions.
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,34 @@ ajaxChosen specific parameters are:
- minLength: this is the number of characters that need to be typed before search occurs. Default is 3.
- queryLimit: this is the max number of items that your server will ever return, and it is used for client side caching. Default is 10.
- delay: time to wait between key strokes
- chosenOptions: passed to vanilla chosen
- searchingText: "Searching..."
- noresultsText: "No results."
- initialQuery: boolean of wether or not to fire a query when the chosen is first focused


The second argument is a callback that the plugin uses to get option elements. The callback is expected to make ajax call, it receives as first argument the options of plugin and must call its second argument to pass the values back to the plugin, e.g. if it were a list of states it would be
The second argument is a callback that the plugin uses to get option elements. The callback is passed the set options, the response callback, and the event that triggered the callback (focus or keyup). The callback is expected to make ajax call, it receives as first argument the options of plugin and must call its second argument to pass the values back to the plugin, e.g. if it were a list of states it would be

states[state.id] = state.name;

which would become

<option value="state.id">state.name</option>

You can use the event parameter to differentiate between initialQuery and subsequent queries to change behavior accordingly

## Example Code

``` js
$("#example-input").ajaxChosen({
minLength: 2,
delay: 300
}, function (options, response) {
minLength: 3,
queryLimit: 10,
delay: 100,
chosenOptions: {},
searchingText: "Searching...",
noresultsText: "No results.",
initialQuery: false
}, function (options, response, event) {
$.getJSON("/ajax-chosen/data.php", {q: options.term}, function (data) {

var terms = {};
Expand All @@ -44,6 +54,4 @@ $("#example-input").ajaxChosen({
response(terms);
});
});
```

Note that this will hit the url: /ajax-chosen/data.php?q=WHATEVS (assuming you're searching for whatevs...)
```
254 changes: 129 additions & 125 deletions lib/ajax-chosen.js
Original file line number Diff line number Diff line change
@@ -1,139 +1,143 @@

/*
ajax-chosen
A complement to the jQuery library Chosen that adds ajax autocomplete
Contributors:
https://github.com/jobvite/ajax-chosen
https://github.com/bicouy0/ajax-chosen
*/

(function() {

(function($) {
return $.fn.ajaxChosen = function(options, callback) {
var defaultedOptions, inputSelector, multiple, select;
defaultedOptions = {
minLength: 3,
queryLimit: 10,
delay: 100,
chosenOptions: {},
searchingText: "Searching...",
noresultsText: "No results."
(function($) {
return $.fn.ajaxChosen = function(options, callback) {
var clickSelector, container, defaultedOptions, field, inputSelector, multiple, search, select,
_this = this;
defaultedOptions = {
minLength: 3,
delay: 100,
chosenOptions: {},
searchingText: "Searching...",
noresultsText: "No results.",
initialQuery: false
};
$.extend(defaultedOptions, options);
defaultedOptions.chosenOptions.no_results_text = defaultedOptions.searchingText;
select = this;
multiple = select.attr('multiple') != null;
if (multiple) {
inputSelector = ".search-field > input";
clickSelector = ".chzn-choices";
} else {
inputSelector = ".chzn-search > input";
clickSelector = ".chzn-single";
}
select.chosen(defaultedOptions.chosenOptions);
container = select.next('.chzn-container');
field = container.find(inputSelector);
if (defaultedOptions.initialQuery) {
field.bind('focus', function(evt) {
if (this.previousSearch || !container.hasClass('chzn-container-active')) {
return;
}
return search(evt);
});
}
field.bind('keyup', function(evt) {
if (this.previousSearch) clearTimeout(this.previousSearch);
return this.previousSearch = setTimeout((function() {
return search(evt);
}), defaultedOptions.delay);
});
return search = function(evt) {
var clearSearchingLabel, currentOptions, prevVal, response, val, _ref;
val = $.trim(field.attr('value'));
prevVal = (_ref = field.data('prevVal')) != null ? _ref : false;
field.data('prevVal', val);
clearSearchingLabel = function() {
var resultsDiv;
if (multiple) {
resultsDiv = field.parent().parent().siblings();
} else {
resultsDiv = field.parent().parent();
}
return resultsDiv.find('.no-results').html(defaultedOptions.noresultsText + " '" + $(_this).attr('value') + "'");
};
$.extend(defaultedOptions, options);
defaultedOptions.chosenOptions.no_results_text = defaultedOptions.searchingText;
select = this;
multiple = select.attr('multiple') != null;
if (multiple) {
inputSelector = ".search-field > input";
} else {
inputSelector = ".chzn-search > input";
if (val === prevVal || (val.length < defaultedOptions.minLength && evt.type === 'keyup')) {
clearSearchingLabel();
return false;
}
select.chosen(defaultedOptions.chosenOptions);
return select.next('.chzn-container').find(inputSelector).bind('keyup', function(e) {
var search,
_this = this;
if (this.previousSearch) clearTimeout(this.previousSearch);
search = function() {
var clearSearchingLabel, currentOptions, field, prevVal, response, val, _ref;
field = $(_this);
val = $.trim(field.attr('value'));
prevVal = (_ref = field.data('prevVal')) != null ? _ref : '';
field.data('prevVal', val);
clearSearchingLabel = function() {
var resultsDiv;
if (multiple) {
resultsDiv = field.parent().parent().siblings();
} else {
resultsDiv = field.parent().parent();
}
return resultsDiv.find('.no-results').html(defaultedOptions.noresultsText + " '" + $(_this).attr('value') + "'");
};
if (val.length < defaultedOptions.minLength || val === prevVal) {
clearSearchingLabel();
return false;
currentOptions = select.find('option');
defaultedOptions.term = val;
response = function(items, success) {
var currentOpt, keydownEvent, latestVal, newOpt, newOptions, noResult, _fn, _fn2, _i, _j, _len, _len2;
if (!field.is(':focus') && evt.type === 'keyup') return;
newOptions = [];
$.each(items, function(value, text) {
var newOpt;
newOpt = $('<option>');
newOpt.attr('value', value).html(text);
return newOptions.push($(newOpt));
});
_fn = function(currentOpt) {
var $currentOpt, newOption, presenceInNewOptions;
$currentOpt = $(currentOpt);
if ($currentOpt.attr('selected') && multiple) return;
if ($currentOpt.attr('value') === '' && $currentOpt.html() === '' && !multiple) {
return;
}
currentOptions = select.find('option');
if (currentOptions.length < defaultedOptions.queryLimit && val.indexOf(prevVal) === 0 && prevVal !== '') {
clearSearchingLabel();
return false;
}
defaultedOptions.term = val;
response = function(items, success) {
var currentOpt, keydownEvent, latestVal, newOpt, newOptions, noResult, _fn, _fn2, _i, _j, _len, _len2;
if (!field.is(':focus')) return;
newOptions = [];
$.each(items, function(value, text) {
var newOpt;
newOpt = $('<option>');
newOpt.attr('value', value).html(text);
return newOptions.push($(newOpt));
});
_fn = function(currentOpt) {
var $currentOpt, newOption, presenceInNewOptions;
$currentOpt = $(currentOpt);
if ($currentOpt.attr('selected') && multiple) return;
if ($currentOpt.attr('value') === '' && $currentOpt.html() === '' && !multiple) {
return;
}
presenceInNewOptions = (function() {
var _j, _len2, _results;
_results = [];
for (_j = 0, _len2 = newOptions.length; _j < _len2; _j++) {
newOption = newOptions[_j];
if (newOption.attr('value') === $currentOpt.attr('value')) {
_results.push(newOption);
}
}
return _results;
})();
if (presenceInNewOptions.length === 0) return $currentOpt.remove();
};
for (_i = 0, _len = currentOptions.length; _i < _len; _i++) {
currentOpt = currentOptions[_i];
_fn(currentOpt);
}
currentOptions = select.find('option');
_fn2 = function(newOpt) {
var currentOption, presenceInCurrentOptions, _fn3, _k, _len3;
presenceInCurrentOptions = false;
_fn3 = function(currentOption) {
if ($(currentOption).attr('value') === newOpt.attr('value')) {
return presenceInCurrentOptions = true;
}
};
for (_k = 0, _len3 = currentOptions.length; _k < _len3; _k++) {
currentOption = currentOptions[_k];
_fn3(currentOption);
}
if (!presenceInCurrentOptions) return select.append(newOpt);
};
presenceInNewOptions = (function() {
var _j, _len2, _results;
_results = [];
for (_j = 0, _len2 = newOptions.length; _j < _len2; _j++) {
newOpt = newOptions[_j];
_fn2(newOpt);
}
latestVal = field.val();
if ($.isEmptyObject(items)) {
noResult = $('<option>');
noResult.addClass('no-results');
noResult.html(defaultedOptions.noresultsText + " '" + latestVal + "'").attr('value', '');
select.append(noResult);
} else {
select.change();
newOption = newOptions[_j];
if (newOption.attr('value') === $currentOpt.attr('value')) {
_results.push(newOption);
}
}
select.trigger("liszt:updated");
$('.no-results').removeClass('active-result');
field.val(latestVal);
if (!$.isEmptyObject(items)) {
keydownEvent = $.Event('keydown');
keydownEvent.which = 40;
field.trigger(keydownEvent);
return _results;
})();
if (presenceInNewOptions.length === 0) return $currentOpt.remove();
};
for (_i = 0, _len = currentOptions.length; _i < _len; _i++) {
currentOpt = currentOptions[_i];
_fn(currentOpt);
}
currentOptions = select.find('option');
_fn2 = function(newOpt) {
var currentOption, presenceInCurrentOptions, _fn3, _k, _len3;
presenceInCurrentOptions = false;
_fn3 = function(currentOption) {
if ($(currentOption).attr('value') === newOpt.attr('value')) {
return presenceInCurrentOptions = true;
}
if (success) return success(items);
};
return callback(defaultedOptions, response);
for (_k = 0, _len3 = currentOptions.length; _k < _len3; _k++) {
currentOption = currentOptions[_k];
_fn3(currentOption);
}
if (!presenceInCurrentOptions) return select.append(newOpt);
};
return this.previousSearch = setTimeout(search, defaultedOptions.delay);
});
for (_j = 0, _len2 = newOptions.length; _j < _len2; _j++) {
newOpt = newOptions[_j];
_fn2(newOpt);
}
latestVal = field.val();
if ($.isEmptyObject(items)) {
noResult = $('<option>');
noResult.addClass('no-results');
noResult.html(defaultedOptions.noresultsText + " '" + latestVal + "'").attr('value', '');
select.append(noResult);
} else {
select.change();
}
select.trigger("liszt:updated");
$('.no-results').removeClass('active-result');
field.val(latestVal);
if (!$.isEmptyObject(items)) {
keydownEvent = $.Event('keydown');
keydownEvent.which = 40;
field.trigger(keydownEvent);
}
if (success) return success(items);
};
return callback(defaultedOptions, response, evt);
};
})(jQuery);

}).call(this);
};
})(jQuery);
4 changes: 0 additions & 4 deletions lib/ajax-chosen.min.js

This file was deleted.

Loading

0 comments on commit eb00693

Please sign in to comment.