Populate selectors using json doesn't work as expected - javascript

I am trying to make two selector's populated with JSON. One for states and one for cities. If i choose a state the next selector is supposed to show me the cities that are in that state.
I've made it so far using functions. My state function is working fine, but I'm having troubles with my city selector. It doesn't show anything.
I'm stuck here.
In my scripts.js I have
function populateState(data){
var listState = "";
for(var i in data.states){
listState += '<option value="'+data.states[i].id+'">'+data.states[i].name+'</option>';
}
$('#states').html(listState);
}
function populateCities(data){
var listobj = "";
for(var i in data.states.cities){
listobj += '<option value="'+data.states.cities[i].id+'">'+data.states.cities[i].name+'</option>';
}
$('#cities').html(listobj);
}
And in my ready.js where i use the functions I have
var dataJson = {
"states": [
{
"name": "First state",
"id": "1",
"cities": [
{
"name": "city1",
"id": "cos"
},
{
"name": "city2",
"id": "mio"
},
{
"name": "city3",
"id": "top"
}
]
},
{
"name": "Second state",
"id": "2",
"cities": [
{
"name": "city4",
"id": "or"
},
{
"name": "city5",
"id": "st"
},
{
"name": "city6",
"id": "bs"
}
]
},
]
};
$(document).ready(function() {
populateState(dataJson);
$("#states").change(function () {
populateCities(dataJson);
});
});
Here`s the HTML
<select id="states" >
<option value="000">-Select State-</option>
</select>
<select id="cities" >
<option value="000">-Select Cities-</option>
</select>

The issue is that you can't iterate through the cities like that, with for(var i in data.states.cities){...}. You need to iterate through just the cities belonging to the selected state.
Here's a working example.
function populateState(data){
var listState = "";
for(var i in data.states){
listState += '<option value="'+data.states[i].id+'">'+data.states[i].name+'</option>';
}
$('#states').html(listState);
}
function populateCities(data){
var listobj = "";
for(var i in data.states){
if (data.states[i].id == $("#states").val()) {
//this is the selected state, let's get their cities
for(var j in data.states[i].cities){
listobj += '<option value="'+data.states[i].cities[j].id+'">'+data.states[i].cities[j].name+'</option>';
}
}
}
$('#cities').html(listobj);
}
var dataJson = {
"states": [
{
"name": "First state",
"id": "1",
"cities": [
{
"name": "city1",
"id": "cos"
},
{
"name": "city2",
"id": "mio"
},
{
"name": "city3",
"id": "top"
}
]
},
{
"name": "Second state",
"id": "2",
"cities": [
{
"name": "city4",
"id": "or"
},
{
"name": "city5",
"id": "st"
},
{
"name": "city6",
"id": "bs"
}
]
},
]
};
$(document).ready(function() {
populateState(dataJson);
$("#states").change(function () {
populateCities(dataJson);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<select id="states" >
<option value="000">-Select State-</option>
</select>
<select id="cities" >
<option value="000">-Select Cities-</option>
</select>
You would probably want to do something like call the populateCities as a callback when you're done with populateState on document.ready, since it comes up with the First state already selected, but doesn't populate its cities. But at least this will get you past your issue.

Related

how to bind nested json data into angularjs dropdown?

I have some json data related to timzone below i need to bind particular nested value into dropdown, in using angularjs, in timezone array its coming as string format i need to bind those into dropdown.
timezone.json --
{
"countries": {
"US": {
"id": "US",
"name": "United States",
"timezones": [
"America/New_York",
"America/Detroit",
]
},
"CA": {
"id": "CA",
"name": "Canada",
"timezones": [
"America/St_Johns",
"America/Halifax",
]
},
"IN": {
"id": "IN",
"name": "India",
"timezones": [
"Asia/Kolkata"
]
},
}
}
Script--
$http({
method: "GET",
url: 'timezon.json'
}).then(function mySuccess(response) {
$scope.timeZones = response.data;
}, function myError(response) {
$scope.timeZones = response.statusText;
});
HTML Content
<select class="form-control">
<option value="0">--Select Time Zones></option>
</select>
You can use the following to iterate through your object keys and populate your select.
<select class="form-control">
<option value="0">--Select Time Zones></option>
<option ng-repeat="(key, value) in data.countries" value="value.id">{{value.timezones.toString()}}</option>
</select>
Demo
First off manipulate data and then populate select
HTML
<div ng-app="app" ng-controller="Ctrl" ng-init="getTimeZones">
<h1>{{selectedTimezone}}</h1>
<select ng-model="selectedTimezone" ng-options="item for item in timezones">
</select>
</div>
JS
var app = angular.module("app", []);
app.controller('Ctrl', function($scope, $filter) {
$scope.timezones = []
$scope.data = {
"countries": {
"US": {
"id": "US",
"name": "United States",
"timezones": [
"America/New_York",
"America/Detroit",
]
},
"CA": {
"id": "CA",
"name": "Canada",
"timezones": [
"America/St_Johns",
"America/Halifax",
]
},
"IN": {
"id": "IN",
"name": "India",
"timezones": [
"Asia/Kolkata"
]
},
}
}
$scope.getTimeZones = setTimeout(function(){
// http request here after success
for (var key in $scope.data.countries) {
var timezones = $scope.data.countries[key].timezones;
timezones.unshift($scope.data.countries[key].name);
Array.prototype.push.apply($scope.timezones, timezones);
// For ES6
// $scope.timezones.push(...timezones)
}
}, 1000);
});
Demo

How to get the corresponding value from two objects

I have first data object which has a list of cafe, and second data object which has a list of cafe types.
I need find, get and display the corresponding type value from first data object and ID value from second data object.
For example: in list of cafe, I have Pinta with "type" : "3", it means that 3 is Bar from second object.
First object:
{
"list": {
"item": [
{
"ID": "31",
"name": "Staut",
"type": "1",
},
{
"ID": "34",
"name": "Pinta",
"type": "3",
}
]
}
}
And second object:
{
"list": {
"item": [
{
"ID": "1",
"name": "Restaurant",
},
{
"ID": "2",
"name": "Cafe",
},
{
"ID": "3",
"name": "Bar",
}
]
}
}
I can do it with Lodash. It is right, but I can't display it and it uses high memory.
getValues: function() {
_.forEach(CafeJSON.list.item, function(cafeValue) {
_.forEach(TypeJSON.list.item, function(typeValue){
if (cafeValue.type == typeValue.ID) {
console.log("Cafe name is: ", cafeValue.name, "and type is: ", typeValue.name)
}
})
})
}
Result:
I'd simplify the types object down to a object having key value pairs in the form of '3': 'Bar', then loop the items once, overriding the type property's value.
let list = {
"list": {
"item": [{
"ID": "31",
"name": "Staut",
"type": "1",
},
{
"ID": "34",
"name": "Pinta",
"type": "3",
}
]
}
}
let types = {
"list": {
"item": [{
"ID": "1",
"name": "Restaurant",
},
{
"ID": "2",
"name": "Cafe",
},
{
"ID": "3",
"name": "Bar",
}
]
}
}
let typesSimplified = types.list.item.reduce((a, b) => {
a[b.ID] = b.name;
return a;
}, {});
list.list.item.forEach(e => {
e.type = typesSimplified[e.type];
});
console.log(list);

Facing Issue on Getting First Level Of Data in JSON File

I have an external JSON file called movie.json and is like following format
{
"action":
[
{ "id": "1001", "name": "Matrix" },
{ "id": "1002", "name": "IP Man" },
{ "id": "1003", "name": "Revenge" }
],
"comedy":
[
{ "id": "2001", "type": "Iceman" },
{ "id": "2002", "type": "Pat & Mat" },
{ "id": "2003", "type": "Sugar" }
],
"animation":
[
{ "id": "3001", "type": "Frozen" },
{ "id": "3002", "type": "Tangled" },
{ "id": "3003", "type": "Croods" }
]
}
in my HTML I have a bootstrap Tab component like
<ul class="nav nav-tabs" role="tablist">
</ul>
can you please let me know how I can get access to upper level of JSON file (action, comedy, animation and populate them as li in .nav-tabs dynamically
I already tried
$.getJSON('data.json', function (data) {
for (i = 0; i < data.length; i++) {
$('.nav-tabs').append('<li role="presentation" >'+data[0]+'</li>')
}
});
but it is not doing the job. Can you please let me know how to fix this? Thanks
You can use $.each() to iterate the data. key will be the "top level" and val the content
$.getJSON('data.json', function (data) {
$.each( data, function( key, val ) {
$('.nav-tabs').append('<li role="presentation" >'+key+'</li>')
});
});
You treating object like an array, its a simple object Use for-in loop
The for...in statement iterates over the enumerable properties of an object, in arbitrary order. For each distinct property, statements can be executed.
var data = {
"action": [{
"id": "1001",
"name": "Matrix"
},
{
"id": "1002",
"name": "IP Man"
},
{
"id": "1003",
"name": "Revenge"
}
],
"comedy": [{
"id": "2001",
"name": "Iceman"
},
{
"id": "2002",
"name": "Pat & Mat"
},
{
"id": "2003",
"name": "Sugar"
}
],
"animation": [{
"id": "3001",
"name": "Frozen"
},
{
"id": "3002",
"name": "Tangled"
},
{
"id": "3003",
"name": "Croods"
}
]
};
for (var i in data) {
$('.nav-tabs').append('<li><strong>' + i + '<strong></li>')
for (var j = 0; j < data[i].length; j++) {
var obj = data[i][j];
$('.nav-tabs').append('<li>' + obj.name + '</li>')
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="nav nav-tabs" role="tablist">
</ul>
// jsonObj is your json object
jQuery.each(jsonObj, function(key,val) {
//key will have action,comedy and animation
console.log(key,val)
});

Binding json arrays in angular js select option

I am working with select box in angular js. i need to bind the data to the select box from the json,How do i populate json with arrays inside a select box in angular. i have the following code.
HTML
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model="selectedName" ng-options="x.names.name for x in names">
</select>
</div>
JS
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = {
"jobs": [
{
"Software": [
{
"name": "Developer",
"displayName": "App Developer"
},
{
"name": "Designer",
"displayName": "App Designer"
}
]
},
{
"Business": [
{
"name": "Sales",
"displayName": "Sales Manager"
},
{
"name": "Marketing",
"displayName": "Head of Marketing"
}
]
}
]
};
});
How do i populate the json $scope.names inside the select box. i am finding difficulty as the json have arrays. Thanks in advance
Try this one may be it will help you
Use ng-repeat on <select> tag
<select name="singleSelect" id="singleSelect" ng-model="selectedName">
<option value="">---Please select---</option> <!-- not selected / blank option -->
<option ng-repeat="n in names.software" value="{{n.name}}">{{n.displayName}}</option>
</select>
same way you can add different data.
It will be alot more easier if you prepare the data in your controller
$scope.values = [];
angular.forEach($scope.names, function (value, key) {
angular.forEach(value, function (value2, key2) {
angular.forEach(value2, function (value3, key3) {
angular.forEach(value3, function (value4, key4) {
$scope.values.push(value4.name);
});
});
});
});
and use $scope.values in your select
One possible way to do this by using custom directive.
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model='selectedName' custom-options>
<option value="">-- choose an option --</option>
</select>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = {
"jobs": [
{
"Software": [
{
"name": "Developer",
"displayName": "App Developer"
},
{
"name": "Designer",
"displayName": "App Designer"
}
]
},
{
"Business": [
{
"name": "Sales",
"displayName": "Sales Manager"
},
{
"name": "Marketing",
"displayName": "Head of Marketing"
},
{
"name": "Sales1",
"displayName": "Sales Manager1"
},
{
"name": "Marketing1",
"displayName": "Head of Marketing1"
}
]
}
]
};
}).directive("customOptions", function () {
return function (scope, element, attrs) {
var data = scope['names']['jobs'];
var propertyName = 'name';
if (angular.isArray(data)) {
angular.forEach(data, function(value, key) {
angular.forEach(value, function(ivalue, ikey) {
for (var i = 0; i < ivalue.length; i++) {
element.append(angular.element('<option>').text(ivalue[i][propertyName]).attr('value',ivalue[i][propertyName]));
}
})
});
}
}
})
JS FIDDLE

How to select json item from the array

From the below JSON, how can I retrieve title from the note and notes using a for loop and ajax to retrieve?
{
"infos": {
"info": [
{
"startYear": "1900",
"endYear": "1930",
"timeZoneDesc": "daweerrewereopreproewropewredfkfdufssfsfsfsfrerewrBlahhhhh..",
"timeZoneID": "1",
"note": {
"notes": [
{
"id": "1",
"title": "Mmm"
},
{
"id": "2",
"title": "Wmm"
},
{
"id": "3",
"title": "Smm"
}
]
},
"links": [
{ "id": "1", "title": "Red House", "url": "http://infopedia.nl.sg/articles/SIP_611_2004-12-24.html" },
{ "id": "2", "title": "Joo Chiat", "url": "http://www.the-inncrowd.com/joochiat.htm" },
{ "id": "3", "title": "Bake", "url": "https://thelongnwindingroad.wordpress.com/tag/red-house-bakery" }
]
}
I tried out the code below but it doesn't work - it either says:
is null
not an object
length is null
r not an object
var detail = eval(xmlhttprequest.responseText)
var rss = detail.infos.info
for(var i = 0; i<rss.length; i++)
startyear += rss[i].startyear
Use
for (i = 0; i < 3; i++) {
alert(JSON.infos.info[0].note.notes[i].title);
}
TRY IT HERE: JSFIDDLE WORKING EXAMPLE
BTW your JSON is not valid. Use this JSON:
var JSON = {
"infos": {
"info": [
{
"startYear": "1900",
"endYear": "1930",
"timeZoneDesc": "daweerrewereopreproewropewredfkfdufssfsfsfsfrerewrBlahhhhh..",
"timeZoneID": "1",
"note": {
"notes": [
{
"id": "1",
"title": "Mmm"
},
{
"id": "2",
"title": "Wmm"
},
{
"id": "3",
"title": "Smm"
}
]
},
"links": [
{
"id": "1",
"title": "Red House",
"url": "http://infopedia.nl.sg/articles/SIP_611_2004-12-24.html"
},
{
"id": "2",
"title": "Joo Chiat",
"url": "http://www.the-inncrowd.com/joochiat.htm"
},
{
"id": "3",
"title": "Bake",
"url": "https://thelongnwindingroad.wordpress.com/tag/red-house-bakery"
}
]
}
]
}
}
EDIT:
Here is what you want:
var infoLength= JSON.infos.info.length;
for (infoIndex = 0; infoIndex < infoLength; infoIndex++) {
var notesLength= JSON.infos.info[infoIndex].note.notes.length;
for (noteIndex = 0; noteIndex < notesLength; noteIndex++) {
alert(JSON.infos.info[infoIndex].note.notes[noteIndex].title);
}
}
Putting your json into an var called obj, use the following:
obj.infos.info[0].note.notes[0].title
http://jsfiddle.net/Znq34/
Well the "path" to the JSON notes array-like object is:
json.infos.info[0].note.notes;
So you could do something like:
var notes = json.infos.info[0].note.notes;
var titles = [];
for (var i = 0, len = notes.length; i < len; i++)
{
titles.push(notes[i].title);
}
alert('titles is: ' + titles.join(', '));
Fiddle: http://jsfiddle.net/garreh/uDxqD/
Are you using jQuery? ;-)
// Assuming your using "success" in ajax response
success: function(json)
{
var titles = $(json.infos.info[0].note.notes).map(function() {
return this.title;
}).get();
alert(titles.join(', '));
}
First count the length of notes
var len = jsonobject.infos.info.note.notes.length;
Then loops through and get
var title = jsonobject.infos.info.note.notes[i].title;

Categories