How do you disable an <option> selected in another <select> while applying to newly added <select> and previous <select>

Viewed 69

I have this code that I'm using here that disables select options based on similar fields.


$(document).on('shown.oc.popup', function() {


    let options = $('.variantPlacementOptions:first select').children();
    let availableOptions = $.map(options ,function(options) {
        return options;
    });


    $('.variantPlacementOptions select option').attr('disabled', false)

    console.log(availableOptions);



    // Get form and check if fields are selected, and disable if they are (on ajaxDone)
    $(document).on('ajaxDone', function (){

        $('.variantPlacementOptions select option').removeAttr('disabled')
        $('.variantPlacementOptions select').each(function() {
            var val = this.value;
            $('.variantPlacementOptions select').not(this).find('option').filter(function() {
                return this.value === val;
            }, this).attr('disabled', true);
        });
    })

    $('.variantPlacementOptions select').on('change', function() {
        $('.variantPlacementOptions select option').removeAttr('disabled')
        $('.variantPlacementOptions select').each(function() {
            var val = this.value;
            $('.variantPlacementOptions select').not(this).find('option').filter(function() {
                return this.value === val;
            }, this).attr('disabled', true);
        });
    }).change();

});

My issue with this code is that it does not work on newly added select fields. oddly enough, I can do this:


$(document).on('shown.oc.popup', function() {


    let options = $('.variantPlacementOptions:first select').children();
    let availableOptions = $.map(options ,function(options) {
        return options;
    });


    // Get form and check if fields are selected, and disable if they are (on ajaxDone)
    $(document).on('ajaxDone', function (){

        $('.variantPlacementOptions select').html(availableOptions) // Add in available options before removing
        $('.variantPlacementOptions select').each(function() {
            var val = this.value;
            $('.variantPlacementOptions select').not(this).find('option').filter(function() {
                return this.value === val;
            }, this).remove; //remove item in question
        });
    });
});

But doing this isn't good for user experience because it deselects the values. It also makes me puzzled because if this could work, in theory, the first option should work.

A little more context on the goal as well

  • I would love to achieve this with the current classes and jQuery
  • I need to keep the classes as is because I do not have complete control over the DOM structure. I can add container classes, but I cannot directly add classes or IDs to the elements. I cannot add IDs to the container class either.
  • I am doing this in OctoberCMS v2, in the backend.

Other notes:

  • This question didn't help as it doesn't achieve what I would like.

I would love any type of help.

1 Answers

Someone on reddit (u/iluminumx) answered my question.

I needed to move the part of the selection to the event handler as a parameter. This:

$('.variantPlacementOptions select').on('change', function() {
   
}).change();

needed to be this:

$('.variantPlacementOptions').on('change', 'select', function() {
   
}).change();
Related