applegrew/django-select2

Assumes the values and choices are in the same order

tiagob opened this issue · 1 comments

I noticed the issue when I tried to delete a selected option. The option I thought I deleted still appeared after I successfully submitted the form. This seems to only happen when I have a lot of selected options (I have ~180 options selected and ~5k choices loaded via ajax).

The issue occurred because data in heavy_data.js wasn't correct. The ids didn't correctly match the txts.

I think this is because in heavy_data.js it's assumed that you can zip up txts and vals and this will yield the correct data objects (lines 46-48):

$(vals).each(function (index) {
    data.push({id: this, text: txts[index]});
});

But when these values are created in widgets.py vals and texts are not created with the same order. Vals is in it's instantiated order but texts is in the order that the matching val appears in choices.

In the render_texts method I think these lines:

for val, txt in chain(self.choices, all_choices):
    val = force_unicode(val)
    if val in selected_choices:
        selected_choices = [v for v in selected_choices if v != val]
        txts.append(txt)

should be changed to something like:

choices_dict = dict(chain(self.choices, all_choices))
for val in selected_choices:
    try:
        txts.append(choices_dict[val])
    except KeyError:
        raise KeyError("Value %s not in choices" % val)

Fix merged in Master.