Home > Net >  How to clear a select when changed another (select2)
How to clear a select when changed another (select2)

Time:09-02

I have this two selects, where I only have to select one at a time:

<div >
    <div >
        <label>Geo Blacklist</label>
        <select name="blacklist[]" multiple="multiple" id="blacklist"
            
            data-placeholder="Seleccionar uno o varios países" tabindex="1"
            onchange="$('#whitelist').val([]).change();">
            <option>a</option>
            <option>b</option>
            <option>c</option>
        </select>
    </div>
</div>

<div >
    <div >
        <label>Geo Whitelist</label>
        <select name="whitelist[]" multiple="multiple" id="whitelist"
            
            data-placeholder="Seleccionar uno o varios países" tabindex="1"
            onchange="$('#blacklist').val([]).change();">
            <option>x</option>
            <option>y</option>
            <option>z</option>
        </select>
    </div>
</div>

When I select anyone I get:

Uncaught RangeError: Maximum call stack size exceeded at RegExp.exec () at [Symbol.replace] () at String.replace () at Function.camelCase (jquery.js:346:17) at Function.style (jquery.js:6643:22) at jquery.js:6866:12 at jQuery.access (jquery.js:4142:5) at jQuery.fn.init.css (jquery.js:6849:10) at Search.resizeSearch (select2.full.js:2032:18) at DecoratedClass.resizeSearch (select2.full.js:580:32)

How can I do this?

CodePudding user response:

Just remove .change() as it trigger the change event on the other select and make infinite loop

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
            <div >
                <label>Geo Blacklist</label>
                <select name="blacklist[]" multiple="multiple" id="blacklist"
                    
                    data-placeholder="Seleccionar uno o varios países" tabindex="1"
                    onchange="$('#whitelist').val([]);">
                    <option>a</option>
                    <option>b</option>
                    <option>c</option>
                </select>
            </div>
        </div>
        
        <div >
            <div >
                <label>Geo Whitelist</label>
                <select name="whitelist[]" multiple="multiple" id="whitelist"
                    
                    data-placeholder="Seleccionar uno o varios países" tabindex="1"
                    onchange="$('#blacklist').val([]);">
                    <option>x</option>
                    <option>y</option>
                    <option>z</option>
                </select>
            </div>
        </div>

CodePudding user response:

This issue is with . When changing a <select> value that's been select2-ised, you have to call .change() to update the UI.

This then triggers the 2nd select change event, which calls .change etc, creating an infinite loop as shown with Maximum call stack size exceeded.

You can't simply remove the .change() as that would then not update the UI.

The solution is described in the select2 documentation

It's common for other components to be listening to the change event, or for custom event handlers to be attached that may have side effects [such as an infinite loop]. To limit the scope to only notify Select2 of the change, use the .select2 event namespace:

$('#mySelect2').val('US');
$('#mySelect2').trigger('change.select2'); // Notify only Select2 of changes

In the case of this question that would be to change

onchange="$('#blacklist').val([]).change();">

to

onchange="$('#blacklist').val([]).trigger('change.select2');">

(and the same for whitelist)

Here's a snippet (and fiddle) that demonstrates change.select2. Edit and change from change.select2 to change and you get the infinite loop.

$('.select2').select2();

$('#opt1').on('change', function() {
  console.log($(this).val())
  $("#opt2").val([]).trigger("change.select2");
});
$('#opt2').on('change', function() {
  $("#opt1").val([]).trigger("change.select2");
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.4/css/select2.min.css" rel="stylesheet" />
<script src="//code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.4/js/select2.min.js"></script>

<select  id='opt1'>
  <option value="AL">Alabama</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>

<select  id='opt2'>
  <option value="AL">Alabama</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>

  • Related