Populate Select With OptGroup From Two Seperate JSon Objects JQuery - javascript

I have two json objects
var type = [{"Id":1,"Name":"This is a name"}];
var subType = [{"Id":2,"ParentId":1,"Name":"This is a name"},];
subType.ParentId references the type.Id
I want to be able to populate a select in jQuery having
<SELECT>
<OPTGROUP LABEL="type.Name" id="type.Id">
<OPTION LABEL="subType.Name" value="subType.Id">subType.Name</OPTION>
</OPTGROUP>
</SELECT>

The code below uses just "select" as a jquery selector, so it will affect all selectboxes on the page.
You probably want to change this.
The code below also does not handle having one of the options selected which is probably something you should watch out for.
var type = [{"Id":1,"Name":"This is a name"}];
var subType = [{"Id":2,"ParentId":1,"Name":"This is a name"}];
var output = [];
$.each(type, function(){
//for each type add an optgroup
output.push('<optgroup label="'+this.Name+'">');
var curId = this.Id;
//linear search subTypes array for matching ParentId
$.each(subType, function(k,v){
if( this.ParentId = curId ){
output.push('<option label="'+this.Name +'" value="'+ this.Id +'">'+ this.Name +'</option>');
//DELETE the element from subType array so the next search takes less time
subType.splice(k,1);
}
});
output.push('</optgroup>');
});
//change the 'select' here to the id of your selectbox
$('select').html(output.join(''));

Adding optgroups to select using javascript dynamically
You able criate dinamamicaly the combo. Access The values of json is In this question.
How to access Json Object which has space in its name?
Have some situations in posts to resolve your question.

Related

html select list - get text value by passing in a variable?

I have a select list that displays a list languages.
<select name="language_code" id="id_language_code">
<option value="ar">Arabic - العربية</option>
<option value="bg">Bulgarian - Български</option>
<option value="zh-CN">Chinese (Simplified) - 中文 (简体)‎</option>
<option value="en" selected="selected">English (US)</option>
<option value="fr-CA">French (Canada) - français (Canada)‎</option>
</select>
I am able to get the text value of the selected value using the following code [returns English (US) from the above select list]:
$('#id_language_code option:selected').text()
How can I get the text value if I pass the option value of 'bg' as a variable when the selected value is still English (US)?
This means that the value returned would be "Bulgarian - Български" when the selected value is still "English (US)".
I have searched Google and SO for an answer, but was unable to find one, so I am thinking that this is not as easy as I 1st thought it was!
Here is an example of how you can use CSS selectors to query the value attribute:
function getOptionTextByValue(value) {
return $('#id_language_code option[value=' + value + ']').text();
}
var bgText = getOptionTextByValue('bg');
Here is a working example
http://plnkr.co/edit/SQ48SmoQkSUgDpQ5BNAx?p=preview
You have some data, and you have the view of this data (html/dom), but it's best if you go data -> view, rather than view -> data.
For example, say you have this array:
var languages = [
{short: "ar", text: "Arabic - العربية"},
{short: "bg", text: "Bulgarian - Български"},
{short: "en", value: "English (US)"}
];
Now you can look things up, for example, "what is the text for the abbreviation 'bg'?"
languages.filter(function(x){ return x.short === 'bg' })[0].text;
Or create DOM nodes from it:
function option(x){
var el = document.createElement('option');
el.value = x.short; el.textContent = el.text;
return el;
}
function select(options){
var el = document.createElement('select');
options.forEach(function(x){ el.appendChild(x); });
return el;
}
var element = select(languages.map(option));
element.id = 'id_language_code';
Hmm, if I understand correctly, you want to retrieve the label associated with a given value of one of the options of the <select> element, which will not necessarily be the currently selected option. Using pure JavaScript approach (aka. No jQuery, since there's already a nice one provided by someone else):
function getOptionLabel(selectId, optionValue){
// Get select element and all options
var sel = document.getElementById(selectId);
var selOpts = sel.options;
// Cycle through each option to compare its value to the desired one
for(var i = 0; i < selOpts.length; i++){
if (selOpts[i].value == optionValue){
return selOpts[i].label;
}
}
// Default return value
return "Option not found.";
}
To get the Bulgarian option from a <select> of the given id, you could call it like so:
getSelectLabel("id_language_code", "bg");
Here's a JSFiddle to demonstrate. Hope this helps! Let me know if you have any questions.

form element index in javascript for use in jquery .change function

I need to get an index of a form element that is passed in to a .change statement.
example HTML form code
<tr><td>Question1</td><td><select class=list1 id=l[1] name=l[1]><option value=1>1<option value=2> 2 <option value=3> 3 </select></td><td><select class=hideme name=x[1] id=x[1]></select></td></tr>
<tr><td>Question2</td><td><select class=list1 id=l[1] name=l[2]><option value=1>1<option value=2> 2 <option value=3> 3 </select></td><td><select class=hideme name=x[2] id=x[2]></select></td></tr>
<tr><td>Question3</td><td><select class=list1 id=l[3] name=l[3]><option value=1>1<option value=2> 2 <option value=3> 3 </select></td><td><select class=hideme name=x[3] id=x[3]></select></td></tr>
Now the user will select 1, 2 or 3 from the first pulldown. based on that selection the second pulldown will be loaded with content.
example javascipt jquery function
$('.list1').change (function ()
{
// here is where I need to pick up the index ie: the [1] [2] or [3] as var id
var selected = $("#l[id] option:selected");
var pdata = 'subjectareaid='+selected.val();
$.ajax({
type : "POST",
cache : false,
url : "subcat.php",
data : pdata,
success: function(data) {
$('#x[id]').html(data);
$('#x[id]').removeClass('hideme');
}
});
});
This will allow me to populate the second pulldown with the options that were returned by the ajax call based on the selection from the first pulldown.
The table has 54 pulldowns that all have to have this action taken against them (this is to populate a mysql table upon form submission) the pulldowns are (l[id]) primary category (x[id]) sub-category. The subcat selection is hidden until after the main cat is picked and then the select statement is populated.
First of all add double qoutes arround your attributes ", this is best practice and will prevent errors if you use spaces in your values. Also make sure your html is valid. You didn't close the <option> tags with a </option>.
You can use a simple regex to get the index of your select element.
$('.list1').change (function () {
var id = $(this).attr('id');
var matches = id.match(/^l\[([0-9]{1,})\]/);
if (matches) {
var index = matches[1];
}
});
You can get the select element changed at the moment with $(this) instead of var selected = $("#l[id] option:selected");
You can reach the index of the changing select by reaching index of parent tr element of that select element by using closest() selector of jQuery.
Finally the code block you need, should be like that:
var selected = $(this);
var selectedIndex = selected.closest("tr").index();
var pdata = 'subjectareaid='+selected.val()+"&index="+selectedIndex;

Jquery append html element to div after for loop, strange behaviour

Here is the code:
$('#date').append(
'<select id="date">'+
'<option value="0">- - SELECT - -</option>');
for(var i in data){
$('#date').append(
'<option value="">'+data[i]['date_time']+'</option>');
});
$('#date').append('</select>');
</select> is always added above for loop. If i replace it with just work select for example, it is appended at the end, where it should be. Why is this happening and how can i fix it?
I believe that jQuery will generate the DOM like this:
<div id="date">
<select id="date">
<option value="0">- - SELECT - -</option>
</select>
<option value="">foo</option>
<option value="">bar</option>
etc...
</div>
Since it is automatically closing the <select> after the first .append(). What you are doing afterwards is appending the options to the <div id="#date"/> rather than the <select> that was appended. I don't think the final closing </select> will actually do anything either.
If you really want to use append the following JavaScript will add the options to the correct node:
// dummy data object for example
var data = new Array(new Array(), new Array());
data[0].date_time = 2011;
data[1].date_time = 2012;
var options = new Array();
$.each(data, function(index, option) {
options.push('<option value="' + index + '">'+ option.date_time +'</option>');
});
$('<select id="date"/>').append(options.join('')).appendTo('#date');
Assuming the existing HTML:
<div id="date"></div>
However this does incur an overhead since appending is occurring twice. The faster approach is to build up the options markup as already answered by ShankarSangoli
It is not the right way to create html dynamically. You should create the complete markup all at once by putting it into an array and then provide it to jQuery. Try this
var html = [];
html.push('<select id="date">');
html.push('<option value="0">- - SELECT - -</option>');
for(var i in data){
html.push('<option value="">'+data[i]['date_time']+'</option>');
}
html.push('</select>');
//This selector should be some container like dateContainer
//because you have already give date as id to the above select element
$('#dateContainer').html(html.join(''));
$('#date').append($("<select/>", { name: "name"+i})
.find('select')
.append($("<option/>", { value: "abc"+i}).text('cell'))
.append($("<option/>", { value: "abc"+i}).text('home'))
.append($("<option/>", { value: "abc"+i}).text('work'));
all options should wrap inside select
I imagine the base HTML you have looks something like this:
<div id="date"></div>
then after the first $('#date').append('<select id="date">... in your code, you will have this:
<div id="date"><select id="date">...</div>
which is 2 elements with the same ID attribute.
The ID attribute is like the highlanders, there must only be one of them (in each page).
The seccond $('#date').append... works unexpectedly, and the 3rd one, also unexpectedly, doesn't work. Because you can't predict to which #date they are referring.
Also, as the other answers say, it will be better if you build it to do only 1 append, because calling the selectors so many times (especially inside the loop) it's a performance hit.
If you want to do it in your way - create, for example, string variable with html code in it and than append it.
data = [1, 2, 3];
var html = '<select id="date">'+
'<option value="0">- - SELECT - -</option>';
for(var i in data){
html += '<option value="">'+data[i]+'</option>';
}
$('#date').append(html)
or look here
What is the best way to add options to a select from an array with jQuery?
ps: the first append tries to create a valid DOM structure inside of document, closing select tag automatically. that is why the second one will not insert options into the created select.
another possible way, based on the link above, is
var sel = $('<select id="date">');
$.each(data, function(key, value) {
sel.append($('<option>').text(key['date_time']));
});
$('#date').append(sel);

Search a dropdown

I have this HTML dropdown:
<form>
<input type="text" id="realtxt" onkeyup="searchSel()">
<select id="select" name="basic-combo" size="1">
<option value="2821">Something </option>
<option value="2825"> Something </option>
<option value="2842"> Something </option>
<option value="2843"> _Something </option>
<option value="15999"> _Something </option>
</select>
</form>
I need to search trough it using javascript.
This is what I have now:
function searchSel() {
var input=document.getElementById('realtxt').value.toLowerCase();
var output=document.getElementById('basic-combo').options;
for(var i=0;i<output.length;i++) {
var outputvalue = output[i].value;
var output = outputvalue.replace(/^(\s| )+|(\s| )+$/g,"");
if(output.indexOf(input)==0){
output[i].selected=true;
}
if(document.forms[0].realtxt.value==''){
output[0].selected=true;
}
}
}
The code doesn't work, and it's probably not the best.
Can anyone show me how I can search trough the dropdown items and when i hit enter find the one i want, and if i hit enter again give me the next result, using plain javascript?
Here's the fixed code. It searches for the first occurrence only:
function searchSel() {
var input = document.getElementById('realtxt').value;
var list = document.getElementById('select');
var listItems = list.options;
if(input === '')
{
listItems[0].selected = true;
return;
}
for(var i=0;i<list.length;i++) {
var val = list[i].value.toLowerCase();
if(val.indexOf(input) == 0) {
list.selectedIndex = i;
return;
}
}
}
You should not check for empty text outside the for loop.
Also, this code will do partial match i.e. if you type 'A', it will select the option 'Artikkelarkiv' option.
Right of the bat, your code won't work as you're selecting the dropdown wrong:
document.getElementById("basic-combo")
is wrong, as the id is select, while "basic-combo" is the name attribute.
And another thing to note, is that you have two variable named output. Even though they're in different scopes, it might become confusing.
For stuff like this, I'd suggest you use a JavaScript library like jQuery (http://jquery.com) to make DOM interaction easier and cross-browser compatible.
Then, you can select and traverse all the elements from your select like this:
$("#select").each(function() {
var $this = $(this); // Just a shortcut
var value = $this.val(); // The value of the option element
var content = $this.html(); // The text content of the option element
// Process as you wish
});

Keeping key value pairs together in HTML <select/> with jQuery?

Given a select with multiple option's in jQuery.
$select = $("<select></select>");
$select.append("<option>Jason</option>") //Key = 1
.append("<option>John</option>") //Key = 32
.append("<option>Paul</option>") //Key = 423
How should the key be stored and retrieved?
The ID may be an OK place but would not be guaranteed unique if I had multiple select's sharing values (and other scenarios).
Thanks
and in the spirit of TMTOWTDI.
$option = $("<option></option>");
$select = $("<select></select>");
$select.addOption = function(value,text){
$(this).append($("<option/>").val(value).text(text));
};
$select.append($option.val(1).text("Jason").clone())
.append("<option value=32>John</option>")
.append($("<option/>").val(423).text("Paul"))
.addOption("321","Lenny");
Like lucas said the value attribute is what you need. Using your code it would look something like this ( I added an id attribute to the select to make it fit ):
$select = $('<select id="mySelect"></select>');
$select.append('<option value="1">Jason</option>') //Key = 1
.append('<option value="32">John</option>') //Key = 32
.append('<option value="423">Paul</option>') //Key = 423
jQuery lets you get the value using the val() method. Using it on the select tag you get the current selected option's value.
$( '#mySelect' ).val(); //Gets the value for the current selected option
$( '#mySelect > option' ).each( function( index, option ) {
option.val(); //The value for each individual option
} );
Just in case, the .each method loops throught every element the query matched.
The HTML <option> tag has an attribute called "value", where you can store your key.
e.g.:
<option value=1>Jason</option>
I don't know how this will play with jQuery (I don't use it), but I hope this is helpful nonetheless.
If you are using HTML5, you can use a custom data attribute. It would look like this:
$select = $("<select></select>");
$select.append("<option data-key=\"1\">Jason</option>") //Key = 1
.append("<option data-key=\"32\">John</option>") //Key = 32
.append("<option data-key=\"423\">Paul</option>") //Key = 423
Then to get the selected key you could do:
var key = $('select option:selected').attr('data-key');
Or if you are using XHTML, then you can create a custom namespace.
Since you say the keys can repeat, using the value attribute is probably not an option since then you wouldn't be able to tell which of the different options with the same value was selected on the form post.

Categories