How do I populate a select using JSON based on previous selection? - javascript

I'm trying to create two select dropdowns for provinces and their cities. The idea is that I first select the province on the first dropdown, and after that, only the cities from that province will show on the second select.
I have this JSON file with the provinces and cities in Catalonia. I edited the file myself so I could have an array of all the cities of each province but I don't know if it's the best way to show the cities in the select though. Here I show you a short version of the JSON file because the original it's too big:
{
"Barcelona":[
[
"Abrera"
],
[
"Aguilar de Segarra"
],
[
"Alella"
]
],
"Girona":[
[
"Agullana"
],
[
"Aiguaviva"
],
[
"Albanyà"
]
],
"Tarragona":[
[
"Aiguamúrcia"
],
[
"Albinyana"
],
[
"Albiol, l'"
]
],
"Lleida":[
[
"Abella de la Conca"
],
[
"Àger"
],
[
"Agramunt"
]
}
I have been able to create the first select and it shows the 4 provinces correctly with this code:
<select name="activity_province" class="form-select" id="activity_province">
<option hidden selected></option>
<script type="text/javascript">
$(document).on('ready',function (){
$.getJSON('/../public/utils/municipios.json', function(data) {
$.each(data, function(key, value) {
$("#activity_province").append('<option name="' + key + '">' + key + '</option>');
});
});
});
</script>
</select>
<label for="activity_province">Province</label>
But when I try to do the second one (cities) I get on each option of the select all the cities from each province together, separated by commas like this:
Cities select
The code of the second select is the following:
<select name="activity_city" class="form-select" id="activity_city">
<option hidden selected></option>
<script type="text/javascript">
$(document).on('ready',function (){
$.getJSON('/../public/utils/municipios.json', function(data) {
$.each(data, function(key, value) {
$("#activity_city").append('<option name="' + value + '">' + value + '</option>');
});
});
});
</script>
</select>
<label for="activity_city">City</label>
I would like to know how to iterate correctly all the cities when I have selected a province. And if you think the JSON file should be organised in a different way for easier access please let me know.
Thank you very much in advance.

I've modified your code a bit, for testing purposes. The relevant fiddle can be found here.
The adjustments I've made refer to omitting the call to an external JSON - I've made a variable out of it, for testing and illustrative purposes. Also, if your regions and cities list is more or less constant, you can just include it as an external JS file. For example:
<script src="/public/utils/municipios.js></script>
And the contents of that JS file would be a JSON variable (minified or not, depending on the number of regions and cities within those regions).
The key point here is that your #activity_province is populated from the keys of your JSON file (or JSON variable, if you organize everything as I've suggested). You can do that right away, on $(document).ready(...).
The contents of #activity_city appear once a region has been selected. Since the cities are the values associated with the specific region key, you would need to extract them from your JSON, clear the previous contents of #activity_city, and then repopulate it with whatever was listed for the selected region.
var regions = {
"Barcelona": [
"Abrera",
"Aguilar de Segarra",
"Alella"
],
"Girona": [
"Agullana",
"Aiguaviva",
"Albanyà"
],
"Tarragona": [
"Aiguamúrcia",
"Albinyana",
"Albiol, l'"
],
"Lleida": [
"Abella de la Conca",
"Àger",
"Agramunt"
]
};
$(document).ready(function (){
var province = Object.keys(regions);
var options = "";
for(var i = 0; i < province.length; i++) {
options += '<option value="' + province[i] + '">' + province[i] + '</option>';
}
$("#activity_province").append(options);
$("#activity_province").on("change",function() {
var chosenProvince = $(this).val();
var basicOption = '<option value="">Please choose a city</option>';
var cityOptions = "";
var cities = regions[chosenProvince];
if(cities) {
for(var i = 0; i < cities.length; i++) {
cityOptions += '<option value="' + cities[i] + '">' + cities[i] + '</option>';
}
}
$("#activity_city").html(basicOption + cityOptions);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="activity_province">Province</label>
<select name="activity_province" class="form-select" id="activity_province">
<option value="" selected>Please choose a province</option>
</select>
<label for="activity_city">City</label>
<select name="activity_city" class="form-select" id="activity_city">
<option value="" selected>Please choose a city</option>
</select>

Related

data showing in single option instead of multiple option from json array

I have a JSON array in a JSON file looks like this:
{
"states": [
{
"state": "Andhra Pradesh",
"districts": [
"Anantapur",
"Chittoor",
"East Godavari",
"Guntur",
"Krishna",
"Kurnool",
"Nellore",
"Prakasam",
"Srikakulam",
"Visakhapatnam",
"Vizianagaram",
"West Godavari",
"YSR Kadapa"]
}
]
}
and I am successfully able to load all states in the select element as a dependent select option
. when I select a state from a select element it populates a related array in the district select element.
but instead of the array showing a separate option it shows as one option:
Should I modify my JSON array in a different format?
jquery
$('#statePicker').on('change', function() {
$("#cityPicker").html('');
$.ajax({
url: "{{ asset('json/in-sc-list.json') }}",
type: "GET",
dataType: 'json',
success: function(res) {
$('#cityPicker').html('<option value="">Select City</option>');
$.each(res.states, function(key, value) {
if (value.state == $('#statePicker').val()) {
console.log(value.districts);
$("#cityPicker").append('<option value="' + value
.districts + '">' + value.districts + '</option>');
}
});
}
});
});
blade
<span>
<select id="statePicker" name="statePicker" required class="form-control"></select>
<select id="cityPicker" name="cityPicker" required class="form-control"></select>
</span>
Your data structure is fine. The issue is that you're not creating multiple option elements, you're only creating one. This part is off:
$("#cityPicker").append('<option value="' + value
.districts + '">' + value.districts + '</option>');
}
What you want to do is create an option element for each district, as follows:
for (const district of value.districts) {
$("#cityPicker").append('<option value="' + district + '">' + district + '</option>');
}
let statePicker = $('#statePicker').val();
let list = $("#cityPicker");
$.each(res.states, function(key, value) {
if (value.state == statePicker) {
$.each(items, function(item) {
list.append(new Option(item, item));
});
}
});
You need to loop value.districts because its an array, and also, you are doing it in a dirty way, you are initializing $("#cityPicker") on every loop, This might give some performance issues in future if the list items increases.

Trouble trying to use JSON and JS with jQuery

I'm trying to get the field 'sigla' from a JSON file and put it on a HTML 'option object', but it's refusing to work as it should.. hope some of you out there can help me with that!
This is a sample of the JSON file:
{
"estados": [
{
"sigla": "AC",
"nome": "Acre",
"cidades": [
"Acrelândia",
"Assis Brasil"
]
},
{
"sigla": "AL",
"nome": "Alagoas",
"cidades": [
"Água Branca",
"Anadia"
]
}, ...
]
}
Script:
<script>
$.getJSON("json/estados.json", function (data){
$.each(data.estados, function (keyEstados, valEstados){
var output = '';
output += '<option value="" disabled="disabled" selected>UF</option>';
$.each(valEstados.sigla, function (keySigla, valSigla){
output += '<option value="' + valSigla + '">' + valSigla + '</option>';
});
$('#selection').html(output);
});
});
</script>
Where it should fit in:
<div class="col-sm-6">
<div class="inputBox">
<div class="inputText">Selecione seu estado*
<select id="selection" name="estado_php" required>
<option value="" disabled="disabled" selected>UF</option>
</select>
</div>
</div>
</div>
It seems to me that you are fetching the valEstados.sigla as it was an object or an array ($.each(valEstados.sigla) and it has the value you need to set the options.
Besides that, you are setting a disabled option and the html of the select one time for each data.estados instead of just once.
This should work:
$.getJSON("json/estados.json", function (data) {
var output = '';
output += '<option value="" disabled="disabled" selected>UF</option>';
$.each(data.estados, function (keyEstados, valEstados) {
output += '<option value="' + valEstados.sigla + '">' + valEstados.sigla + '</option>';
});
$('#selection').html(output);
});
Have you tried using the "developer" mode in your browser to set breakpoints in your code to debug it? E.g. on Firefox, the menu has a top level entry to "Web Developer"->"Debugger".
If you do, I think you will find have mixed up your loops. The first loop looks OK in that
$.each(data.estados, function (keyEstados, valEstados){...
should match the list starting
"estados": [...]
However, I don't think the second loop starting
$.each(valEstados.sigla, function (keySigla, valSigla){
is needed. I think your code needs to look more like this:
$.getJSON("json/estados.json", function (data){
var output = '';
output += '<option value="" disabled="disabled" selected>UF</option>';
$.each(data.estados, function (keyEstados, valEstados){
output += '<option value="' + valSigla + '">' + valSigla + '</option>';
});
$('#selection').html(output);
});
(not tested, but it basically gets rid of the inner loop).

Appending data from ajax to html select tag using jquery

How can I append the data from API to a select tag in html.
This is my javascript code.
var options = '';
for (var i = 0; i < data.total; i++) {
options += '<option value="' + data.data[i].projectName + '">' + data.data[i].projectName + '</option>';
}
$("#selectProjectName").append(options);
This is my html code.
<select id="selectProjectName" class="form-control show-tick selectpicker" title="Choose project name">
</select>
The data is shown in the console of the browser, but it is not appended to the select tag while hard coded values are shown in the select tag.
Using AdminBSBMaterialDesign-master template.
It looks that you're using selectpicker, so after you change anything in the select element you need to refresh it using $(".selectpicker").selectpicker("refresh");
This is in the documentation here.
Also, there's nothing apparently wrong with your method of appending it, as long as data.total returns the length of it (otherwise, use .length) but just as a FYI you can use the following syntax:
$('#select').append($('<option>', {value:1, text:'One'}));
To make things easier and nicer for you.
Cheers! :)
I assume your data is key value type
var newOptions = {
'red' : 'Red',
'blue' : 'Blue',
'green' : 'Green',
'yellow' : 'Yellow'
}; // get this data from server
var selectedOption = 'green';
var select = $('#selectProjectName');
var options = select.prop('options');
$.each(newOptions, function(val, text) {
options[options.length] = new Option(text, val);
});
select.val(selectedOption);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="selectProjectName" class="form-control show-tick selectpicker" title="Choose project name">
</select>
Try .length instead of .total
var options = '';
for (var i = 0; i < data.length; i++) {
options += '<option value="' + data[i].projectName + '">' + data[i].projectName + '</option>';
}
$("#selectProjectName").append(options);
$("#selectProjectName").selectpicker("refresh");
Instead of using string concatenation, you can use jquery style of creating option element and appending the same as below.
Please check whether your data structure is similar to the one below according to the code that you are trying.
Otherwise better to use data.data.length instead of data.total
var data = {
total: 3,
data: [
{
projectName: 'jquery'
},
{
projectName: 'reactjs'
},
{
projectName: 'angular'
}
]
};
for (var i = 0; i < data.data.length; i++) {
var option = $('<option>', {
value: data.data[i].projectName,
html: data.data[i].projectName
});
$("#selectProjectName").append(option);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="selectProjectName" class="form-control show-tick selectpicker" title="Choose project name">
</select>
Use .length instead of .total
Inside the loop, create each option element and add them one by one to the select element:
for (var i = 0; i < data.length; i++) {
var opt = $('<option></option>');
opt.attr('value', data.data[i].projectName).text(data.data[i].projectName);
$("#selectProjectName").append(opt);
}

jQuery select (Dropdown) populate from array

I currently have this here working..
$(document).ready(function() {
$("#image").change(function() {
$("#imagePreview").empty();
$("#imagePreview").append("<img src=\"" + $("#image").val() + "\" />");
});
});
<select name="image" id="image" class="inputbox" size="1">
<option value="imageall.jpg" selected> - All - </option>
<option value="image1.jpg">image1.jpg</option>
<option value="image2.jpg">image2.jpg</option>
<option value="image3.jpg">image3.jpg</option>
</select>
<div id="imagePreview">
</div>
from this previous question:
Previous Question
I was wondering how can I populate the from a jQuery Array instead?
How could I do that? So basically the values and name from an array
This is the example in Fiddle i will be using Example Working
function populateSelect(el, items) {
el.options.length = 0;
if (items.length > 0)
el.options[0] = new Option('please select', '');
$.each(items, function () {
el.options[el.options.length] = new Option(this.name, this.value);
});
}
As seen here:
Using javascript and jquery, to populate related select boxes with array structure
You may want to retrieve names and values from JSON array this way.
var image_maps = {image1: "image1.jpg", image2: "image2.jpg"};
$.each(image_maps , function(name, value) {
alert("name: " + name + " value: " + value);
});

jquery ui autocomplete comobox recreating options not working

hi i am using jquery ui autocomplete combobox plugin , i am creating a combobox initially in document.ready
jQuery('#combolist_city').combobox();
i set some options when page is loading
<select id="combolist_city" class="city" name="search[city]">
<option value="0">Select city</option>
<?php
if(isset($city_list))
{
foreach($city_list as $city_data)
{
if(isset($selected_city) && ($selected_city == $city_data['CityID']))
{
echo "<option selected='selecetd' value=".$city_data['CityID'].">".$city_data['CityName']."</option>";
}
else
{
echo "<option value=".$city_data['CityID'].">".$city_data['CityName']."</option>";
}
}
}
?>
</select>
now i want to change his options, i am tying to do it by
jQuery("#combolist_city").combobox({
initialValues: ['aaa','bbb','ccc']
});
but it is not working , it is not recreating the options ,
how can i do this , please help.............................
You have to do it manually. First destroy the combobox and empty the select. Append the new options and build the combobox again:
var aList = {'id1': 'val1', 'id2': 'val2', 'id3': 'val3'};
var sKey;
$("#combolist_city").combobox('destroy').empty();
for (sKey in aList) {
$("#combolist_city").append('<option value="' + sKey + '">' + aList[sKey] + '</option>');
}
$("#combolist_city").combobox();
Also see this example.

Categories

Resources