Akshay
Akshay

Reputation: 2763

Remove a class on selection and add class to others

Very much new to JS and so far I did get what I needed but its a chaos.

I have three classes aer, bsa and sf who have their own div space and by default, they have Bootstrap 4's d-none (display none) class. Now when aer is selected from a drop-down list d-none should be removed and bsa and sf shouldn't change (because they already have d-none in them). Then when I select bsa, d-none should be removed and aer should have d-none, and for bsa nothing should happen. Same goes to sf.

I was able to get this done by the following JQuery:

const aer = $('.aer');
const bsa = $('.bsa');
const sf = $('.sf');

// Encoding algorithm
$('select[id=id_encoding_algorithm_name]').change(function () {
    console.log($(this).val());
    switch ($(this).val()) {
        case "AER":
            if(aer.hasClass('d-none')) {
                aer.each(function () {
                    $(this).removeClass('d-none');
                });
            }

            if (!bsa.hasClass('d-none')) {
                bsa.each(function () {
                    $(this).addClass('d-none');
                });
            }
            if (!sf.hasClass('d-none')) {
                sf.each(function () {
                    $(this).addClass('d-none');
                });
            }
            break;
        case "BSA":
            if(bsa.hasClass('d-none')) {
                bsa.each(function () {
                    $(this).removeClass('d-none');
                });
            }

            if (!aer.hasClass('d-none')) {
                aer.each(function () {
                    $(this).addClass('d-none');
                });
            }
            if (!sf.hasClass('d-none')) {
                sf.each(function () {
                    $(this).addClass('d-none');
                });
            }
            break;
        case "SF":
            if(sf.hasClass('d-none')) {
                sf.each(function () {
                    $(this).removeClass('d-none');
                });
            }

            if (!aer.hasClass('d-none')) {
                aer.each(function () {
                    $(this).addClass('d-none');
                });
            }
            if (!bsa.hasClass('d-none')) {
                bsa.each(function () {
                    $(this).addClass('d-none');
                });
            }
            break;
    }
});

This is too much of code for toggling a class (I guess), is there a better way to do it?

Update 1:

HTML Code (only div code):

<div class="pt-4">
    <div class="card">
        <div class="card-header">
            Encoding Algorithm
        </div>
        <div class="card-body">
            <div class="form-group row">
                <label for="Encoding Algorithm Name" class="col-sm-2 col-form-label align-self-center">Encoding
                    Algorithm Name</label>
                <div class="col-sm-9 align-self-center">
                    <select name="encoding_algorithm_name" class="form-control" id="id_encoding_algorithm_name">
                        <option value="AER" selected>Address Event Representation</option>

                        <option value="BSA">Ben&#39;s Spiker Algorithm</option>

                        <option value="SF">Step Forward Algorithm</option>

                    </select>
                </div>
                <div class="col-sm-1 align-self-center">
                    <a href="#" data-toggle="tooltip" data-html="true" title="Set the Encoding algorithm. &lt;br&gt;&lt;strong&gt;Value: AER (Address Event Representation the same as Threshold-base algorithm), BSA (Ben&#39;s spiker algorithm), SF (Step forward with optimisation).&lt;/strong&gt;"><i class="fas fa-info-circle"></i></a>
                </div>
            </div>
            <div class="form-group row aer d-none">
                <label for="Aer Spike Threshold Value" class="col-sm-2 col-form-label align-self-center">Aer
                    Spike Threshold Value</label>
                <div class="col-sm-9 align-self-center">
                    <input type="text" name="aer_spike_threshold_value" value="0.5" class="form-control" required id="id_aer_spike_threshold_value">
                </div>
                <div class="col-sm-1 align-self-center">
                    <a href="#" data-toggle="tooltip" data-html="true" title="Set the distance between the mean and the standard deviation of temporal data changes. &lt;br&gt;&lt;strong&gt;Value: (0,1] (real value) (anything less than 1)&lt;/strong&gt;"><i class="fas fa-info-circle"></i></a>
                </div>
            </div>
            <div class="form-group row bsa d-none">
                <label for="Num Filters" class="col-sm-2 col-form-label align-self-center">Num
                    Filters</label>
                <div class="col-sm-9 align-self-center">
                    <input type="number" name="num_filters" value="1" class="form-control" required id="id_num_filters">
                </div>
                <div class="col-sm-1 align-self-center">
                    <a href="#" data-toggle="tooltip" data-html="true" title="Set the number of filters to be used. If the numnber of filters is equals to 1 then all the features of the sample will be encoded using the same filter. If the number of filters is greater than 1 then the number of filters must be the same as the number of features of the data. &lt;br&gt;&lt;strong&gt;Value: [1, numFeatures ] (integer)&lt;/strong&gt;"><i class="fas fa-info-circle"></i></a>
                </div>
            </div>
            <div class="form-group row bsa d-none">
                <label for="Threshold Vec" class="col-sm-2 col-form-label align-self-center">Threshold
                    Vec</label>
                <div class="col-sm-9 align-self-center">
                    <input type="text" name="threshold_vec" value="0.9" class="form-control" required id="id_threshold_vec">
                </div>
                <div class="col-sm-1 align-self-center">
                    <a href="#" data-toggle="tooltip" data-html="true" title="Set the threshold value. &lt;br&gt;&lt;strong&gt;Value: [0.5, 1.0] (real value)&lt;/strong&gt;"><i class="fas fa-info-circle"></i></a>
                </div>
            </div>
            <div class="form-group row bsa d-none">
                <label for="Filter Order Vec" class="col-sm-2 col-form-label align-self-center">Filter
                    Order Vec</label>
                <div class="col-sm-9 align-self-center">
                    <input type="text" name="filter_order_vec" value="24" class="form-control" required id="id_filter_order_vec">
                </div>
                <div class="col-sm-1 align-self-center">
                    <a href="#" data-toggle="tooltip" data-html="true" title="Set the order of the low pass FIR. &lt;br&gt;&lt;strong&gt;Value: [0.5, 1.0] (real value)&lt;/strong&gt;"><i class="fas fa-info-circle"></i></a>
                </div>
            </div>
            <div class="form-group row bsa d-none">
                <label for="Filter Cutoff Vec" class="col-sm-2 col-form-label align-self-center">Filter
                    Cutoff Vec</label>
                <div class="col-sm-9 align-self-center">
                    <input type="text" name="filter_cutoff_vec" value="0.1255" class="form-control" required id="id_filter_cutoff_vec">
                </div>
                <div class="col-sm-1 align-self-center">
                    <a href="#" data-toggle="tooltip" data-html="true" title="Set the cutoff frequency of the FIR. &lt;br&gt;&lt;strong&gt;Value: (0,1). If the numFilters key is greater than 1 this&lt;/strong&gt;"><i class="fas fa-info-circle"></i></a>
                </div>
            </div>
        </div>
    </div>
</div>

Upvotes: 0

Views: 791

Answers (5)

Charlie
Charlie

Reputation: 23798

Your code can be further simplified.

  1. You can execute the removeClass method on the whole selection at once.

Remove a single class, multiple classes, or all classes from each element in the set of matched elements.

  1. You really don't have to check if a selection has a class in order to remove it.

So, the code can be simplified as:

    case "AER":
        aer.removeClass('d-none');
        bsa.addClass('d-none');
        sf.addClass('d-none');

Same applies to other cases too.

Upvotes: 1

dganenco
dganenco

Reputation: 1616

I would advice you to use jQuery#toggleClass method with condition to get more control against your code:

const divs = $('.aer, .bsa, .sf');

// Encoding algorithm
$('select#id_encoding_algorithm_name').change(function () {
        const value = $(this).val().toLowerCase();
        divs.each(function(index, el){
            $(el).toggleClass('d-none', !$(el).hasClass(value))
        });
});

Upvotes: 1

Mangesh
Mangesh

Reputation: 365

Do check the below jsFiddle: https://jsfiddle.net/ulric_469/tyf5epk2/11/

JScode:

$('select[id=id_encoding_algorithm_name]').change(function () {
    $(".common-class").addClass('d-none');
    let currentClass = $(this).val();
    currentClass = currentClass && currentClass.toLowerCase();
    $("."+currentClass).removeClass('d-none');
});

I have added one common class to html you can check the same in JSfiddle

Upvotes: 1

ss_rn
ss_rn

Reputation: 111

You could use toggleClass() as well in jQuery.

aer.toggleClass('d-none')

Upvotes: 1

Kiran Shinde
Kiran Shinde

Reputation: 5982

Why so much of conditions?

You can simply do it by

$('select[id=id_encoding_algorithm_name]').change(function () {
    console.log($(this).val());
    
    $(aer, bsa, sf).addClass('d-none');
    switch ($(this).val()) {
        case "AER":
                aer.removeClass('d-none');
            break;
        case "BSA":
                bsa.removeClass('d-none');
            break;
        case "SF":
                sf.removeClass('d-none');
            break;
    }
});

or if you can change values to aer, bsa, sf instead of AER, BSA it will simply become

 $('select[id=id_encoding_algorithm_name]').change(function () {
    console.log($(this).val());

    $(aer, bsa, sf).addClass('d-none');
    $("." + $(this).val()).removeClass('d-none');
});

Upvotes: 1

Related Questions