I'm trying to do a dropdown using json.
json:
[["a","Apple"],["b", "Berry"]]
JavaScript:
$.ajax({url:'fruit.json'}).done(function(data) {
var items = '<option value="" selected>Select</option>';
$.each(data, function(i, val) {
items += '<option value= "'+val[0]+'" > '+val[1]+' </option>';
});
$('#menu').html(items);
console.log(items); //shows values correctly
});
html:
<script type="text/template" id="menuScriptWrapper">
<select id="menu"></select>
</script>
Why aren't the items being populated in to the drop down menu?
I realized a fiddle following your instructions, skipping ajax layer for simplicity sake (anyway if your console log shows your expected values ajax should be just fine)
Javascript:
var f = function(data) {
console.log(data);
var items = '<option value="" selected>Select</option>';
$.each(data, function(i, val) {
items += '<option value= "'+val[0]+'" > '+val[1]+' </option>';
});
$('#menu').html(items);
console.log(items); //shows values correctly
};
f(([["a","Apple"],["b", "Berry"]]));
HTML
<select id="menu"/>
Fiddle
Everythink seem just fine. I'd say your problem lies somewere else on the page. I'd double check your menu selector... Check also you do not have more than one tags with the id="menu" attribute
Related
I've been using JQuery to populate a drop down list on the click of a HTML select element. The options get created however on the first click the options get shown in a very small box with a scroll. see below
incorrect
If I then close and reopen the dropdown it appears correctly. as below.
correct
It feels like the dropdown list is appearing before jquery has rendered the new options elements. I've tried to find away to re-render it but with no luck.
This feels like it should be such an easy fix but I'm new to scripting and struggling.
HTML
<select class="custom-select" id="templateGroupName" name="templateGroupName">
<option selected>Please Select a group</option>
</select>
JS - Wrapped in document.ready
$('#templateGroupName').click(function () {
$.ajax({
type: "GET",
url: '/Layout/GetGroups',
success: function (data) {
helpers.buildDropdown(
data,
$('#templateGroupName'),
'Select an option'
);
}
});
});
var helpers =
{
buildDropdown: function (result, dropdown, emptyMessage) {
// Remove current options
dropdown.html('');
// Add the empty option with the empty message
dropdown.append('<option value="">' + emptyMessage + '</option>');
// Check result isnt empty
if (result != '') {
// Loop through each of the results and append the option to the dropdown
$.each(result, function (k, v) {
dropdown.append('<option value="' + v.Id + '">' + v.Name + '</option>');
});
}
}
}
First, you need a <select> as the parent, not an empty element,
dropdown = $('#templateGroupName');
then insert it as a document element, not a string:
var opt = document.createElement('option');
opt.value = v.Id;
opt.innerHTML = v.Name;
dropdown.appendChild(opt);
The browser gets confused when you inject options while the <select> is open. To be fair, your users would probably be confused too.
If you're waiting for something to load, tell them to wait.
If something isn't usable, disable it.
Putting these two together: the first time a user hovers over the <select>, disable it and set the cursor to a loading wheel. Wait until your data loads, then insert the options, re-enable it and switch the cursor back.
var helpers = {
buildDropdown: function(result, dropdown, emptyMessage) {
dropdown.html('');
dropdown.append(`<option value="">${emptyMessage}</option>`);
if (!!result) {
$.each(result, function(k, v) {
dropdown.append(`
<option value="${v.Id}">
${v.Name}
</option>
`);
});
}
}
}
const $DROPDOWN = $('#templateGroupName');
// using jQuery#one to only fire the click event once
$DROPDOWN.one('mouseenter', _ => {
// disable dropdown while loading options
$DROPDOWN.attr('disabled', true)
console.log('loading options...');
// replace contents with your GET request
setTimeout(function() {
helpers.buildDropdown(
Array.from({
length: 30
}, (_, i) => ({
Id: i,
Name: i
})),
$DROPDOWN,
'Select an option'
);
// un-disable after options are loaded and inserted
$DROPDOWN.attr('disabled', false)
}, 1000);
})
/* Show "loading" wheel while loading */
select.custom-select[disabled] {
cursor: wait;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="custom-select" id="templateGroupName" name="templateGroupName">
<option selected>Please Select a group</option>
</select>
I have a select item html with a list of departement.
When I select one (method "change"), it launch an ajax request in jquery, that will display in another select input, a list of cities taken from a database.
Everything works fine, but I have a case where I want to be able to get back what values are stored for departement and ville select items, and at the same time I want to be able to modify it.
I tried to use jQuery .trigger("change"), but it doesn't get into my change function.
I tried to do as it's written here, but there was no difference.
jquery trigger change with chained ajax select
My html file :
<div class="inscriptionForm">
<label for="departement">Département :</label>
<select name="departement" id="departement" required="required">
<option value="">Choisissez un département</option>
<c:forEach items="${departements}" var="departement">
<option value="${departement.code}">${departement.code} - <c:out value="${departement.nom}"/></option>
</c:forEach>
</select>
</div>
<div class="inscriptionForm">
<label for="ville">Ville :</label>
<select name="ville" id="ville" required="required">
<option value="">Choisissez une ville</option>
<c:forEach items="${villes}" var="ville">
<option value="${ville.id}"><c:out value="${ville.nom}"/></option>
</c:forEach>
</select>
</div>
My Jquery methods :
$(document).ready(function(){
var departement = ${spot.departement.code};
var ville = ${spot.ville.id};
$("#departement option[value="+departement+"]").prop('selected', true);
$('#departement').trigger("change");
$("#ville option[value="+ville+"]").prop('selected', true);
$('#departement').change(function() {
var choixDep = $('#departement').val();
$.getJSON("choixDepartement.do",{codeDep: choixDep},
function (data) {
$("#ville").empty();
var option = "<option value=''>Choisissez une ville</option>";
$("#ville").append(option);
$.each( data, function(key, val) {
.....
ajax callback treatment
........
});
}
);
});
});
I don't understand why it doesn't get into the method .change();.
Your code should something like this
$(document).ready(function(){
var departement = ${spot.departement.code};
var ville = ${spot.ville.id};
$("#departement option[value="+departement+"]").prop('selected', true);
$("#ville option[value="+ville+"]").prop('selected', true);
$('#departement').change(function() {
var choixDep = $('#departement').val();
$.getJSON("choixDepartement.do",{codeDep: choixDep},
function (data) {
$("#ville").empty();
var option = "<option value=''>Choisissez une ville</option>";
$("#ville").append(option);
$.each( data, function(key, val) {
.....
ajax callback treatment
........
});
}
);
});
$('#departement').trigger("change");
});
In Jquery we should define event first then we need to trigger
To be executed, an eventListener must be declared before the trigger.
Once again thank you.
It's working after declaring the change() function before,
but I still don't figure out how to select a value in my "ville" option list, even with your advice with the setTimeout to 0.
The execution order seems pretty strange to me. I probably don't know jQuery enough. So far my code looks like that, and the ville list stay with no value selected.
var departement =${spot.departement.code};
var ville =${spot.ville.id};
$("#departement option[value="+departement+"]").prop('selected', true);
alert(departement);
alert(ville);
$('#departement').change(function() {
var choixDep = $('#departement').val();
$.getJSON("choixDepartement.do",{codeDep: choixDep},
function (data) {
$("#ville").empty();
var option = "<option value=''>Choisissez une ville</option>";
$("#ville").append(option);
$.each( data, function(key, val) {
var valToString = val.toString();
var valToArray = valToString.split(",");
var option = "<option value=" + valToArray[0] + ">" + valToArray[1] + "</option>";
$("#ville").append(option);
});
}
);
});
setTimeout(function(){$('#departement').trigger("change");},0);
$("#ville option[value="+ville+"]").prop('selected', true);
My ville value, and the list is there, but the value doesn't get selected
Ok so i found the full answer for my problem.
First obviously it was the problem of declaration order. Function .change() should have been declared before being called.
But then it was not working cause the Ajax request was taking a certain amount of time time, and the $("#ville option[value="+ville+"]").prop('selected', true);was executed bbefore the request send the result. So i just put this line after the ajax request and now it's working properly.
So here is the final code :
var departement =${spot.departement.code};
$('#departement').change(function() {
var choixDep = $('#departement').val();
$.getJSON("choixDepartement.do",{codeDep: choixDep},
function (data) {
$("#ville").empty();
var option = "<option value=''>Choisissez une ville</option>";
$("#ville").append(option);
$.each( data, function(key, val) {
var valToString = val.toString();
var valToArray = valToString.split(",");
var option = "<option value=" + valToArray[0] + ">" + valToArray[1] + "</option>";
$("#ville").append(option);
});
$("#ville option[value="+ville+"]").prop('selected', true);
}
);
});
$("#departement option[value="+departement+"]").prop('selected', true);
$('#departement').trigger("change");
Let say I have this variable html which contain these select options:
var html = '<select>'+
'<option value="10">10</option>'+
'<option value="20">20</option>'+
'</select>';
How can I programmatically select an option which is inside the html variable so when I append them to somewhere, for example
$(this).children('div').append(html);
it will become like this:
<div> <!-- children div of the current scope -->
<select>
<option value="10" selected>10</option>
<option value="20">20</option>
</select>
</div>
How is it possible?
edit: the variable contents is generated from remote locations, and I must change the value locally before it is being appended into a div. Hence, the question.
edit 2: sorry for the confusion, question has been updated with my real situation.
You can cast the HTML into a jQuery element and select the value at index 0. Then you can add it to the DOM.
Here is a simple jQuery plugin to select an option by index.
(function($) {
$.fn.selectOptionByIndex = function(index) {
this.find('option:eq(' + index + ')').prop('selected', true);
return this;
};
$.fn.selectOptionByValue = function(value) {
return this.val(value);
};
$.fn.selectOptionByText = function(text) {
this.find('option').each(function() {
$(this).attr('selected', $(this).text() == text);
});
return this;
};
})(jQuery);
var $html = $([
'<select>',
'<option value="10">10</option>',
'<option value="20">20</option>',
'</select>'
].join(''));
$('#select-handle').append($html.selectOptionByIndex(0));
// or
$html.selectOptionByValue(10);
// or
$html.selectOptionByText('10');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="select-handle"></div>
By default, the first option will be selected - if you want to do on any other set it so using the index as soon as the select is appended:
$('#select_handle option:eq(1)').prop('selected', true)
(this selects the second option)
See demo below:
var html = '<select>'+
'<option value="10">10</option>'+
'<option value="20">20</option>'+
'</select>';
$('#select_handle').append(html);
$('#select_handle option:eq(1)').prop('selected', true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="select_handle"></div>
You could try simply setting the value of the drop-down to the one you wish to 'select' - like
$("#select_handle select").val( a_value );
For example, if a_value is 30 it will add the needed HTML to the DOM node. This would be my take:
$(function() {
var html = '<select>' +
'<option value="10">10</option>' +
'<option value="20">20</option>' +
'<option value="30">30</option>' +
'<option value="40">40</option>' +
'<option value="50">50</option>' +
'</select>';
// set a value; must match a 'value' from the select or it will be ignored
var a_value = 30;
// append select HTML
$('#select_handle').append(html);
// set a value; must match a 'value' from the select or it will be ignored
$("#select_handle select").val(a_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>select added below</h2>
<div id="select_handle">
</div>
selected="selected" will work
var html = '<select>'+
'<option value="10">10</option>'+
'<option value="20" selected="selected">20</option>'+
'</select>';
$('#select_handle').append(html);
You can do this in jQuery using the .attr() function and nth pseudo-selector.
Like so:
$("option:nth-child(1)").attr("selected", "");
Hope it helps! :-)
after the append, try $('#select_handle select').val("10"); or 20 or whatever value you want to select
I am designing a dynamic HTML for Select Option like below:
item += "<td class='ddl' style='width:40%;'>";
item += "<select>"
item += " <option id='list' name='selector' value=" + select + ">" + select + "</option>";
for (var l = 0; l < array.length; l++) {
item += " <option class='ddl' value=" + array[l] + ">" + array[l] + "</option>";
}
item += "</select>";
if ("One"!= '') {
$('#list').val("One");
}
item += "</td>";
The above code creates a dynamic HTML like below:
<select disabled="">
<option select="" value="Please" name="selector" id="list">Please Select</option>
<option value="One" class="ddl">One</option>
<option value="Two" class="ddl">Two</option>
</select>
I want to set the value of the Select to "One" dynamically.
NOTE: The code is not inside document.ready, as I cant keep the code inside ready().
Might be I am assigning the value to the Select before it is revdered on the page. Please suggest me.
You need to call the javaScript to select the value after the dropdown(select) is added to the page. For example if the html is
<div id="myContainer" />
Then the javascript should be like
var item = "";
//Insert your code to create item
item +="<select id='mySelect'>";
item +='<option select="" value="Please" name="selector" id="list">Please Select</option>';
item +='<option value="One" class="ddl">One</option> ';
item +='<option value="Two" class="ddl">Two</option>';
item +='</select>';
$('#myContainer').append(item); //Add to html
//Now the id "mySelect" is available
$('#mySelect').val('One')
I've added a jsFiddle to demonstrate this at http://jsfiddle.net/taleebanwar/n9vCb/
You could also set a selected attribute on the corresponding option tag as you create the select dynamically.
If you are using jQuery then why don't you utilize the library for creating the select, for example, using something like this (Example):
var numbers = ['one', 'two', 'three', 'four', 'five'];
var select = $('<select/>', {id:'list', name:'selector'});
$.each(numbers, function(key, value) {
var text = value[0].toUpperCase() + value.substr(1);
var option = $("<option/>", { class:'ddl', value: value, text: text });
select.append(option);
});
select.val('two').appendTo('body');
I've appended the select into body but you may append it into a td and you can achieve it, give it a try, create the td same way and insert the select in the td and then insert the td in the table. Also you may check this answer.
I am having the drop down list by selecting the country sode the state drop down list populated dynamically using javascript
<div id="ddlState" class='selectBox'>
<span class='selected' id="StatesID">Select a State</span>
<span class='selectArrow'>▼</span>
<div class="selectOptions" id="stateSelectOption">
<span class="selectOption" id="ddlStateText" >Select a State</span>
</div>
</div>
on clicking country the state is populated for tht the code is below
$('#CountriesID').click(function () {
var items;
$('#CountriesID').removeClass("input-validation-error");
if (!$("select#CountriesID").val() == "Select a Country") {
document.getElementById("disableasterisk9").style.display = "";
}
else {
document.getElementById("disableasterisk9").style.display = "none";
}
var countryid = $('#CountriesID').text();
$.getJSON(
"#Url.Action("StateList1", "UserRegistration")" + '/' + countryid,
function (data) {
var items = "<span id='ddlStateText' class='selectOption'>Select a State </span>";
$.each(data, function (i, state) {
items += "<span id='ddlStateText' value='" + state.Value + "' class='selectOption'>" + state.Text + "</span>";
});
$('#stateSelectOption span').html(items);
}
);
});
the list is populated but the selection is not working properly it rendering all the state items in one span tag so for selecting any element all list get selected
I need that the individual element should get selected
What see in the code on this line is that you are adding your html inside the span, so just take away that:
$('#stateSelectOption span').html(items)
The line must look like this (it will insert the code inside the div and not the span):
$('#stateSelectOption').html(items)
I tested it on jsfiddle:
http://jsfiddle.net/uz2vf/