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>
Related
I would like to put multiple values in tag within select, so I could adress precisely one or few items.
Example:
<select id="select1">
<option value="pf, nn">NN</option>
<option value="pf, x2, jj">JJ</option>
<option value="pf, uu">UU</option>
<option value="pf, x2, oo">OO</option>
<option value="tt">TT</option>
<option value="rr">RR</option>
</select>
In my js I got that one function that depend on one value that is common for many items:
if (document.getElementById("select1").value = "pf";) {
// do something;
}
if (document.getElementById("select1").value = "x2";) {
// do some-other-thing;
}
But I don't want to use (cos' and with more options gonna get messy)
var sel1 = document.getElementById("select1").value
if (sel1="nn" || sel1="jj" || sel1="uu" || sel1="oo") {
// do something;
}
if (sel1="jj" || sel1="oo") {
// do some-other-thing;
}
Neverthelesst I need to be able to set item by precise one value
if (document.somethingelse = true) {
document.getElementById("select1").value = "oo";)
}
Is there a nice way to achieve this? Maybe use some other "value-like" attribute of option (but which?)?
Only JS.
I think you can do what you want with selectedOpt.value.split(",").includes("sth") code:
$(document).ready(function(e){
selectedChange($("#select1")[0])
});
function selectedChange(val) {
var selectedOpt = val.options[val.selectedIndex];
var status1 = selectedOpt.value.split(",").includes("x2");
var status2 = selectedOpt.value.split(",").includes("pf");
console.log(status1);
console.log(status2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select1" onchange="selectedChange(this)">
<option value="pf,nn">NN</option>
<option value="pf,x2,jj">JJ</option>
<option value="pf,uu">UU</option>
<option value="pf,x2,oo">OO</option>
<option value="tt">TT</option>
<option value="rr">RR</option>
</select>
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);
});
I'm not a coder ut I've found this code here
http://jsfiddle.net/kjy112/kchRh/
<textarea id="mytext"></textarea>
<select id="dropdown">
<option value="">None</option>
<option value="text1">text1</option>
<option value="text2">text2</option>
<option value="text3">text3</option>
<option value="text4">text4</option>
</select>
var mytextbox = document.getElementById('mytext');
var mydropdown = document.getElementById('dropdown');
mydropdown.onchange = function(){
mytextbox.value = mytextbox.value + this.value;
}
I'd like to modify it so that I've more than one dropdown and each one add his text in the same field.
Practically I'd have to create a compact code easily for the user so that the user select some phrases using the dropdown and the code will fill the text field.
If I can be more precise please let me know. As said Iìm not a coder so if you can write down the code to use I'll be very happy.
Thanks!
Here's a js bin with multiple dropdowns' onchange event being listed to: https://jsfiddle.net/kchRh/944/
You want to give the dropdowns class names and then loop through each drop down to setup their listeners.
HTML:
<textarea id="mytext"></textarea>
<select class="dropdown">
<option value="">None</option>
<option value="text1">text1</option>
<option value="text2">text2</option>
<option value="text3">text3</option>
<option value="text4">text4</option>
</select>
<select class="dropdown">
<option value="">2None</option>
<option value="2text1">2text1</option>
<option value="2text2">2text2</option>
<option value="2text3">2text3</option>
<option value="2text4">2text4</option>
</select>
JS:
var mytextbox = document.getElementById('mytext');
var mydropdowns = document.getElementsByClassName('dropdown');
for(i=0;i<mydropdowns.length;i++) {
mydropdowns[i].onchange = function(){
mytextbox.value = mytextbox.value + this.value;
}
}
I'd suggest the following approach:
// create a reusable function:
function updateTextArea() {
// get all the elements with the class 'dropdown':
var selectElems = document.querySelectorAll('.dropdown'),
// get the <textarea> element, using its id:
textArea = document.getElementById('mytext'),
// using Array.prototype.filter on the array-like
// NodeList, using Function.prototype.call, in
// order to iterate over the found '.dropdown'
// elements to form an array of only those elements
// with a non-zero-length value:
values = Array.prototype.filter.call(selectElems, function(el) {
if (el.value.trim().length) {
return el.value;
}
// iterating over the filter-created array, to form a map of
// the selected values of the elements:
}).map(function(el) {
return el.value;
// joining those arrays together, with Array.prototype.join,
// to form a comma-separated string of values, and appending
// a period:
}).join(', ') + '.';
// setting the value of the <textarea> to:
// - an empty string (if the values variable is
// just the appended-period), or to the value of
// the values variable:
textArea.value = values === '.' ? '' : values;
}
// as above, retrieving the '.dropdown' elements:
var selects = document.querySelectorAll('.dropdown');
// iterating over the '.dropdown' elements, using
// Array.prototype.forEach:
Array.prototype.forEach.call(selects, function(el, index, arr) {
// within the anonymous function of Array.prototype.foreach:
// the first argument (here: 'el') is the current array-element,
// second argument (here: 'index') is the index of the current
// array-element within the array over which we're iterating,
// third argument (here: 'arr') is the array over which we're
// iterating.
// binding updateTextArea as the change event-handler for
// each of the array-elements over which we iterate:
el.addEventListener('change', updateTextArea);
});
function updateTextArea() {
var selectElems = document.querySelectorAll('.dropdown'),
textArea = document.getElementById('mytext'),
values = Array.prototype.filter.call(selectElems, function(el) {
if (el.value.trim().length) {
return el.value;
}
}).map(function(el) {
return el.value;
}).join(', ') + '.';
textArea.value = values === '.' ? '' : values;
}
var selects = document.querySelectorAll('.dropdown');
Array.prototype.forEach.call(selects, function(el) {
el.addEventListener('change', updateTextArea);
});
<textarea id="mytext"></textarea>
<select class="dropdown">
<option value="">None</option>
<option value="text1">text1</option>
<option value="text2">text2</option>
<option value="text3">text3</option>
<option value="text4">text4</option>
</select>
<select class="dropdown">
<option value="">None</option>
<option value="text5">text5</option>
<option value="text6">text6</option>
<option value="text7">text7</option>
<option value="text8">text8</option>
</select>
JS Fiddle demo.
Note, in the HTML, I've changed from the use of id to identify the <select> elements, to using class; simply because it allows a group of elements to be associated together without having to use a large number of ids and subsequently having to update the JavaScript in turn with the HTML.
Referencs:
Array.prototype.filter().
Array.prototype.forEach().
Array.prototype.join().
Array.prototype.map().
document.querySelectorAll().
eventTarget.addEventListener().
Function.prototype.call().
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>
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]);
}