I fill a combobox via Javascript as follows:
let option = document.createElement("option");
option.innerHTML = elem.businessObject.get('id');
option.value = elem.businessObject.get('id');
taskTypeEl.appendChild(option);
whereby taskTypeE1 refers to the select - tag from my html-code
but unfortunately, I fill my combobox with a lot of duplicates. Is there an easy way
to get rid of that, such that every item only appears once?
Thanks in advance and kind regards
You can define a dictionary before starting the insertion of options, and only add the ones with the values that were not added before:
let dictionary = {}; //initiate
So when iterating to add the options, you can check if it is unique like this:
if(!dictionary[elem.businessObject.get('id')]){ //check for prev insertion
let option = document.createElement("option");
option.innerHTML = elem.businessObject.get('id');
option.value = elem.businessObject.get('id');
taskTypeEl.appendChild(option);
dictionary[elem.businessObject.get('id')] = option; //add option
}
Related
I try to make dynamically multiple input with dropdown list,
My select list is using viewbag and the result is always undefined.
The Viewbag List
private void ToolCategories(object selectedcat = null)
{
var catQuery = from d in db.Toolcategories
where d.In == "AD"
orderby d.CategoryName
select d;
SelectList ToolCategories = new SelectList(catQuery, "CategoryId", "CategoryName", selectedcat);
ViewBag.ToolCategories = ToolCategories;
}
The View
#using System.Text.Json;
<script>
var resin = document.createElement("div");
resin.setAttribute("class", "col-md-4");
var resinGrup = document.createElement("div");
resinGrup.setAttribute("class", "form-grup");
var resinLabel = document.createElement("label");
resinLabel.setAttribute("class", "form-label fs-6");
resinLabel.innerHTML = "Tool";
var jsonObj = #Html.Raw(JsonSerializer.Serialize(ViewBag.ToolCategories));
var resinSelect = document.createElement("select");
resinSelect.setAttribute("id", "CategoryId");
resinSelect.setAttribute("class", "form-control");
resinSelect.setAttribute("required", "");
resinSelect.setAttribute("name", `[${toolID}].ToolCategories`);
$.each(jsonObj, function (index, ToolCategories) {
var option = document.createElement("option");
option.value = ToolCategories.CategoryId;
option.text = ToolCategories.CategoryName;
resinSelect.append(option);
})
</script>
My select list is using viewbag and the result is always undefined.
Well, your undefined dropdown is pretty obvious because you have used SelectList which keeps data as Text and Value pairs. Thus, you are binding it within your $.each loop as CategoryId andCategoryName but the items is not residing there as it is. As you can see below:
Solution:
You need to modify your option binding as option.value = ToolCategories.Value; instead of ToolCategories.CategoryId;
Thereofore, complete code would be:
$.each(jsonObj, function (index, ToolCategories) {
console.log(ToolCategories);
var option = document.createElement("option");
option.value = ToolCategories.Value;
option.text = ToolCategories.Text;
resinSelect.append(option);
});
Output:
Note: If you still need further details on it, please have a look on our official document here.
Seems everything looks fine except below 2 lines, in your view file.. Replace your Category Id with Value and CategoryName with Text.
option.value = ToolCategories.Value;
option.text = ToolCategories.Text;
You are getting undefined as it failed to find values but required values mapped to different properties.
listCities.forEach(function(city){
let option = document.createElement('option');
option.value = city;
listFrom.appendChild(option);
listTo.appendChild(option);
});
I have an array and I want to add each string in it as options to two datalists (listFrom and listTo). The problem is that no matter the order I put them, only the last one of the list gets the options added to them.
Is there a way to do this in the same forEach loop or do I have to create two different loops that do exactly the same thing.
I'm just having trouble understanding the logic behind it.
When you appendChild, you MOVE the element to the last mentioned container since the element only exists once in the DOM.
This is a LOT faster than creating an option, cloning it and appending it twice:
const listCities = ["Buenos Aires","Cordoba","Rosario","Mendoza","La Plata","Tucumán","Mar del Plata","Salta","Santa Fe","San Juan","Resistencia","Santiago del Estero","Corrientes","Neuquén","Posadas","San Salvador de Jujuy","Bahía Blanca","Paraná","Formosa","San Fernando del Valle de Catamarca","San Luis","La Rioja","Comodoro Rivadavia","Río Cuarto"],
listFrom = document.getElementById("from"),
listTo = document.getElementById("to");
const options = listCities
.map(city => `<option value="${city}">${city}</option>`)
.join("");
listFrom.innerHTML += options;
listTo.innerHTML += options;
<select id="from"><option value="">From city</option></select> <select id="to"><option value="">To city</option></select>
An element can only exist in one place. You need to make a clone of it
const listFrom = document.querySelector('#from');
const listTo = document.querySelector('#to');
listCities = ["a","b","c","d"];
listCities.forEach(function(city){
let option = document.createElement('option');
option.textContent = city;
option.value = city;
listFrom.appendChild(option);
listTo.appendChild(option.cloneNode(true));
});
<label for="from">From:</label><select id="from"></select>
<label for="to">To:</label><select id="to"></select>
Suppose there is a select menu like this:"
<select id="dropDown"></select>
And I wish to populate it with an array value ["apple","mango","banana"];
How can this be achieved at one go without using any looping construct?
Here you can do like
var arr = ["apple", "mango", "banana"];
document.getElementById('dropdown').innerHTML =
'<option>' + arr.join('</option><option>') + '</option>';
JSFiddle
Without the use of a loop, you would do something like this:
var x = document.getElementById("dropDown");
var option = document.createElement("option");
option.innerHTML = "apple";
x.appendChild(option);
option = document.createElement("option");
option.innerHTML = "mango";
x.appendChild(option);
option = document.createElement("option");
option.innerHTML = "banana";
x.appendChild(option);
Obviously this assumes you know what the array values are going to be ahead of time. The most common way of doing this however would be to use a loop to iterate over the array.
If you just mean not using looping construct like for/while:
document.getElementById('dropDown').innerHTML = ["apple","mango","banana"].map(function(e) {
return "<option>"+e+"</option>";
}).join('');
The demo.
You'll want to do this:
var options = ["apple","mango","banana"],
select = document.getElementById('dropDown');
for(var i = 0; i < options.length; i++){
var option = document.createElement("option");
option.value = option.innerHTML = options[i];
select.appendChild(option);
}
The "No loops" requirement is really a bad idea. This is the most efficient way to build the list, in native JS. (Aside from micro optimizations in the loop)
It also doesn't use innerHTML on DOM elements that are rendered already, avoiding the need for the browser to re-structure the entire DOM.
I have a simple question. I have a select list like this:
var myarray = ["one", "two", "three"];
var container = document.createElement("select");
for (var i = 0; i < myarray.length; i++) {
var element = document.createElement("option");
var textlabel = document.createTextNode(myarray[i]);
if (element.nodeValue == "two") {
element.selected = true;
}
element.appendChild(textlabel);
container.appendChild(element);
}
document.body.appendChild(container);
I have two questions about it:
1) I am pretty sure that the element that should be selected right now is "two"... isn't it?
2) Since the option elements are being created dinamically inside a loop (there are no three different option variables for me to play with, but just one that gets renewed as the loop goes forward), how do I reference the selected one for future uses?
For example, imagine that later on I get user input, and according to that input I want that this list has as a selected item, "three".
Thank you for any help! Here is the fiddle if you want to use it...
1) I am pretty sure that the element that should be selected right now
is "two"... isn't it?
No, it's not: you check element.nodeValue, while in fact you should've been checking textLabel's one - or just the content itself:
if (myarray[i] === 'two') {
element.selected = true;
}
2) Since the option elements are being created dinamically inside a
loop (there are no three different option variables for me to play
with, but just one that gets renewed as the loop goes forward), how do
I reference the selected one for future uses?
See, <select> elements has two useful properties: options (which contains all the options in it, and is updated dynamically) and selectedIndex. You can combine them to get the selected option:
container.addEventListener('change', function() {
console.log(this.options[this.selectedIndex]);
}, false);
But if what you want is to know the value of selected element, that's even easier - with container.value.
For example, imagine that later on I get user input, and according to
that input I want that this list has as a selected item, "three".
That's piece of cake if you know the position of the option that corresponds to this: just use selectedIndex property again:
container.selectedIndex = 3;
Just change the following in the for loop to fix the selection problem:
if (myarray[i] == "two")
Try to use console.log (on chrome or firefox with firebug) to debug your script :
Try this :
var myarray = ["one", "two", "three"];
var container = document.createElement("select");
container.id = "mySelect" ;
for (var i = 0; i < myarray.length; i++) {
var element = document.createElement("option");
var textlabel = document.createTextNode(myarray[i]);
element.appendChild(textlabel);
if (element.value == "two") {
element.selected = true;
}
container.appendChild(element);
}
document.body.appendChild(container);
in order to refer to your selected element you should give your select element an id and access to it like below:
el = document.getElementById('mySelect');
el.selectedIndex ; // give you the selected index
el.options[el.selectedIndex]; // give you the value
I have a text file which I am reading and storing the data in a javascript array, it's a list of cuisines. I want to use the array to fill up a drop down select box. I know how to hard code in the values for the drop down box (using correct me if i'm wrong) but I want to be able to use the array to fill it up instead.
<script type="text/javascript">
var cuisines = ["Chinese","Indian"];
</script>
<select id="CusineList"></select>
I have hard coded an array for simplicity, the "CuisineList" is my drop down box
Use a for loop to iterate through your array. For each string, create a new option element, assign the string as its innerHTML and value, and then append it to the select element.
var cuisines = ["Chinese","Indian"];
var sel = document.getElementById('CuisineList');
for(var i = 0; i < cuisines.length; i++) {
var opt = document.createElement('option');
opt.innerHTML = cuisines[i];
opt.value = cuisines[i];
sel.appendChild(opt);
}
DEMO
UPDATE: Using createDocumentFragment and forEach
If you have a very large list of elements that you want to append to a document, it can be non-performant to append each new element individually. The DocumentFragment acts as a light weight document object that can be used to collect elements. Once all your elements are ready, you can execute a single appendChild operation so that the DOM only updates once, instead of n times.
var cuisines = ["Chinese","Indian"];
var sel = document.getElementById('CuisineList');
var fragment = document.createDocumentFragment();
cuisines.forEach(function(cuisine, index) {
var opt = document.createElement('option');
opt.innerHTML = cuisine;
opt.value = cuisine;
fragment.appendChild(opt);
});
sel.appendChild(fragment);
DEMO
This is a part from a REST-Service I´ve written recently.
var select = $("#productSelect")
for (var prop in data) {
var option = document.createElement('option');
option.innerHTML = data[prop].ProduktName
option.value = data[prop].ProduktName;
select.append(option)
}
The reason why im posting this is because appendChild() wasn´t working in my case so I decided to put up another possibility that works aswell.