I have a select field with different values :
- africa
- europe
- america
- asia
- oceania
When selecting a value, I want to add a css class to a specific div, the name of the css class being the value selected. Easy enough :
$(document).on("change", "[data-name='continent'] select", function () {
var continent = $('[data-name="continent"] select').val();
$("#mydiv").addClass(continent);
});
This works fine, but there is a problem : if I change the select field value, the previous classes will not be removed. I can't do :
$("#mydiv").removeClass().addClass(continent);
Because #mydiv already has other important classes. I could do :
$("#mydiv").removeClass('africa').removeClass('europe').removeClass('america').removeClass('asia').removeClass('oceania').addClass(continent);
But in reality I have more than just 5 options and they might change in the future; I'd rather keep things flexible. And more than anything, i want to learn javascript. Is there any way to remove all the classes that are values of the select field ?
CodePudding user response:
To get a list of the classes you want to remove, you can use something like this:
[...testEl.querySelectorAll('option')].map(x => x.value).join(' ');
This is vanilla JavaScript...if done in jQuery it would look like this:
$('#my-select > option').map((i,el)=> el.value).toArray().join(' ');
That will pull out a list of the options and give you a space-delimited string. You could then use this list to do your .removeClass()
.
However I wonder if class is the best option for this. In the following snippet there is an example of using a data attribute instead of class, and how that data attribute could be used in a CSS selector (this would also work in jQuery
or querySelector
). Maybe an option to consider...
const testEl = document.querySelector('#test');
const allOptions = $('#test > option').map((i,el)=> el.value).toArray().join(' ');
console.log(allOptions);
const testChange = e => {
const el = e.target;
el.dataset.chosen = el.value;
};
testEl.addEventListener('change', testChange);
testChange({ target: testEl });
#test[data-chosen="africa"] {
color: red;
}
#test[data-chosen="america"] {
color: blue;
}
#test {
color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name='test' id='test' value='europe'>
<option value='africa'>africa</option>
<option value='europe'>europe</option>
<option value='america'>america</option>
<option value='asia'>asia</option>
<option value='oceania'>oceania</option>
</select>
CodePudding user response:
Try this:
$('#continent').on('change', (e) => {
let $myDiv = $('#myDiv'),
$continent = $(e.target),
possibleValues = $continent.find('option').toArray().map(item => item.value).join(' ');
$myDiv.removeClass(possibleValues).addClass($continent.val());
});
Explanation:
Gather all possible values from the select:
$continent.find('option').toArray().map(item => item.value)
Join them in a space-separated list into a string:
.join(' ');
Remove all classes from that list from the target element
$myDiv.removeClass(possibleValues)
Add the selected class after it.
Demo:
$('#continent').on('change', (e) => {
let $myDiv = $('#myDiv'),
$continent = $(e.target),
possibleValues = $continent.find('option').toArray().map(item => item.value).join(' ');
$myDiv.removeClass(possibleValues).addClass($continent.val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="continent">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
<option value="d">D</option>
<option value="e">E</option>
</select>
<div id="myDiv" >my div</div>
CodePudding user response:
You will have to create a string containing all the classes you want to add/remove seperated by space:
$("#mydiv").removeClass("africa europe america asia oceania");