How to trigger a method change() in jQuery which launch ajax query - javascript

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");

Related

HTML select not refreshing after being populated via JQuery

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>

How to get the value of dropdown and display in label

I have a dropdown where I am filling the content with dynamic data and in the model I am appending my data to the dropdown
$("#dpp").append($("<option disabled></option>").val(0).html('Select Locations'));
$("#dpp").append($("<option selected='selected'></option>").val(1111).html('All'));
for (var i = 0; i < Location.length; i++) {
$("#dpp").append($("<option></option>").val(data[i].sno).html(data[i].name));
}
I am unable to get the value and text of the selected option by using a change handler.
I tried:
$('#dpp').change(function () {
var thisvalue = $(this + "option:selected").text();
alert(thisvalue);
});
and by default on page load All option selected in the dropdown.
How can I get that value or text and show it on the label?
For change event and document ready:
$(document).ready(function() {
getSelectData($('#dpp'));
});
$('#dpp').on('change', function() {
getSelectData($(this));
});
function getSelectData(el) {
var $option = el.find('option:selected');
var text = $option.text();
var val = $option.val();
alert('option text: ' + text + '; option value ' + val)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="name" id="dpp">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
Use the below code for both purposes (on page load as well as on change event)
$(document).ready(function() {
var dppText= $("#dpp option:selected").text(); // to get text on page load
//to get text on change of drop-down
$(document).on('change','#dpp',function(){
var thisvalue = $(this + "option:selected").text();
alert(thisvalue);
});
});
You can use this:
$(document).on('change','#dpp',function(){
var thisvalue = $(this + "option:selected").text();
alert(thisvalue);
});
This will add change listener to the document level so you will be able to detect the change on dpp.
This will do it:
$("#dpp option:selected").val();

$.ajax json dropdown menu items

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

Getting a 'Cannot find variable' error trying to access a json object

hopefully somebody can help me. The JS below, loads a JSON file and parses the counties into a select menu. It also removes duplicates. Now in the JSON feed, each item has something like this:
{
"County":"Antrim",
"Town":"Antrim Town",
"Restaurant":"Diane's Restaurant & Pizzeria"
}
What I am trying to do is in the first select menu, once the user chooses the county, the second select menu is updated with values from the son object. At the moment I'm getting a 'Cannot find variable' error and I can't work out why. Is the data array not available for some reason?
<script type="text/JavaScript">
$(document).ready(function(){
//get a reference to the select elements
var county = $('#county');
var town = $('#town');
var restaurant = $('#restaurant');
//request the JSON data and parse into the select element
$.getJSON('rai.json', function(data){
console.log(data);
//clear the current content of the select
$('#county').html('');
$('#county').append('<option>Please select county</option>');
$('#county').html('');
$('#town').append('<option>Please select town</option>');
$('#restaurant').html('');
$('#restaurant').append('<option>Please select restaurant</option>');
//iterate over the data and append a select option
$.each(data.irishtowns, function(key, val) {
county.append('<option id="' + val.County + '">' + val.County+ '</option>');
});
var a = new Array();
$('#county').children("option").each(function(x){
test = false;
b = a[x] = $(this).text();
for (i=0;i<a.length-1;i++){
if (b ==a[i]) test =true;
}
if (test) $(this).remove();
});
});
$( "#county" ).change(function() {
var myCounty = $(this).val();
console.log(myCounty);
$.each(data.irishtowns, function(key, val) {
if (val.Town === myCounty) {
town.append('<option id="' + val.Town + '">' + val.Town + '</option>');
}
});
});
});
</script>
Data is not in scope in this line
$.each(data.irishtowns, function(key, val) {
You could move this up into the callback, or use a global variable to provide access: i.e. in the callback have a line countries = data and then
$.each(countries.irishtowns, function(key, val) {

JQuery set select box value to selected

Please help i am doing this to use in my mobile with jquery mobile
var obj = jQuery.parseJSON(finalresult);
//alert(obj);
var dept = '2';
$(document).ready(function () {
//$("#opsContactId").empty();
$.each(obj, function (k, v) {
var $opt = $("<option/>");
$opt.attr("value", k);
//alert(k);
//alert(v);
//var value1=v;
if (k == dept) {
//$opt.attr("selected","selected");
//alert("in if");
$("#opsContactId").val(k);
//document.getElementById("opsContactId").value=k;
// $('#opsContactId').selectmenu('refresh', true);
}
$opt.text(v);
$opt.appendTo($("#opsContactId"));
});
});
not able to set an option to be selected by dafault
As others as stated, jQuery's .prop() would be the most suitable answer here as jQuery Docs mention themselves:
"The .prop() method should be used to set disabled and checked instead of the .attr() method. The .val() method should be used for getting and setting value."
To further your on your example, jQuery allows for method 'chaining' which returns the jQuery object after the method has completed, thus you can add another method directly after it.
<select id="opsContactId">
</select>
<script>
$(document).ready(function() {
var tmp = [ 1, 2, 3, 4, 5 ],
dept = 2;
$.each( tmp, function( k, v ) {
$("<option/>").attr("value", k)
.text( "Value - " + v)
.appendTo( $("#opsContactId") )
.prop( 'selected', ( k == dept ? 'selected' : '' ));
});
});
</script>
Fiddle: http://jsfiddle.net/twdgC/
Later I forgot you mentioned the jQuery mobile aspect of your question, which changes the dynamic of the question a little bit. The snippet above is run after the page has loaded (Thus, all the jQuery mobile attachments have already been set/made), which would happen to give you the result of (below)
Fiddle: http://jsfiddle.net/5ksG8/
This obviously isn't helpful when trying to construct an <select> list, thus we'll need to append the snippet above with:
$("#opsContactId").selectmenu('refresh', true );
After the snippet has run, thus it 'reloads' the entire list, finally providing you with (below)
Fiddle: http://jsfiddle.net/YxVg6/
You were doing this in your original snippet, the issue was - you were executing it within the loop (And it was commented out!).
Would something like this not be easier?
Would something like this not be easier?
var selected = "selected"; // work this out
var text = "Option Text"; // work this out
var value = "Option Value"; // work this out
$("#opsContactId").append('<option value="' + value + '" '+ selected + '>' + text + '</option>');
jsBin demo
if you have a match you'll need to add the attribute selected. however I don't know how your object looks like...
var obj = {"1":"one","2":"two","3":"three","4":"four"}; // let's say that's how it looks
var dept = '2';
$(function () {
var $sel = $("#opsContactId");
$.each(obj, function (k, v) {
var $opt = $("<option/>", {value:k, text:v}).appendTo( $sel );
if (k == dept) $opt.prop({selected:true});
});
});

Categories

Resources