Reputation: 5151
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.
Upvotes: 0
Views: 2141
Reputation: 26161
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>
Upvotes: 1
Reputation: 50291
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);
Upvotes: 1
Reputation: 122027
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>
Upvotes: 1