django-select2 programatically setting value

318 views Asked by At

I'm using Django-select2 to show select2 widgets on my forms. On one of these form select-fields I want to user to be able to set the value by clicking a link containing a suggestion.

My javascript looks like:

<script type="text/javascript">
    $( document ).ready(function() {
        // When the topicSuggestion is clicked, populate the select2 field with that value.
        $('#topicSuggestion').on('click',function (e) {
            var value = {{ object.suggestion.topic.id }};
            $('#id_topic').val(value).trigger('change');
        });    
    });
</script>

This isn't quite working as expected though. Instead of nicely populating the value, this is the behaviour I see:

  1. Click the link, nothing happens
  2. Select a random value from the list, and click the link. The select seems to clear
  3. Select the desired value once, now click a random value and click the link. Now the value populates correctly

I can imagine this is related to my non-existing js skills. Could someone be kind enough to help me clear this up on this newyears day?

1

There are 1 answers

0
S.D. On BEST ANSWER

As we can see in https://github.com/codingjoe/django-select2/discussions/145 the items are loaded async. So if you want to pre-populate, you need to add the value first.

The select2 docs explain this: https://select2.org/programmatic-control/add-select-clear-items#create-if-not-exists

The answer in this case is:

    $( document ).ready(function() {
        // When the topicSuggestion is clicked, populate the select2 field with that value.
        $('#topicSuggestion').on('click',function (e) {
            $( "#topicSuggestion" ).css( "border", "9px solid red" );

            var data_id = {{ object.suggestion.topic.id }};
            var data_name = "{{ object.suggestion.topic.name }}";

            // Set the value, creating a new option if necessary
            if ($('#id_topic').find("option[value='" + data_id + "']").length) {
                $('#id_topic').val(data_id).trigger('change');
            } else { 
                // Create a DOM Option and pre-select by default
                var newOption = new Option(data_name, data_id, true, true);
                // Append it to the select
                $('#id_topic').append(newOption).trigger('change');
            };

        });