seaders
seaders

Reputation: 4106

With select2, how to access the original select/input element after it's been processed?

I'm using a combination of JQuery EasyUI and Select2 to be able to drag options from a right panel, onto a left select box.

In the original HTML, the select boxes are empty, and I only "add" anything to them if I drop an option on them,

<form id="section1">
<select class="select2" class="drop_target" id="selected_options" name="selected_options"></select>
<div>
<div class="draggable_option" data-id="1234">1234</div>
</div>
</form>
<form id="section2">
<select class="select2" class="drop_target"></select>
<div>
<div class="draggable_option" data-id="1235" id="selected_options" name="selected_options">1235</div>
</div>
</form>

Then in javascript, I do something like this,

$('.drop_target').droppable({
    accept: '.draggable_option',
    onDrop:function(e, source){
        var $dragged_source = $(source);
        var $drop_target = $(this);
    }
});

The problem comes at this point, if you're dynamically adding things to the select, you have to check it doesn't exist, and if it doesn't, you create a new option, and add it,

var new_option = {
    id: $drag_source.data('id'), data_id: $drag_source.data('id'),
    text: $drag_source.val(), selected: true};

// Set the value, creating a new option if necessary
if (!$drop_target.find("option[value='" + new_option.id + "']").length) {
    // Append it to the select
    $drop_target.append(new Option(
        new_option.text, new_option.id, true, true)).trigger('change');
}

var data = $drop_target.select2('data');
$drop_target.select2('data', data.concat([new_option]));

Clear as mud? Unfortunately it goes wrong at this point. While all calls to .select2 from $drop_target work as expected, this is not the select that was originally in the HTML, this is a div that select2 created, after hiding the original select, with an id attribute like id="s2id_selected_options". So when we append the new option to it, it doesn't get added to the select, and gets added to select2's div incorrectly instead.

My HTML pseudocode is deliberately set up in this "obtuse" way, because my page is like that. I have multiple forms, and multiple "identical" selects in those forms, generated by WTForms. So the "general" method of selecting your select by id, $('#selected_options') doesn't work correctly.

What I need to do, within the javascript, is gain access directly to the original, now hidden, select, and I can't access it via id.

Upvotes: 1

Views: 1997

Answers (1)

seaders
seaders

Reputation: 4106

When you have access to one of the elements that's "associated" with the generated by select2, you can access meta information for it via .data('select2'), or in this instance,

$(this).data('select2');

In here, there's loads of metadata that select2 uses (which you can see if you browse the source). For this question, to get the original select or input element, you can use,

var $drop_target = $(this).data('select2').opts.element;

Whether you're using a select, or an input, this gives you a jQuery element linking to it. If you're using a select, and are only interested in that, you can use the shorter option,

var $drop_target = $(this).data('select2').select;

This may be in the docs somewhere, but I was unable to find it, and I'm also not able to find it by searching now, because searching the docs for "data" and "select2" returns a result for nearly every page of their docs (hence the reason I'm answering this question myself, to hopefully save others the trouble).

Upvotes: 2

Related Questions