Skip to content
This repository has been archived by the owner on Jun 7, 2022. It is now read-only.

How to trigger change event with server side select2 to download and render a selected item? #32

Closed
alexaka1 opened this issue Jan 27, 2021 · 1 comment

Comments

@alexaka1
Copy link

alexaka1 commented Jan 27, 2021

With regular select2 I use this handy function, that I call on the underlying HTML Select element, and basically it loads the data from the provided URL, makes a new option element, appends it to the select element, then triggers both the plain change and select2 specific events.

$.fn.extend({
        preSelect2: function (params) {
            var select = this;
            $.ajax({
                type: 'GET',
                url: params.url
            }).then(function (data) {
                var option = new Option(data.text, data.id, true, true);
                select.append(option).trigger('change');

                select.trigger({
                    type: 'select2:select',
                    params: {
                        data: data
                    }
                });
            });
            return select;
        },
        ...
});

But since 🥕 farming is the future...
How can I do this with ng-select2?

If I change the wired [(ngModel)] on an "unused" select2 (meaning user hasn't selected any values yet), then it doesn't show the selection. However, if the user have selected a specific element before, then changed it to something else (either new value or cleared), then if I change the wired model value to the specific element, the correct element is shown as selection. (But neither times does the (valueChanged) event fire.)

I know that regular select2 appends each new selected value to the DOM permanently, so I assume this wrapper does the same thing (and that's why it's able to "show" a previously selected item, because it already exists in the dom), but I haven't been able to observe such DOM manipulation with dev tools or find the underlying select element and observe what happens when I do some clicky clicky. (Then again I'm still new to Angular, so maybe it does some magic on the fly without it reflecting in the DOM.)

@alexaka1
Copy link
Author

alexaka1 commented Jan 27, 2021

I managed to find a workaround, similair to my original jQuery.

const select = document
                    .getElementById('myNgSelect2')
                    ?.querySelector('select'); // select element is first child of the <ng-select2> element
const option = document.createElement('option');
option.innerText = myOption.text;
option.setAttribute('value', myModel.someProperty);
/* this selected attirbute makes it kinda jank, because multiple options will 
have the selected attribute, but ng-select2 seems to handle it well, and always selects the latest added option.
I would need more extensive testing, like if this select2 is part of a form, then the correct value gets sent or some random, or maybe first in the DOM?.
*/
option.setAttribute('selected', 'selected'); 
select?.appendChild(option);
select?.dispatchEvent(new Event('change')); // needless to say, but this will only work if the view has been initialized :)
<ng-select2 id="myNgSelect2" [(ngModel)]="myModel.someProperty"></ng-select2>

With myOption being populated by a server side request. I've put this into my observable.subscribe() method, and it seems the regular select change event is enough to trigger the select2 changing the selected item to this new one.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants