I have a select dropdown field that is being created dynamically from a database . Due to the way this is being created it results in the dropdown having duplicate items and values.
<select id="locationList">
<option value="1">Andover</option>
<option value="2">Bishops waltham</option>
<option value="1">Andover</option>
<option value="3">Boscombe</option>
<option value="4">Bournemouth</option>
<option value="2">Bishops waltham</option>
<option value="4">Bournemouth</option>
</select>
Does anyone know if there is a way to use some code on the page which checks the dropdown for duplicates and removes duplicates from the menu only by Javascript No Jquery?
Thanks in advance,
Abhinav
Javascript has removeChild option, you can use it to remove duplicate value:
var fruits = document.getElementById("locationList");
[].slice.call(fruits.options)
.map(function(a){
if(this[a.value]){
fruits.removeChild(a);
} else {
this[a.value]=1;
}
},{});
<select id="locationList">
<option value="1">Andover</option>
<option value="2">Bishops waltham</option>
<option value="1">Andover</option>
<option value="3">Boscombe</option>
<option value="4">Bournemouth</option>
<option value="2">Bishops waltham</option>
<option value="4">Bournemouth</option>
</select>
Another option is to use the set as suggested here: alternatives or another alternative.
[ ...new Set([ ...<arg1>, ...<arg2> ]) ] for e.g.
var y = [ ...new Set([ ...[1, 2, 3, 4, 5], ...[3, 4, 5] ]) ]
// expected output: [ 1, 2, 3, 4, 5 ]
Use the output to bind to the dropdown list.
Do it with dual for loop using pure js
Simple and easy way with select remove method
function clearList() {
var x = document.getElementById("locationList");
//count the lenth of select optons
var listLength = x.length;
for (var i = 0; i < listLength; i++) {
for (var j = 0; j < listLength; j++) {
//i != j This prevents the actual index from being deleted
//x.options[i].value == x.options[j].value => it finds the duplicate index.
if (x.options[i].value == x.options[j].value && i != j) {
//Remove duplicate option element
x.remove(j);
//Refresh the list Length
listLength--;
}
}
}
}
<select id="locationList">
<option value="1">Andover</option>
<option value="2">Bishops waltham</option>
<option value="1">Andover</option>
<option value="3">Boscombe</option>
<option value="4">Bournemouth</option>
<option value="2">Bishops waltham</option>
<option value="4">Bournemouth</option>
</select>
<p>Click to remove duplicates</p>
<button onclick="clearList()">Remove</button>
Related
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>
Im trying to trigger options for a select from another select.
Now I want to check if my options contains the exact value of ex "5" and not also choose "15" and "25" as it does today, because both 15 (1->5<-) and 25 (2->5<--) contains 5 aswell..
console.log(height); // e.g 5, 10, 15, 25, 30
if($('#pa_height').children('option').filter(':contains("'+height+'")')) {
var option = height + 'cm-' + (typeof closestPrice[1] !== 'undefined' ? closestPrice[1] : closestPrice[0]) + 'kr';
console.log('option exists', option);
// some of my options gives me 1 here and other 0
console.log($('#pa_hojd').children('option[value="'+option+'"]').length);
.if($('#pa_height').children('option[value="'+option+'"]').length !== 0) {
$('#pa_height').children('option[value="'+option+'"]').attr('selected', 'selected').siblings().removeAttr('selected').trigger('change');
}
else {
$('#pa_height').children('option').filter(':contains("'+height+'")').last().attr('selected', 'selected').siblings().removeAttr('selected').trigger('change');
console.log('Highest price for this height is set, Price is: ', price);
}
} else {
console.log('Height is not set');
}
These options is custom variations in woocommerce that i've made to set the price of a product depending on how much text you write in a textarea.
Some of my options.length returns 0, even though I can see them in the select. It's like woocommerce don't understand that they are options.
Does anyone know something that can help me? :)
Here is a screenshot
this is the HTML for my variations-select
<select id="pa_height" class="" name="attribute_pa_hojd" data-attribute_name="attribute_pa_hojd">
<option value="">Välj ett alternativ</option>
<option value="5cm-79kr">5cm: 79kr</option>
<option value="5cm-99kr">5cm: 99kr</option>
<option value="5cm-199kr" selected="selected">5cm: 199kr</option>
<option value="5cm-299kr">5cm: 299kr</option>
<option value="5cm-399kr">5cm: 399kr</option>
<option value="5cm-499kr">5cm: 499kr</option>
<option value="10cm-149kr">10cm: 149kr</option>
<option value="10cm-199kr">10cm: 199kr</option>
<option value="10cm-299kr">10cm: 299kr</option>
<option value="10cm-399kr">10cm: 399kr</option>
<option value="10cm-499kr">10cm: 499kr</option>
<option value="10cm-99kr">10cm: 99kr</option>
<option value="15cm-129kr">15cm: 129kr</option>
<option value="15cm-149kr">15cm: 149kr</option>
<option value="15cm-249kr">15cm: 249kr</option>
<option value="15cm-349kr">15cm: 349kr</option>
<option value="15cm-449kr">15cm: 449kr</option>
<option value="15cm-599kr">15cm: 599kr</option>
<option value="20cm-150kr">20cm: 150kr</option>
<option value="20cm-200kr">20cm: 200kr</option>
<option value="20cm-250kr">20cm: 250kr</option>
<option value="20cm-350kr">20cm: 350kr</option>
<option value="25cm-450kr">25cm: 450kr</option>
<option value="25cm-550kr">25cm: 550kr</option>
<option value="25cm-700kr">25cm: 700kr</option>
<option value="25cm-900kr">25cm: 900kr</option>
<option value="30cm-1000kr">30cm: 1000kr</option>
<option value="30cm-150kr">30cm: 150kr</option>
<option value="30cm-200kr">30cm: 200kr</option>
<option value="30cm-250kr">30cm: 250kr</option>
<option value="30cm-350kr">30cm: 350kr</option>
<option value="30cm-550kr">30cm: 550kr</option>
<option value="30cm-750kr">30cm: 750kr</option>
<option value="30cm-850kr">30cm: 850kr</option>
</select>
You can rule out 15 / 25 / 35 etc by restricting your search to 1 character long strings. Then by looking for the number 5, you should get your expected results. E.g;
var options = document.getElementsByTagName('option');
for(var i = 0; i < options.length; i++){
var option_value = options[i].value;
var search_value 5;
if(options_value.length < 1){
// String length = 0(1). This rules out double or triple digit numbers
if(options_value.indexOf(search_value) > -1){
// Found the value 5
console.log('Success!');
}
}
}
Update
Now that I've seen your HTML (after your edit), the above probably won't work. You may be able to modify the method to check if '5' is the first character. If it is, check if it is followed by another number. If it is not, then you've found your number 5.
var options = document.getElementsByTagName('option');
for(var i = 0; i < options.length; i++){
var option_value = options[i].value();
var first_char = option_value.charAt(0);
if(first_char == 5){
// first char = 5, check second
var second_char = option_value.charAt(1);
if(isNaN(second_char)){
// value is not 5
}else{
// not a number, found 5
// do code
}
}
}
if($("#pa_height option[value='"+height+"']").length>0) {
//
}
How is it possible to change the numbers in within the option tag with JS?
<select name="resunit">
<option value="res_0">R1 (18768194)</option>
<option value="res_1">R2 (44507354)</option>
<option value="res_2">R3 (15217874)</option>
<option value="unit_1">U1 (3047)</option>
<option value="unit_2">U2 (10)</option>
<option value="unit_3">U3 (60)</option>
</select>
e.g.
<option value="res_0">R1 (18768194)</option>
to
<option value="res_0">R1 (10)</option>
Not quite sure what you're asking, but have a look:
var select = document.getElementsByName("resunit")[0];
for (var i = 0; i < select.length; i++) {
if (select[i].value === "res_0") {
select[i].innerHTML = "R1 (10)";
} else if (select[i].value === "res_1") {
select[i].innerHTML = "R2 (12)";
}
}
The select element is not bound as expected.
html:
<select ng-model="SelectedPage"
ng-change="ShowPageResult();" ng-options="o for o in PageNumbers">
</select>
ctrl.js:
function BindPageNumbers() {
$scope.PageNumbers = [];
for (var i = 1; i <= 2) ; i++) {
$scope.PageNumbers.push(i);
}
}
output:
<option value="0"label="1">1</option>
<option value="1" label="2">2</option>
if i put $scope.PageNumbers.push(i.toString());, then the output is
<option value="?"label=""></option>
<option value="0" label="1">1</option>
<option value="1" label="2">2</option>
expected:
<option value="1">1</option>
<option value="2">2</option>
what should be done to get the desired o/p : http://jsfiddle.net/s222904f/
In your controller:
$scope.PageNumbers = [];
for (var i = 1; i <= 2 ; i++) {
$scope.PageNumbers.push({ id: i, value: i });
}
In your view:
<select ng-model="SelectedPage"
ng-options="o.id for o in PageNumbers track by o.value"></select>
Check it: http://jsfiddle.net/khwuv4Lj/
Per the answer here, the empty option exists because the
ng-model="SelectedPage"
line binds it to an empty string. You can avoid this by setting the default value if the select in the scope.
Edit: Plnkr was updated to fix the OP's comment.
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]);
}