Dynamically add options to option group at particular location - javascript

I have a small query. I would like to have a HTML select in my page having structure:
<select id="selectedFormulae">
<option value="0" disabled="" selected="">select</option>
<optgroup label="Box1">
<option value="1">Formula1</option>
<option value="2">Formula2</option>
</optgroup>
<optgroup label="Box2?">
<option value="1">Formula1</option>
<option value="2">Formula2</option>
<option value="3">Formula3</option>
</optgroup>
<optgroup label="Marital status?">
<option value="1">Formula1</option>
</optgroup>
</select>
The options of the select will be added as per what user adds in his computations. My question here is how do I add particular option under particular option group? ie. if user adds another value under box1 then new option should be added under <optgroup label="Box1"> like this:
<optgroup label="Box1">
<option value="1">Formula1</option>
<option value="2">Formula2</option>
<option value="3">Formula3</option>
</optgroup>
Same way if user deleted some value say Formula2 of Box1 then it will have only this:
<optgroup label="Box1">
<option value="1">Formula1</option>
<option value="3">Formula2</option>
</optgroup>
I was planning to save all the options in JSON object and then modifying the select html as per what user adds in. Any help with this?
I tried adding it to jsonobject like this:
var opt = {
Box1:[
{name:"Formula1"},
{name:"Formula2"}
],
Box2:[
{name:"Formula1"},
{name:"Formula2"}
],
Box3:[
{name:"Formula1"},
{name:"Formula2"}
]
};

Try this: you can use jQuery attribute selector to find a particular option group and append new option to it
$("#selectedFormulae").find('optgroup[label="Box1"]').append('<option>New option</option>');
Here option group with label="Box1" get selected and user can append new option to it, similarly, user can delete option using below code
$("#selectedFormulae").find('optgroup[label="Box1"]').find('option').filter(function(){
var text = $(this).text();
return text=='New option';
}).remove();
EDIT - to know if an option exists already, use below code
var $optionGroup = $("#selectedFormulae").find('optgroup[label="Box1"]');
var optionLength = $optionGroup.find('option').filter(function(){
return $(this).text() == "New option";
);
if(optionLength.length < 1) //option does not exist
{
$optionGroup.append('<option>New option</option>');
}

it can be achieve by your jsonobject :
var opt = {
Box1:[
{name:"Formula1"},
{name:"Formula2"}
],
Box2:[
{name:"Formula1"},
{name:"Formula2"}
],
Box3:[
{name:"Formula1"},
{name:"Formula2"}
]
};
$(function(){
var $select = $('#mySelect');
$.each(opt, function(key, value){
var group = $('<optgroup label="' + key + '" />');
$.each(value, function(){
$('<option />').html(this.name).appendTo(group);
});
group.appendTo($select);
});
});
here the fiddle http://jsfiddle.net/ZP4E9/29/

Related

Multiple select get Selected options in order selected

i have a multiple select like the following
<select name="cars" id="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
that i have implemented chosen plugin on i have an onchange listener that adds selected elements to an array like so
$("#cars").change(function () {
var selected = [];
for (var option of document.getElementById('cars').options) {
if (option.selected) {
selected.push(option.value);
}
}
console.log(selected);
});
however in which ever option i select the items they always end up arranging themselves in the order they are in the multiple select
for example by selecting the values Volvo , Audi, Saab in that order results in the following array
Array [ "Volvo" ]
Array [ "Volvo", "Audi" ]
Array(3) [ "Volvo", "Saab", "Audi" ]
Is there a way that i can add elements in a multiple select to an array in the order which they were selected?
You always get the same order of the selected array because you create it each time you run your onChange function. So the solution would be to make it a global variable. When you do that, your array won't be empty at the second choice tho, so you have to take care of removing items from it.
Here's some code
var selected = [];
$("#cars").change(function () {
for (var option of document.getElementById('cars').options) {
var value = option.value;
if (option.selected) {
if(selected.indexOf(value) < 0){//we only add element if it's not present in the array
selected.push(value);
}
}else{
if(selected.indexOf(value) >= 0){ //we only remove item if it is present
selected.splice(selected.indexOf(value),1)
}
}
}
console.log(selected);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name="cars" id="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>

How to call onchange event when dropdown values are same

I am using Jquery chosen plugin and it's working fine. I have used this plugin in my one of the module. My dropdown values are something like that:
<select id="itemcode" onchange="get_data()">
<option value="1">ITEM001</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001</option>
<option value="3">ITEM003</option>
</select>
It's working fine. But problem is that when user select first option and then try to change third option onchange event does not fire because both options values are same. Is there any way to call onchange event every time if values are same or differ ?
Options values is a unique key of item so it's repeated in dropdown. Dropdown value is duplicate we have allowed to use same item in others module
I saw your implementation and it is working fine in code pen here is the link no need to change anything
<select id="itemcode" onchange="get_data()">
<option value="1">ITEM001</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001</option>
<option value="3">ITEM003</option>
</select>
var get_data =function(){
alert("saas")
}
http://codepen.io/vkvicky-vasudev/pen/dXXVzN
Try this
$('#itemcode').click(function() {
console.log($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="itemcode">
<option value="1">ITEM001-A</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001-B</option>
<option value="3">ITEM003</option>
</select>
Edit: This doesn't work. Sorry!
You could add a data attribute that differs for each element, for example:
<select id="itemcode" onchange="get_data()">
<option value="1" data-id="1">ITEM001</option>
<option value="2" data-id="2">ITEM002</option>
<option value="1" data-id="3">ITEM001</option>
<option value="3" data-id="4">ITEM003</option>
</select>
If you're using Rails or another framework to generate the <option> tags, it should be easy to add an incremental id to each element.
There is no way to fire get_data() with your current data.
The solution below is more of a hack. When you populate the options, prepend the value with something unique.
Eg.
<select id="itemcode" onchange="get_data()">
<option value="1_1">ITEM001</option>
<option value="2_2">ITEM002</option>
<option value="3_1">ITEM001</option>
<option value="4_3">ITEM003</option>
</select>
Thus your get_data() method will be called everytime. And in your get_data() method, split the value using underscore _ and you can get the actual value there.
function get_data(){
var actualValue=$(this).val().split("_")[1];
//do other processing
...
}
You can use other characters like $, or anything you like, instead of _
Ideally you want to change the data coming from the backend so that you don't get duplicate data. However if this is not possible, another approach would be to sanitise the data before putting it in the select. E.g
https://jsfiddle.net/vuks2bpt/
var dataFromBackend = [
{key:1,
value: "ITEM0001"
},
{key:2,
value: "ITEM0002"
},
{key:1,
value: "ITEM0001"
},
{key:3,
value: "ITEM0003"
}
];
function removeDuplicates(array){
var o = {};
array.forEach(function(item){
o[item.key] = item.value;
});
return o;
}
function get_data(){
console.log('get_data');
}
var sanitised = removeDuplicates(dataFromBackend);
var select = document.createElement('select');
select.id = "itemcode";
select.addEventListener('change', get_data);
Object.keys(sanitised).forEach(function(key){
var option = document.createElement('option');
option.value = key;
option.textContent = sanitised[key];
select.appendChild(option);
})
document.getElementById('container').appendChild(select);
i am using jquery instead of java script
<select id="itemcode">
<option value="1">ITEM001</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001</option>
<option value="3">ITEM003</option>
</select>
jquery
$('#itemcode:option').on("click",function(){
alert(saaas);
})

JQuery Set Option in Opt Group

I'm trying to figure out how to set an option inside of a optgroup using JQuery and I can't seem to figure it out.
I have a hidden field on the page that contains the following value 4-2014. On ready I would like to read the hidden value and set the selected option.
html:
<select name="dropdownlist" id="dropdownlist">
<option value="All">All</option>
<optgroup label="2013" id="2013">
<option value="7">July</option>
<option value="4">April</option>
</optgroup>
<optgroup label="2014" id="2014">
<option value="4">April</option>
<option value="3">March</option>
</optgroup>
Jquery:
$(document).ready(function() {
//set the dropdown selected item.
var varDropdownvalue = $("input[id$=Dropdownvalue]").val();
var monthyear = varDropdownvalue.split('-');
$('#dropdownlist #'+monthyear[1]+' option[value='+monthyear[0]+']').prop("selected", true);
$('#dropdownlist').change(function () {
//get the optgroup label and value of selected option.
var label = $(this.options[this.selectedIndex]).closest('optgroup').prop('label');
var value = $(this).find("option:selected").val();
alert(value+'-'+label);
});
});
Here is a fiddle: jsfiddle
Try
$('#dropdownlist').val(monthyear[0]).change();
http://jsfiddle.net/LPAFD/1/
Field:
<input type="hidden" id="hidden_select" value="4-2014" />
JS:
var hidden = $("#hidden_select").val().split("-");
var month = hidden[0];
var year = hidden[1];
var list = $("#dropdownlist");
var theOption = list.find('optgroup#'+year+' option[value="'+month+'"]').val();
list.val(theOption).change();

Replace Select Box Options With JSON Result

I have a select box, and when I click on a button, an ajax request is made, and it returns json object the object contains a new list of options for the select box. Is there any way that I can remove all the options from the select box and replace them with the new list?
<select id="cat-0" >
<option value="0">Select One...</option>
<option value="1">Text 1</option>
<option value="2">Text 2</option>
<option value="3">Text 3</option>
</select>
Use .html() to insert new options clearing the existing ones.
$('#cat-0').html(newOptions);
But of course you need to construct options from your JSON Data something like this.
var json=[{value:'1', text:'Option1'},
{value:'2', text:'Option2'},
{value:'3', text:'Option3'}];
var options=$('<select/>');
$.each(json, function(id, ob){
options.append($('<option>',
{value:ob.value,
text:ob.text}));
});
$('#cat-0').html(options.html());
Fiddle
//Clear the select list
$('#cat-0').empty();
//then fill it with data from json post
$.each(data, function(key, value) {
$('#cat-0')
.append($("<option></option>")
.attr("value",key)
.text(value));
}

Playing with selects and javascript

My code is:
<select name='main'>
<option>Animals</option>
<option>Food</option>
<option>Cars</option>
</select>
<select name='other'>
<option>Rats</option>
<option>Cats</option>
<option>Oranges</option>
<option>Audi</option>
</select>
How can I filter my second <select>, so it would only show items which I want eg. if I choose Animals, my select would be:
<select name='other'>
<option>Rats</option>
<option>Cats</option>
</select>
and if I choose "Food", my <select> would look like:
<select name='other'>
<option>Oranges</option>
</select>
Well, I hope you get the idea. Thanks.
You'd need to create some kind of association between the selects, I'd recommend using the data-* attribute:
<select id="main_select" name='main'>
<option>Animals</option>
<option>Food</option>
<option>Cars</option>
</select>
<select id="other_select" name='other'>
<option data-category="Animals">Rats</option>
<option data-category="Animals">Cats</option>
<option data-category="Food">Oranges</option>
<option data-category="Cars">Audi</option>
</select>
Once that's in place for all of the <option> elements, the JavaScript code would look something like this:
EDITED, this works:
$(function() {
var cloned = $('#other_select option').clone();
$('#main_select').change(function() {
var selectedCategory = $(':selected', this).text();
var filtered = $(cloned).filter("[data-category='" + selectedCategory + "']");
$("#other_select option").replaceWith(filtered);
});
$('#main_select').change(); //fire the event initially.
});
jsFiddle example
You could add a change event handler to the main select box that then branches on which option was selected and then dynamically adds options to the other select. The following assumes a select with id main and id other:
HTML:
<select name="main" id="main">
<option value="1">Cars</option>
<option value="2">Food</option>
<option value="3">Animals</option>
</select>
<!-- Default the other select to 'cars' -->
<select name="other" id="other">
<option value="Audi">Audi</option>
</select>
JavaScript:
$("#main").bind("change", function() {
var categories = $("#other").get(0);
categories.options.length = 0;
switch (this.value) {
case "1":
categories.options[0] = new Option("Audi", "Audi");
break;
case "2":
categories.options[0] = new Option("Oranges", "Oranges");
break;
case "3":
categories.options[0] = new Option("Rats", "Rats");
categories.options[1] = new Option("Cats", "Cats");
break;
}
});
Check out an example here: http://jsfiddle.net/andrewwhitaker/nRGC9/
The naive solution would be:
$('select [name=main]').change(function(){
var other = $('select [name=other] option');
switch($(this).val()){
case 'Animals':
other.each(function () { if (!isAnimal($(this).val()))
$(this).hide();
else
$(this).show();
});
//where isAnimal is a function that accepts a string parameter and checks whether its an animal or not
break;
case 'food':
//continue in the same manner......
}});

Categories