Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added Prototype version #6

Open
wants to merge 3 commits into from

4 participants

@ndbroadbent

Support the Prototype javascript framework.

Please also be aware that we have released an ajax-chosen-rails gem for use with Rails 3.1 applications.
This gem has been released with the prototype version included.

@meltingice
Owner

I'm a bit confused by this. Where is the Chosen class that is being extended by ajaxChosen? Is that a part of the ajax-chosen-rails gem?

@ndbroadbent

Hi,

The Chosen class is just the original chosen javascript library. In the prototype version of chosen, you call

new Chosen(element);

So the prototype version of ajaxChosen wraps the Chosen object, but binds to the 'keyup' event on the input after chosen is initialized. You call it like this:

new ajaxChosen(element);

I'll update the README with this info too, sorry, I should have added that to the pull request

@ndbroadbent ndbroadbent commented on the diff
src/ajax-chosen.proto.coffee
((25 lines not shown))
+ # Some simple validation so we don't make excess ajax calls. I am
+ # assuming you don't want to perform a search with less than 3
+ # characters.
+
+ return false if val.length < 3 or val is $(this).readAttribute('data-prevVal')
+
+ # Set the current search term so we don't execute the ajax call if
+ # the user hits a key that isn't an input letter/number/symbol
+ $(this).writeAttribute('data-prevVal', val)
+
+ # This is a useful reference for later
+ field = $(this)
+
+ # I'm assuming that it's ok to use the parameter name `term` to send
+ # the form value during the ajax call. Change if absolutely needed.
+ query_key = options.query_key || "term"

We did need to change the parameter name, so we made this configurable via a query_key option.

Do you think this ok? If so, I'll add it to the jQuery version and also fix the comment above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@manuelmeurer

@meltingice What is the status of this PR? Can this be merged? Seems like a great addition.

@evilguc

Too many bugs to use

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
0  lib/ajax-chosen.js → lib/ajax-chosen.jquery.js
File renamed without changes
View
67 lib/ajax-chosen.proto.js
@@ -0,0 +1,67 @@
+(function() {
+ var ajaxChosen, root;
+ var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
+ function ctor() { this.constructor = child; }
+ ctor.prototype = parent.prototype;
+ child.prototype = new ctor;
+ child.__super__ = parent.prototype;
+ return child;
+ };
+ root = this;
+ ajaxChosen = (function() {
+ __extends(ajaxChosen, Chosen);
+ ajaxChosen.prototype.activate_field = function() {
+ if (this.options.show_on_activate && !this.active_field) {
+ this.results_show();
+ }
+ return ajaxChosen.__super__.activate_field.apply(this, arguments);
+ };
+ function ajaxChosen(select, options, callback) {
+ this.options = options;
+ ajaxChosen.__super__.constructor.call(this, select, options);
+ select.next('.chzn-container').down('.chzn-search > input').observe('keyup', function() {
+ var field, query_key, success, val;
+ val = $(this).value.strip();
+ if (val.length < 3 || val === $(this).readAttribute('data-prevVal')) {
+ return false;
+ }
+ $(this).writeAttribute('data-prevVal', val);
+ field = $(this);
+ query_key = options.query_key || "term";
+ (options.parameters || (options.parameters = {}))[query_key] = val;
+ success = options.success;
+ options.onSuccess = function(data) {
+ var items;
+ if (!(data != null)) {
+ return;
+ }
+ select.childElements().each(function(el) {
+ if (!el.selected) {
+ return el.remove();
+ }
+ });
+ items = callback ? callback(data.responseJSON) : data.responseJSON;
+ $H(items).each(function(pair) {
+ if (select.value !== pair.key) {
+ return select.insert({
+ bottom: new Element("option", {
+ value: pair.key
+ }).update(pair.value)
+ });
+ }
+ });
+ val = field.value;
+ select.fire("liszt:updated");
+ field.value = val;
+ if (success != null) {
+ return success();
+ }
+ };
+ return new Ajax.Request(options.url, options);
+ });
+ }
+ return ajaxChosen;
+ })();
+ root.ajaxChosen = ajaxChosen;
+}).call(this);
View
0  src/ajax-chosen.coffee → src/ajax-chosen.jquery.coffee
File renamed without changes
View
88 src/ajax-chosen.proto.coffee
@@ -0,0 +1,88 @@
+root = this
+
+class ajaxChosen extends Chosen
+ activate_field: ->
+ if @options.show_on_activate and not @active_field
+ this.results_show()
+ super
+
+ constructor: (select, @options, callback) ->
+ # Load chosen. To make things clear, I have taken the liberty
+ # of using the .chzn-autoselect class to specify input elements
+ # we want to use with ajax autocomplete.
+ super select, options
+
+ # Now that chosen is loaded normally, we can bootstrap it with
+ # our ajax autocomplete code.
+ select.next('.chzn-container')
+ .down('.chzn-search > input')
+ .observe 'keyup', ->
+ # This code will be executed every time the user types a letter
+ # into the input form that chosen has created
+
+ # Retrieve the current value of the input form
+ val = $(this).value.strip()
+ # Some simple validation so we don't make excess ajax calls. I am
+ # assuming you don't want to perform a search with less than 3
+ # characters.
+
+ return false if val.length < 3 or val is $(this).readAttribute('data-prevVal')
+
+ # Set the current search term so we don't execute the ajax call if
+ # the user hits a key that isn't an input letter/number/symbol
+ $(this).writeAttribute('data-prevVal', val)
+
+ # This is a useful reference for later
+ field = $(this)
+
+ # I'm assuming that it's ok to use the parameter name `term` to send
+ # the form value during the ajax call. Change if absolutely needed.
+ query_key = options.query_key || "term"

We did need to change the parameter name, so we made this configurable via a query_key option.

Do you think this ok? If so, I'll add it to the jQuery version and also fix the comment above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ (options.parameters ||= {})[query_key] = val
+
+ # If the user provided an ajax success callback, store it so we can
+ # call it after our bootstrapping is finished.
+ success = options.success
+
+ # Create our own callback that will be executed when the ajax call is
+ # finished.
+ options.onSuccess = (data) ->
+ # Exit if the data we're given is invalid
+ return if not data?
+
+ # Go through all of the <option> elements in the <select> and remove
+ # ones that have not been selected by the user.
+ select.childElements().each (el) -> el.remove() if not el.selected
+
+ # Send the ajax results to the user callback so we can get an object of
+ # value => text pairs to inject as <option> elements.
+ items = if callback then callback(data.responseJSON) else data.responseJSON
+
+ # Iterate through the given data and inject the <option> elements into
+ # the DOM
+ $H(items).each (pair) ->
+ if select.value != pair.key
+ select.insert
+ bottom:
+ new Element("option", {value: pair.key})
+ .update(pair.value)
+
+ val = field.value
+
+ # Tell chosen that the contents of the <select> input have been updated
+ # This makes chosen update its internal list of the input data.
+ select.fire("liszt:updated")
+
+ # For some reason, the contents of the input field get removed once you
+ # call trigger above. Often, this can be very annoying (and can make some
+ # searches impossible), so we add the value the user was typing back into
+ # the input field.
+ field.value = val
+
+ # Finally, call the user supplied callback (if it exists)
+ success() if success?
+
+ # Execute the ajax call to search for autocomplete data
+ new Ajax.Request options.url, options
+
+root.ajaxChosen = ajaxChosen
Something went wrong with that request. Please try again.