Get list of classes from array of elements - javascript

I have the following array that holds a number of option elements, depending on if it has the hidden class or not.
var list = $('#condition option').not('.hidden');
How can I get an array of classes these elements have?
What I have tried:
var list = $('#condition option').not('.hidden').attr('class');
However, this only returns classes associated with the last element in the array.

You can use .map():
$('#condition option').not('.hidden').map(function() {
return this.className.split(' ');
}).get();
Here's a fiddle

Like suggested in the comments, use JQuery's each function.
var list_condition = $('#condition option').not('.hidden');
var list_class = []; // Creates an empty array
$(list_condition).each(function(index) {
list_class.push($(list_condition)[index].attr('class')); // Pushes the element into the array
});

You can do that using jQuery.each() function
Example:
var list = $('#condition option').not('.hidden'),
classes = [];
$(list).each(function () {
classes.push($(this).attr('class'));
});
console.log(classes);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="condition">
<option class="some-class-1" > some option </option>
<option class="some-class-2" > some option </option>
<option class="some-class-3" > some option </option>
<option class="some-class-4" > some option </option>
<option class="some-class-5" > some option </option>
<option class="some-class-6" > some option </option>
<option class="some-class-7" > some option </option>
<option class="some-class-8" > some option </option>
</select>
Update
If you want to split/separate every single element, for example if some option have some classes like class-1-a, class-1-b .. etc
in this case you may need String.prototype.split()
Example
var list = $('#condition option').not('.hidden'),
allClasses = [];
$(list).each(function () {
var elemClasses = $(this).attr('class');
elemClasses.trim().split(/\s+/).map(function (x) {
allClasses.push(x);
})
});
console.log(allClasses);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="condition">
<option class="some-class-1-a some-class-1-b" > some option </option>
<option class="some-class-2-a some-class-1-b " > some option </option>
<option class="some-class-3" > some option </option>
<option class="some-class-4" > some option </option>
<option class="some-class-5" > some option </option>
<option class="some-class-6" > some option </option>
<option class="some-class-7" > some option </option>
<option class="some-class-8" > some option </option>
</select>

Maybe something like this. The list selects all of the dom elements.
The .each iterates through them all.
var list = $('#condition option').not('.hidden').attr('class');
$(list).each(function( index ) {
var myClass = $(this).attr("class");
console.log(myClass);
});

Related

How to set the default value on select dropdowns with javascript after AJAX call

I have a program that generates a table rows based on part selections from a dropdown menu. On each row that is created, I have a <td> element that contains a dropdown for quantity. My problem is that when a new part is selected thus creating a new row, all my quantity dropdowns reset back to the default value of 1. I tried fixing it with "selected = true;" but that doesn't seem to work. Basically, I need to set the selected value of each quantity dropdown to stay as whatever selected value it was last set at when the user adds a new row. I'm using an ajax call to generate the data from a SQL table on each new row.
Here is the function which is called from the select dropdown. I've omitted a lot of unnecessary code:
function update(){
var selectLists = document.getElementsByName("qty_dropdown");
for(var i = 0; i < selectLists.length; i++){
var firstSelectList = selectLists[i].value;
}
}
Here is my dropdown:
<td>
<select name = "qty_dropdown" onChange = "update()">
<option value = '1'> 1 </option>
<option id = '2'value = '2'> 2 </option>
<option value = '3'> 3</option>
<option value = '4'> 4 </option>
<option value = '5'> 5 </option>
<option value = '6'> 6 </option>
<option value = '7'> 7 </option>
<option value = '8'> 8 </option>
<option value = '9'> 9 </option>
<option value ='10'> 10</option>
</td>
</select>
The function you are performing inside update() (i renamed it to add() ) should be performed on the addition of new row.
function add(){
var selectLists = document.getElementsByName("qty_dropdown");
var firstSelectList=[];
for(var i = 0; i < selectLists.length; i++){
firstSelectList.push(selectLists[i].value);
}
document.getElementById("inject").innerHTML+="<select name = 'qty_dropdown' onChange = 'update()'> <option value = '1'> 1 </option> <option id = '2'value = '2'> 2 </option> <option value = '3'> 3</option> <option value = '4'> 4 </option> <option value = '5'> 5 </option> <option value = '6'> 6 </option> <option value = '7'> 7 </option> <option value = '8'> 8 </option> <option value = '9'> 9 </option> <option value ='10'> 10</option> </select> ";
for(var i = 0; i < selectLists.length-1;i++){
selectLists[i].value=firstSelectList[i];
}
}
this function add() will add a new row without resetting previous dropdown.
Demo : https://jsfiddle.net/0wur28ot/
What i did is save the value in array before adding new row and then i assigned values to the dropdown accordingly after row addition.
Here is one way you can do it. You can keep a variable around that keeps track of the most recently selected dropdown value, and when you add a new dropdown to the DOM, it will use that value as its initial value.
var lastUpdatedDropdownValue = "";
function update(event) {
lastUpdatedDropdownValue = event.target.value;
}
function addNewDropdown() {
var dropdown = document.querySelector("[name=qty_dropdown]");
var newDropdown = dropdown.cloneNode(true); // make sure no duplicate IDs. If your elements that are being cloned have IDs, remove them before re-inserting into the DOM
document.getElementById("dropdownContainer").append(newDropdown);
var selectedOption = newDropdown.querySelector("[value='" + lastUpdatedDropdownValue + "']");
selectedOption.selected = true;
}
<button onclick="addNewDropdown()">Add New Dropdown</button>
<div id="dropdownContainer">
<select name="qty_dropdown" onChange="update(event)">
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
<option value='6'>6</option>
<option value='7'>7</option>
<option value='8'>8</option>
<option value='9'>9</option>
<option value='10'>10</option>
</select>
</div>

Remove the duplicate values and combinations in html select option

I have a dynamically generated <select> field with <option>.
<select>
<option value=""></option>
<option value=""></option>
<option value=""> False</option>
<option value=""> True</option>
<option value="">False False</option>
<option value="">False True</option>
<option value="">True</option>
<option value="">True True</option>
</select>
I would like to remove the duplicate occurrences and combinations. The final <select> field with <option> should look like :
<select>
<option value=""></option>
<option value="">False</option>
<option value="">True</option>
</select>
Here is how my fiddle looks like. Been trying to solve this for hours.
var values = [];
$("select").children().each(function() {
if (values.length > 0) {
var notExists = false;
for (var x = 0; x < values.length; x++) {
var _text = this.text.replace(/\s/g, "");
var value = values[x].replace(/\s/g, "");
if (values[x].length > _text.length) {
//console.log('>>+', value, ' || ', _text, value.indexOf(_text))
notExists = value.indexOf(_text) > -1 ? true : false;
} else {
//console.log('>>*', value, ' || ', _text, _text.indexOf(value))
notExists = _text.indexOf(value) > -1 ? true : false;
}
}
if (notExists) {
//this.remove();
values.push(this.text);
}
} else {
values.push(this.text);
}
});
Any help to solve this is appreciated.
You can use map() to return all options text and use split() on white-space. Then to remove duplicates you can use reduce() to return object. Then you can empty select and use Object.keys() to loop each property and append to select.
var opt = $("select option").map(function() {
return $(this).text().split(' ')
}).get();
opt = opt.reduce(function(o, e) {return o[e] = true, o}, {});
$('select').empty();
Object.keys(opt).forEach(function(key) {
$('select').append(' <option value="">'+key+'</option>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option value=""></option>
<option value=""></option>
<option value="">False</option>
<option value="">True</option>
<option value="">False False</option>
<option value="">False True</option>
<option value="">True</option>
<option value="">True True</option>
</select>
You can loop through each of this children text , then use substring to get the first text & put it in an array.
Once done empty the select element and append the newly created options
var _textHolder=[]; // NA empty array to hold unique text
var _options="";
$("select").children().each(function(item,value) {
var _textVal = $(this).text().trim(); // Remove white space
//get the first text content
var _getText = _textVal.substr(0, _textVal.indexOf(" "));
// if this text is not present in array then push it
if(_textHolder.indexOf(_getText) ==-1){
_textHolder.push(_getText)
}
});
// Create new options with items from _textHolder
_textHolder.forEach(function(item){
_options+='<option value="">'+item+'</option>'
})
// Empty current select element and append new options
$('select').empty().append(_options);
JSFIDDLE
I would do with pure JS ES6 style. This is producing a words array from the whitespace separated options element's innerText value regardless the words are in the front, middle or the end; and it will create a unique options list from that. Basically we are concatenating these arrays and getting it unified by utilizing the new Set object. The code is as follows;
var opts = document.querySelector("select").children,
list = Array.prototype.reduce.call(opts, function(s,c){
text = c.innerText.trim().split(" ");
return new Set([...s].concat(text)) // adding multiple elements to a set
},new Set());
list = [...list]; // turn set to array
for (var i = opts.length-1; i >= 0; i--){ //reverse iteration not to effect indices when an element is deleted
i in list ? opts[i].innerText = list[i]
: opts[i].parentNode.removeChild(opts[i]);
}
<select>
<option value=""></option>
<option value=""></option>
<option value=""> False</option>
<option value=""> True</option>
<option value="">False False</option>
<option value="">False True</option>
<option value="">True</option>
<option value="">True True</option>
</select>

Javascript: dropdown, get first element value LIKE?

Given a dropdown with an unknown number of option elements:
<select id="ddlDropDown">
<option value="text1">Some text</option>
<option value="text2">Some text</option>
<option value="text3">Some text</option>
...
<option value="textN">Some text</option>
And given a textbox where I can type in a value:
<input type=text id="txtTextBox" onkeyup="selectDDL();"/>
And given the script function:
function selectDDL(){
var txtElem = document.getElementById("txtTextBox");
var ddlElem = document.getElementById("ddlDropDown");
var typedText = txtElem.value;
//magic happens here
}
How do I, using purely javascript, get select the first option matching LIKE the text in the text box without iterating through the entire collection?
That is to say, assume that I have 500 dropdown option elements with random values between 500 and 1500, how do I get and select the first option (in the list, not in order) that matches what the user has typed so far?
So if their were three items: 1030, 1012, and 1013 in the dropdown and the user types:
1: 1030 is selected.
10: 1030 is still selected
101: 1012 is selected
1013: 1013 is selected
Clarification: without iterating the collection and similar to jquery's ^= operator
You don't need jQuery to use ^=, just use querySelectorAll with the attribute prefix selector:
var texts = document.querySelectorAll("[value^='text']");
console.log(texts);
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<select id="ddlDropDown">
<option value="text1">Some text</option>
<option value="text2">Some text</option>
<option value="text3">Some text</option>
<option value="textN">Some text</option>
<option value="notText">123456</option>
</select>
You can use a starts with attribute selector. Only issue with the code is I am not escaping any of the special characters from the selector. So if the user enters in ' it will blow up.
document.querySelector("#x").addEventListener("keyup", function(){
//code to filter out the options
var txt = this.value;
var opts = document.querySelectorAll("#ddlDropDown option[value^='" + txt + "']");
//code to display the options for demo
var out = Array.prototype.slice.call( opts ).map(function (x) {return x.value});
document.querySelector("p").innerHTML = out.join("<br/>");
});
<select id="ddlDropDown">
<option value="text1">Some text</option>
<option value="text2">Some text</option>
<option value="text3">Some text</option>
<option value="text11">Some text</option>
<option value="text21">Some text</option>
<option value="text31">Some text</option>
</select>
<input type="textbox" id="x">
<p></p>
I would use the string#indexOf method to find out if there's a match.
function selectDDL() {
var txtElem = document.getElementById("txtTextBox");
var ddlElem = document.getElementById("ddlDropDown");
var typedText = txtElem.value;
var options = document.querySelectorAll("#ddlDropDown option");
var matches = [];
for (var i = 0; i < 3; i++) {
if (options[i].innerHTML.indexOf(typedText) == 0) {
matches.push(options[i]);
}
}
matches[0].setAttribute("selected", "selected");
}
Those who rely on a selector with [value^=...] will find an option by its value attribute, not by its text.
There is no CSS selector for selecting an option by its text. jQuery supports "has" and "contains", but uses iteration to implement those features.
Just for a fun alternative, but probably not advisable: innerHTML is slow and this will go wrong when the select tag has other tags inside than the options:
var html = ddlElem.innerHTML;
var idx = html.indexOf('>'+typedText);
ddlElem.selectedIndex = idx === -1
? -1
: html.substr(0, idx).match(/\<option/g).length - 1;

Display items of two drop down based on each other

I have two drop downs with exactly the same values.
I want the drop down 2 to display the values based on the selection of items of drop down 1.
So the selected index of drop down 2 will be equal to or more than the selected index of drop down 1.
document.getElementById("SELECTB").selectedIndex >= document.getElementById("SELECTA").selectedIndex
So if B is selected in Drop down 1 then selectable options in drop down 2 will be B,C and D. (A will be not selectable item)
http://jsfiddle.net/xxyhm78t/1/
Solution working with pure Javascript:
var select1 = document.getElementById("SELECTA");
var select2 = document.getElementById("SELECTB");
select1.onchange = function () {
while (select2.firstChild) {
select2.removeChild(select2.firstChild);
}
for (var i = select1.selectedIndex; i < select1.options.length; i++) {
var o = document.createElement("option");
o.value = select1.options[i].value;
o.text = select1.options[i].text;
select2.appendChild(o);
}
}
Fiddle
Reference: This is an adjusted solution from javascript Change the Dropdown values based on other dropdown
Update: Like asked in the comment - to disable the options instead of removing them:
var select1 = document.getElementById("SELECTA");
var select2 = document.getElementById("SELECTB");
select1.onchange = function () {
while (select2.firstChild) {
select2.removeChild(select2.firstChild);
}
for (var i = 0; i < select1.options.length; i++) {
var o = document.createElement("option");
o.value = select1.options[i].value;
o.text = select1.options[i].text;
(i <= select1.selectedIndex)
? o.disabled = true
: o.disabled = false ;
select2.appendChild(o);
}
}
Adjusted Fiddle
Update 2: Like asked in the comment if it's possible to adjust this to use class names instead of ids - yes, by using getElementsByClassName(). I've adjusted in this Fiddle both selects to have class="SELECTA" and class="SELECTB" instead of the previously used id. The according adjustment for the Javascript is only the declaration of the variables:
var select1 = document.getElementsByClassName("SELECTA")[0];
var select2 = document.getElementsByClassName("SELECTB")[0];
As you already know, an id is a unique attribute, therefore it's possible to get a single element using getElementById(). getElementsByClassName() returns a collection of HTML elements instead, even if there's only a single element having the class. So it's - in this example - necessary to address the 1st element of this collection. As counting starts by 0, the first (and only) element having the class "SELECTA" is getElementsByClassName("SELECTA")[0].
Reference: https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName#Syntax
You can do this using selectedIndex with the following piece of code:
$("#SELECTA").change(function() {
var selIndex = this.selectedIndex;
$("#SELECTB").find("option").each(function(k,v) {
$(this).attr("disabled", selIndex > k);
});
});
Depending on what it is you are after, you may need to reset #SELECTB if one of the disabled values is selected.
I think this is what you are looking for:
$("select").on("change", function (e) {
var sel = this.selectedIndex;
$("#SELECTB option").each(function (i, e) {
$(this).prop("disabled", sel > i);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="SELECTA">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
<select id="SELECTB">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
And this can be even more general:
$("select").on("change", function (e) {
var sel = this.selectedIndex;
var nextSelect = $(this).parent().find("select").not(this);
$(nextSelect).children().each(function (i, e) {
$(this).prop("disabled", sel > i);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="SELECTA">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
<select id="SELECTB">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>

How can I remove options with the same text from a select element?

I have a select element that shows multiple options with the same text:
<select name="tur" id="tur">
<option value="1">a</option>
<option value="2">a</option>
<option value="3">a</option>
<option value="4">a</option>
<option value="5">b</option>
<option value="6">b</option>
<option value="7">c</option>
<option value="8">d</option>
</select>
Using JavaScript, I would like to remove these duplicates so that only one of each is shown:
<select name="tur" id="tur">
<option value="1">a</option>
<option value="5">b</option>
<option value="7">c</option>
<option value="8">d</option>
You can loop through the <option> elements, checking each one to see if its text content is in an array. If it is, remove the <option>. If not, add its content to the array. This will remove options that are redundant in the list.
Try it out: http://jsfiddle.net/FXq8W/
​var array = [];
​$('#tur option').each(function() {
var $th = $(this);
var text = $th.text();
if( $.inArray(text, array) > -1 ) {
$th.remove();
} else {
array.push( text );
}
});​​​​​​​​​​​​​​
http://api.jquery.com/jquery.inarray/
var remove = [], values = {}, value, i;
var options = document.getElementById('tur').getElementsByTagName('option');
for (i=0; i<options.length; i++) {
value = options[i].innerHTML.replace(/^\s*|\s*$/g, '');
if (value in values) remove.push(options[i]);
else values[value] = true;
}
for (i=0; i<remove.length; i++) {
remove[i].parentNode.removeChild(remove[i]);
}

Categories