(function($) {
	$.widget("ui.djselectable", {

        options: {
            removeIcon: "ui-icon-close",
            comboboxIcon: "ui-icon-triangle-1-s",
            prepareQuery: null
        },
        
        _initDeck: function(hiddenInputs) {
            var self = this;
            var data = $(this.element).data();
            var style = data['selectable-position'] || 'bottom';
            this.deck = $('<ul>').addClass('ui-widget selectable-deck selectable-deck-' + style);
            if (style === 'bottom' || style === 'bottom-inline') {
                $(this.element).after(this.deck);
            } else {
                $(this.element).before(this.deck);
            }
            $(hiddenInputs).each(function(i, input) {
                self._addDeckItem(input);
            });
        },

        _addDeckItem: function(input) {
            var self = this;
            $('<li>')
            .text($(input).attr('title'))
            .addClass('selectable-deck-item')
            .appendTo(this.deck)
            .append(
                $('<div>')
                .addClass('selectable-deck-remove')
                .append(
                    $('<button>')
                    .button({
                        icons: {
                            primary: self.options.removeIcon
                        },
                        text: false
                    })
                    .click(function() {
                        $(input).remove();
                        $(this).closest('li').remove();
                        return false;
                    })
                )
            );
        },

        _create: function() {
            var self = this,
            input = this.element;
            var data = $(input).data();
            var allowNew = data['selectable-allow-new'];
            var allowMultiple = data['selectable-multiple'];
            var textName = $(input).attr('name');
            var hiddenName = textName.replace('_0', '_1');
            var hiddenSelector = 'input[type=hidden][data-selectable-type=hidden-multiple][name=' + hiddenName + ']';
            if (allowMultiple) {
                allowNew = false;
                $(input).val("");
                this._initDeck(hiddenSelector);
            }

            function dataSource(request, response) {
                var url = data['selectable-url'];
                var now = new Date().getTime();
                var query = {term: request.term, timestamp: now};
                if (self.options.prepareQuery) {
                    self.options.prepareQuery(query);
                }
				$.getJSON(url, query, response);
            }

            $(input).autocomplete({
                source: dataSource,
                change: function(event, ui) {
                    $(input).removeClass('ui-state-error');
                    if ($(input).val() && !ui.item) {
                        if (!allowNew) {
                            $(input).addClass('ui-state-error');
                        } 
                    } 
                    if (allowMultiple && !$(input).hasClass('ui-state-error')) {
                        $(input).val("");
	                    $(input).data("autocomplete").term = "";
                    }
                },
                select: function(event, ui) {
                    $(input).removeClass('ui-state-error');
                    if (ui.item && allowMultiple) {
                        $(input).val("");
		                $(input).data("autocomplete").term = "";
                        if ($(hiddenSelector + '[value=' + ui.item.id + ']').length === 0) {
                            var newInput = $('<input />', {
                                'type': 'hidden',
                                'name': hiddenName,
                                'value': ui.item.id,
                                'title': ui.item.value,
                                'data-selectable-type': 'hidden-multiple'
                            });
                            $(input).after(newInput);
                            self._addDeckItem(newInput);
                            return false;
                        }
                    }
                }
            }).addClass("ui-widget ui-widget-content ui-corner-all");
            if (data['selectable-type'] === 'combobox') {
                // Change auto-complete options
                $(input).autocomplete("option", {
                    delay: 0,
                    minLength: 0
                })
                .removeClass("ui-corner-all")
                .addClass("ui-corner-left ui-combo-input");

                $("<button>&nbsp;</button>").attr("tabIndex", -1).attr("title", "Show All Items")
                .insertAfter($(input))
                .button({
                    icons: {
                        primary: self.options.comboboxIcon
                    },
                    text: false
                })
                .removeClass("ui-corner-all")
		        .addClass("ui-corner-right ui-button-icon ui-combo-button")
                .click(function() {
                    // close if already visible
                    if ($(input).autocomplete("widget").is(":visible")) {
                        $(input).autocomplete("close");
                        return false;
                    }

                    // pass empty string as value to search for, displaying all results
                    $(input).autocomplete("search", "");
                    $(input).focus();
                    return false;
                });
            }
        }
	});
})(jQuery);

function bindSelectables(context) {
    $(":input[data-selectable-type=text]", context).djselectable();
    $(":input[data-selectable-type=combobox]", context).djselectable();
    $(":input[data-selectable-type=hidden]", context).each(function(i, elem) {
        var hiddenName = $(elem).attr('name');
        var textName = hiddenName.replace('_1', '_0');
        $(":input[name=" + textName + "][data-selectable-url]").bind(
            "autocompletechange autocompleteselect",
            function(event, ui) {
                if (ui.item && ui.item.id) {
                    $(elem).val(ui.item.id);
                } else {
                    $(elem).val("");
                }
            }
        );
    });
}

if (typeof(django) != "undefined" && typeof(django.jQuery) != "undefined") {
    if (django.jQuery.fn.formset) {
        var oldformset = django.jQuery.fn.formset;
	    django.jQuery.fn.formset = function(opts) {
            var options = $.extend({}, opts);
            var addedevent = function(row) {
                bindSelectables($(row));
            };
            var added = null;
            if (options.added) {
                var oldadded = options.added;
                added = function(row) { oldadded(row); addedevent(row); };
            }
            options.added = added || addedevent;
            return oldformset.call(this, options);
        }
    }
}

$(document).ready(function() {
    bindSelectables('body');
});

@@ -340,24 +340,51 @@
  var style =
+ data.selectablePosition %7C%7C
  data%5B'selec
@@ -413,16 +413,16 @@
 ottom';%0A
-
         
@@ -1823,16 +1823,43 @@
 lowNew =
+ data.selectableAllowNew %7C%7C
  data%5B's
@@ -1908,24 +1908,51 @@
 owMultiple =
+ data.selectableMultiple %7C%7C
  data%5B'selec
@@ -2438,16 +2438,38 @@
 ar url =
+ data.selectableUrl %7C%7C
  data%5B's
@@ -4420,35 +4420,107 @@
     
-if (data%5B'selectable-type'%5D
+var selectableType = data.selectableType %7C%7C data%5B'selectable-type'%5D;%0A            if (selectableType
  ===
@@ -7190,24 +7190,24 @@
 , options);%0A
-
         %7D%0A  
@@ -7199,24 +7199,25 @@
 );%0A        %7D
+;
 %0A    %7D%0A%7D%0A%0A$(

Update JS to work with jQuery 1.6.0. Fixes #18.