HTML select not refreshing after being populated via JQuery - javascript

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>

Related

Adding Checkbox to dropdown list

I am new to JavaScript programming. My program gives me another dropdown
menu based on the selection of the first dropdown menu. I am trying figure out how I can add checkbox into my dropdown so that I can check different types of fruits or
vegetables.
<script>
window.onload = function() {
// provs is an object but you can think of it as a lookup table
var provs = {
'Vegetable': ['Broccoli', 'Cabbage','Carrot'],
'Fruit': ['Tomato', 'Apple','Orange']
},
// just grab references to the two drop-downs
food_select = document.querySelector('#food'),
type_select = document.querySelector('#type');
// populate the drop-down
setOptions(food_select, Object.keys(provs));
// populate the town drop-down
setOptions(type_select, provs[food_select.value]);
// attach a change event listener to the drop-down
food_select.addEventListener('change', function() {
// get the towns in the selected province
setOptions(type_select, provs[food_select.value]);
});
function setOptions(dropDown, options) {
// clear out any existing values
dropDown.innerHTML = '';
// insert the new options into the drop-down
options.forEach(function(value) {
dropDown.innerHTML += '<option name="' + value + '">' + value + '</option>';
});
}
};
</script>
<body>
<select id="food"></select><br><br><br>
<select id="type"></select>
<body>

How to change the Select options of multiple Selects but keep the currently selected Options selected in jQuery

I'm trying to keep a destination Option selected if it's already selected. If the user chooses a new client, each Select needs to change destination Options (there are often dozens of destinations per client), but keep the currently selected one if it's already in the list.
I've tried getting $.each() of the Selects, emptying them, and then $.append()ing them with the list of destinations, but it's only changing the second of three selects.
$('#client_id').on('change', function () { // Client is selected, load branch destinations
// AJAX server-side script with the client id to fetch client branches
$.post('/directtransit/getbranchlist', {'id': id}, function (data) {
// Change all of the line items' destination options based on client branches
$('select[id^="destination"]').each(function(){
var currentDestination = $(this).val(); // Get items currently selected destination
$(this).empty().append('<option></option>');
$.each(branches, function (k, v) { // Populate select options for each of the line items
var option = '<option value="' + v.id + '">' + v.name + '</option>';
// If the currently selected location is in the new option list...
// ... keep it selected
if (v.id === currentDestination) {
option = '<option value="' + v.id + '" selected>' + v.name + '</option>';
}
$(this).append(option);
});
});
});
});
Shouldn't it be changing all of them?

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

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

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

jQuery Tooltip on Selectize

I am trying to add a jQuery tooltip on a Selectize (http://brianreavis.github.io/selectize.js/) select box, however for some reason I'm having some problems.
Here's a snippet of my code:
$(function() {
$("#myDropdown").selectize({
onChange: function(value) {
var ddOptions = {
1: triggerOpt1,
2: triggerOpt2,
3: triggerOpt3,
4: triggerOpt4
};
ddOptions[value]();
},
render: {
option: showItem,
item: showItem
}
});
$("#myDropdown .ddOption").tooltip({
position: "bottom left",
offset: [-2, 10],
opacity: 0.9
});
});
function showItem(data) {
return Handlebars.templates["dropdown"]({
itemClass: data.value,
label: data.text,
title: I18n["ddOption_" + data.value]
});
}
<select id="myDropdown">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
</select>
For some reason, I am not getting the jQuery tooltip but the native browser tooltip. When I try to attach the tooltip in the console it works fine..
Has anyone ever encountered this issue?
EDIT: the class ddOption is being added to the selectize items in the handlebars template.
I don't know about Selectize but I can figure out it is based on jQuery-ui's selectmenu with which I experienced same problem.
The underlying cause is that jquery-UI hides actual select element and build an entirely new one with other html which simulates it and synchronize its value to original select tag.
So, if you capture it, for example, by it's id or class to do anything, you end up modifying a hidden element.
You should search for a sibling span with the ui-selectmenu-button class instead. But better use your preferred browser inspector to see it's actual attributes uses selectize plugin.
ddOptions is JS array type.. you need html element to get hover intent..
so try below code .. it might help you out...
$("#myDropdown option").tooltip({
position: "bottom left",
offset: [-2, 10],
opacity: 0.9
});
});
I found a partial solution:
Only apply if you tooltip message is generic or equals, to each elements that take Selectize plugin in the View.
Use jQuery to set manually ToolTip options:
$(".selectize-control").tooltip({
placement: "top", // position
title: "Your Message"
});
I've created this code. I hope it helps you.
This is the way like I initialized my data to Selectize
$.ajax({
type: 'GET',
url : 'tableConfig',
success : function(data) {
$('#idTrans').each(function() {
if (this.selectize) {
let list = data.filter(x => x.codigo === "TRANS");
for(let i = 0; i < list.length; i++){
this.selectize.addOption({value:list[i].idConfiguracion, text: list[i].valor, title: list[i].descripcion});
}
}
});
},
error: function (request, status, error) {
//alert("No se pudo realizar la operación por un error interno, contactese con el Administrador.");
}
});
And then, I can customize the tooltip.
$('#idTrans').selectize({
render: {
option: function(data, escape) {
let txtTitle = data.title;
if(txtTitle === undefined || txtTitle === 'Ingrese Detalle:') txtTitle = '';
return '<div class="option">' +
'<div title="' + txtTitle + '">' + escape(data.text) + '</div>' +
'</div>';
},
item: function(data, escape) {
return '<div>'+ escape(data.text) + '</div>';
}
},
onChange: function (value) {
let tableConfig = $('#tableConfig').bootstrapTable('getData');
let list = tableConfig.filter(x => x.idConfiguracion === parseInt(value));
if (list.length > 0) {
let idProTrans = list[0].nivel_padre;
if (idProTrans !== null) {
$("#idProceso_Trans").val(idProTrans);
}
}
}
});
The property 'onChange'. Maybe, it isn't necessary for you and also you can delete that part.As you see, inside of render's property. I put 'title' for tooltip
Finally, looks like this.

Categories

Resources