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.
Related
I'm trying to populate a div dynamically with data from JSON but want to avoid duplicates. The script below will give me 3 divs, 2 "standard" and one "special".
How can I achieve without creating duplicate div?
var productList = [
{
model:"helskap",
type:"special",
family:"Bravo"
},
{
model:"Z-skap",
type:"standard",
family:"Valhalla"
},
{
model:"smafacksskap",
type:"standard",
family:"Jona"
}
];
$.each(productList, function(i, item) {
$('.filter').append('<div class="' + productList[i].type+ '"><input type="radio" name="type" value="' + productList[i].type+ '" /><label>' + productList[i].type+ '</label></div>')
});
<div class"filter"></div>
The better way is to first get the array with unique objects on property type then you can use that new filtered array for rendering like in filterProductList:
var productList = [{
model: "helskap",
type: "special",
family: "Bravo"
},
{
model: "Z-skap",
type: "standard",
family: "Valhalla"
},
{
model: "smafacksskap",
type: "standard",
family: "Jona"
}
];
var filterProductList = productList.reduce((acc, item) => {
var existItem = acc.find(({type}) => type === item.type);
if (!existItem) {
acc.push(item);
}
return acc;
}, []);
console.log(filterProductList);
Then use filterProductList to render the HTML in your page. Your code will look:
$.each(filterProductList, function(i, item) {
var type = filterProductList[i].type;
$('.filter').append('<div class="' + type + '"><input type="radio" name="type" value="' + type + '" /><label>' + type + '</label></div>')
});
I think the easy way is to create each div with id="type", then append contents to div id="type".
function showData(){
Object.keys(JSONcall).forEach(function(key){
var tvShow = JSONcall[key].show;
$('#show-select').append("<option class=\"selectS\"" +
"id=\"" + key + "\"" + "value=\"JSONcall[" + key + "]
.show\" onchange=\"selectShow(this.id)\">" + tvShow.name + "</option>");
});
}
Hello, I have this forEach loop where the function is to append the results of a JSON object. After appending the result is:
<option class="selectS" id="0" value="JSONcall[0].show"
onchange="selectShow(this.id)">Some Value</option>
First question: Is it wise to append onchange=(function()) like that?
selectShow(value) is a function meant to get id of <option> and display the data in another <div>.
Last question is why am I unable to get the results of this.id in this context?
create option element like this , and three is no need of id at option element as you are having val on option to identify it.
$('<option>').val(key).text(tvShow.name).appendTo('#show-select');
one more thing selectShow() must need to apply at to select not to option.
<select onchange= "selectShow()"> </select>
function selectShow(){
console.log($( "#show-select" ).val());
}
You have to put your onchange trigger on your select. I advice you to add event with javascript no in html attribute. You have to use value instead of id for sharing value.
const obj = {
channel1: {
show: {
id: "#ch1",
name: "ch1"
}
},
channel2: {
show: {
id: "#ch2",
name: "ch2"
}
}
};
function showData() {
$.each(obj, function(key, value) {
const tvShow = value.show; // obj[key] === value
$("<option></option")
.addClass("selectS")
.val(key)
.text(tvShow.name)
.appendTo("#show-select");
});
}
function selectShow() {
console.log($(this).val());
}
showData();
$("#show-select").on("change", selectShow)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="show-select"></select>
I have reworked your code in a different way.
Used $.ajax() to pull some random JSON data and parse it.
Used $.each(var, function(index, value) {}) to iterate over the object.
Used change() event to log text, val, id
The rest you can modify inside append() method.
function showData() {
$.ajax({
url: "https://www.json-generator.com/api/json/get/bHepFCoNmG?indent=2",
success: function(data) {
$.each(data, (i, val) => {
$("#mySelect").append('<option class="selectS" id="' + i + '" value="' + val.name + '">' + val.name + '</option>');
});
}
});
}
// change event
$('#mySelect').change(function() {
console.log($(this).find(':selected').text());
console.log($(this).find(':selected').val());
console.log($(this).find(':selected').attr("id"));
});
showData();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<select id="mySelect">
</select>
</div>
The code below shows how to use jQuery.data() to solve the same issue:
//TODO: Add triggers and events
function showData() {
// Retrieve JSON file from website
$.ajax({
// Returns 15 rows
url: "https://www.json-generator.com/api/json/get/cuScfPsQRK?indent=2",
success: function(data) {
// Iterate retrieved JSON Object
$.each(data, (i, val) => {
// Get JSON keys
let key = val.key;
let value = val.value;
// Define metadata object
let metaData = JSON.stringify({
index : i,
key : key,
value : value
})
// Create template & pass configuration object
$('<option></option>', {
id : i,
text : key,
value : value,
class : "selectS",
'data-meta' : metaData
}).appendTo('#mySelect');
});
}
});
}
$('#mySelect').change(function() {
// Get data('meta') keys
let index = $(this).find(':selected').data('meta').index;
let key = $(this).find(':selected').data('meta').key;
let value = $(this).find(':selected').data('meta').value;
$("#dataId").text(index);
$("#dataKey").text(key);
$("#dataValue").text(value);
// Using template literals
//console.log(`================\nID: ${index}\nKey: ${key}\nValue: ${value}\n================`);
});
showData();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Select a Person:</h3>
<hr>
<select id="mySelect">
</select>
<hr>
<div id="data">
Index:
<span id="dataId">N/A</span><br>
Key:
<span id="dataKey">N/A</span><br>
Value:
<span id="dataValue">N/A</span>
</div>
This is my JSON file:
{
"AL2": {
"3810": "AL2GR1",
"3814": "AL2GR2",
"3815": "AL2GR3",
},
"AN3": {
"3818": "AN3GR1",
"3819": "AN3GR2"
},
"CME": {
"2405": "CME"
}
I need to populate two select boxes. The first one let choose between first level values (AL2,AN3,CME) and the second one between the deep level ones (AL2GR#,AN3GR#,CME).
My infile Javascript is :
var jsonData = {"AL2": {"3810": "AL2GR1","3814": "AL2GR2","3815": "AL2GR3"},"AN3": {"3818": "AN3GR1","3819": "AN3GR2"},"CME": {"2405": "CME"}};
$(window).load(function(){
$.each(jsonData,function(key, value) {
$('#ue').append('<option value=' + key + '>' + key + '</option>');
});
});
function grfromue(element,jsonData) {
var ue = $("#ue option:selected").text();
alert(ue);
$.each(jsonData[ue],function(key, value) {
$('#gr').append('<option value=' + key + '>' + value + '</option>');
});
};
And HTML :
<select id="ue" onChange="grfromue(this,jsonData);">
</select>
<select id="gr">
</select>
The second select box isn't changing, what am I doing wrong ?
Below snippet of code might be helpful to you
var json = {
"AL2": {
"3810": "AL2GR1",
"3814": "AL2GR2",
"3815": "AL2GR3",
},
"AN3": {
"3818": "AN3GR1",
"3819": "AN3GR2"
},
"CME": {
"2405": "CME"
}
};
to get each value in first level
$.each( json, function( key, value ) {
console.log( key );
});
to get second level values based on your first input
input = 'AL2';
$.each( json[input], function( key, value ) {
console.log( key + ' : ' + value );
});
Hope this helps you.
You can use a nested JQuery each method to iterate over the objects and the nested objects within them. You can extend it for as many nested objects as you like.
jQuery.each(obj, function(i, val) {
console.log("Object: " + i);
jQuery.each(val, function(j, value) {
console.log('It has ' + j + ' with value ' + value);
});
});
If you want to populate the second select box based on the value of the first, you can use array notation to fetch contents of the object. Something like this:
jQuery("#selec-id").change(function(){
$("#second-select-id").html("");
jQuery.each(obj[$(this).val()], function(key, value) {
$("#second-select-id").append("<option value='"+key+"'>"+value+"</option>");
});
});
I have a JSON file set up with data that, when a user on my site selects a music genre from a dropdown menu, songs of that music genre (the songs are stored in the JSON file, along with the artist) will be displayed in a combo box on my site. Sadly, this is not going according to plan.
I know that this error is based around some mistake that I am making, but I don't know where exactly! My browser's console is saying, "Uncaught TypeError: Cannot read property 'undefined' of undefined" on the following statement:
var selectedValue = dropDown.options[dropDown.selectedIndex].value;
However, I don't know what that means or if it's actually a legitimate runtime error. Anyways, here is my code. I would really appreciate it if you awesome people could look over my code and see what you think may be causing my code to not act in the way that I want to it to act (detailed in the first paragraph) :)
JSON
{
"library":
[
// ROCK
{
"title": "Your Love",
"artist": "The Outfield"
},
{
"title": "Voodoo Child",
"artist": "Jimi Hendrix"
},
{
"title": "When I'm Gone",
"artist": "Three Doors Down"
},
// ALTERNATIVE
{
"title": "Jumper",
"artist": "Third Eye Blind"
},
{
"title": "One Week",
"artist": "Barenaked Ladies"
},
{
"title": "The Middle",
"artist": "Jimmy Eat World"
}
]
}
JavaScript
$(document).ready(function()
{
// Declare our needed variables
var dropDown = $("#music-genre"); // <select id="music-genre">...</select>
var selectedValue = dropDown.options[dropDown.selectedIndex].value;
var target = $('#song'); // <select multiple id="song">...</select>
// If "Alternative" is chosen, choose the alternative songs
// I didn't add a conditional statement for choosing "Rock" because it's the same
if (selectedValue == "Alternative")
{
// "data/music.json" is the location of my JSON file
$.getJSON("data/music.json", function(data)
{
$.each(data, function(key, val)
{
target.innerHTML += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>';
}); // END $.each
}); // END $.getJSON
} // END if
}); // END ready()
HTML
<!-- Drop Down -->
<select id="music-genre">
<option id="rock" value="rock">Rock</option>
<option id="alternative" value="alternative">Alternative</option>
</select>
<!-- Combo Box -->
<select multiple id="song">
<!-- "Select one or more" is disabled because I don't want users selecting it -->
<option value="select" disabled>Select one or more</option>
</select>
Your the data you want from your returned JSON is in the library array, so you need to use data.library.
Also note that target will be a jQuery object which does not have a innerHTML property, so you need to use append instead:
$.each(data.library, function(key, val) {
target.append('<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>');
})
Finally as others mentioned you can use the val() property on a select element to get the selected value:
var selectedValue = $("#music-genre").val();
Try to use it like this:
JSON:
{
"library": {
"rock": [
{
"title": "Your Love",
"artist": "The Outfield"
},
{
"title": "Voodoo Child",
"artist": "Jimi Hendrix"
},
{
"title": "When I'm Gone",
"artist": "Three Doors Down"
}
],
"alternative": [
{
"title": "Jumper",
"artist": "Third Eye Blind"
},
{
"title": "One Week",
"artist": "Barenaked Ladies"
},
{
"title": "The Middle",
"artist": "Jimmy Eat World"
}
]
}
JAVASCRIPT:
$(function(){
// Declare our needed variables
var dropDown = $("#music-genre"); // <select id="music-genre">...</select>
// var selectedValue = dropDown.options[dropDown.selectedIndex].value;
var target = $('#song'); // <select multiple id="song">...</select>
dropDown.on("change", function(){
var genre = $(this).val();
var html = '';
$.getJSON("test.json", function(data){
$.each(data.library[genre], function(key, val){
html += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>'; // Save whole html in a var
}); // END $.each*/
target.html(html); // append it in target div
}); // END $.getJSON
});
}); // END ready()
Try to use:
var selectedValue = dropDown.find(':selected').val();
or:
var selectedValue = dropDown.val();
instead of:
var selectedValue = dropDown.options[dropDown.selectedIndex].value;
since dropDown is a jQuery object which required you to use jQuery method here.
Also note that data contains library array, so you need to access this array to get the value inside:
$.each(data.library, function(key, val) {
target.innerHTML += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>';
});
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I've a requirement where in I receive a List of HashMap from a database query and I've to display that on the JSP.
The JSON object looks like below:
[
{"UNIT_NM":"ATLANTA", "UNIT_CD":"A00"},
{"UNIT_NM":"ATLANTA CKO","UNIT_CD":"A00"},
{"UNIT_NM":"DALLAS", "UNIT_CD":"D00"},
{"UNIT_NM":"DALLAS CKO", "UNIT_CD":"D00"}
]
I've to display it in dropdown like:
"<option value='A00'> A00 ATLANTA</option>";
"<option value='A00'> A00 ATLANTA CKO</option>";
"<option value='D00'> D00 DALLAS</option>";
"<option value='D00'> D00 DALLAS CKO</option>";
The JS code is:
$.ajax({
url:indexContextRoot+"populateManualCsoCodes",
type:"post",
async:true,
success: function(data){
var listItems= "<option value=''>Please Select</option>";
$.each(data, function(key, value) {
listItems+= "<option value='" + key + "'>" + value + "</option>";
});
$("#manualCsoCodes").html(listItems);
}
});
I'm getting the dropdown as:
[object][Object]
[object][Object]
[object][Object]
[object][Object]
Any suggestions please!
The each() callback function has two parameters: 1) The index of the array element, and 2) The array element. So key is going to be 0, 1, 2, etc. and value is going to be the js object at that index position. So you need to do:
$.each(data, function(key, obj) {
var str = obj["UNIT_CD"];
listItems+= "<option value='" + str + "'>" + str + " " + obj["UNIT_NM"] + "</option>";
});
To make this a bit more modular and involve lesser HTML, here's my take on this :
var data = [
{
"UNIT_NM": "ATLANTA",
"UNIT_CD": "A00"
},
{
"UNIT_NM": "ATLANTA CKO",
"UNIT_CD": "A00"
},
{
"UNIT_NM": "DALLAS",
"UNIT_CD": "D00"
},
{
"UNIT_NM": "DALLAS CKO",
"UNIT_CD": "D00"
}
];
//init first option
var $option = $("<option/>", {
"value": '',
"html": "Please Select"
});
//add that to an array
var options = [$option];
//iterate over data
$.each(data, function (key, value) {
// value now contains a row eg., when key = 0, value = { "UNIT_NM": "ATLANTA", "UNIT_CD": "A00" }
//clone the default option, change the value and the HTML, then push into options array
options.push($option.clone().val(value.UNIT_CD).html(value.UNIT_CD + " " + value.UNIT_NM));
});
//add that array into select
$("#manualCsoCodes").html(options);
The idea is to create an options array, which fills up with jQuery objects with tag name option and then place that in the select tag. Here's a demo
Oh, before i forget, each iterates row-wise. So, in any iteration of each, you'll get a row of data. For example,
if key === 2, then value === {
"UNIT_NM": "DALLAS",
"UNIT_CD": "D00"
}
So, to access UNIT_NM & UNIT_CD, you'll have to use value.UNIT_NM & value.UNIT_CD respectively. For more info on each, see docs.
Hope that helps!
listItems+= "<option value='" + value.UNIT_CD + "'>" + value.UNIT_CD + " " + value.UNIT_NM + "</option>";
PS: you could do that yourself if you used console.log(value);