I am trying to create a 3 level dropdown with data, but the second and third dropdowns still show the data as a whole. How to have the second and third dropdown filter data based on related data?
var json = [{
"country": "USA",
"state": "LOS ANGELES",
"city": "LOS ANGELES"
},
{
"country": "USA",
"state": "LOS ANGELES",
"city": "LOS ANGELES 2"
},
{
"country": "USA",
"state": "New York",
"city": "New York",
},
{
"country": "USA",
"state": "New York",
"city": "New York 2",
},
{
"country": "CANADA",
"state": "British Columbia",
"city": "Vancovour",
}
];
for (i = 0; i < json.length; i++) {
$("#country").append("<option value=" + json[i]["country"] + ">" + json[i]["country"] + "</option>");
$("#state").append("<option value=" + json[i]["country"] + ">" + json[i]["state"] + "</option>");
$("#city").append("<option value=" + json[i]["country"] + ">" + json[i]["city"] + "</option>");
}
$("#state").change(function() {
$("#country")[0].selectedIndex = $(this)[0].selectedIndex
$("##city")[0].selectedIndex = $(this)[0].selectedIndex
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="myform" id="myForm">
<select name="opttwo" id="country" size="1">
<option value="" selected="selected">Please select state </option>
</select>
<br>
<br>
<select name="optone" id="state" size="1">
<option value="" selected="selected">Please Select country first</option>
</select>
<br>
<br>
<select name="optthree" id="city" size="1">
<option value="" selected="selected">Please select country first</option>
</select>
</form>
I have tried to make it like this. what should I add?
var json = [{
"country": "USA",
"state": "LOS ANGELES",
"city": "LOS ANGELES"
},
{
"country": "USA",
"state": "LOS ANGELES",
"city": "LOS ANGELES 2"
},
{
"country": "USA",
"state": "New York",
"city": "New York",
},
{
"country": "USA",
"state": "New York",
"city": "New York 2",
},
{
"country": "CANADA",
"state": "British Columbia",
"city": "Vancovour",
}
];
function addElementsFor(c, v, index) {
var tracker = [];
for (var i = 0, o; o = json[i]; i++) {
if (!!v && !!index && o[v] !== json[index][v]) {
continue;
}
if (tracker.indexOf(o[c.id]) !== -1) {
continue;
}
tracker.push(o[c.id]);
var option = document.createElement('option');
option.value = i;
option.innerText = o[c.id];
c.appendChild(option);
}
return c
}
function populateSubCategory(c, v, index) {
var state = document.getElementById(c);
state.disabled = false;
while (state.firstChild) state.firstChild.remove();
var option = document.createElement('option');
option.value = -1;
option.innerText = '----';
state.appendChild(option);
if (index * 1 < 0) return;
return addElementsFor(state, v, index);
}
window.addEventListener('load', function() {
addElementsFor(document.getElementById('country')).addEventListener('change', function(ev) {
populateSubCategory('state', ev.target.id, ev.target.value).addEventListener('change', function(ev) {
populateSubCategory('city', ev.target.id, ev.target.value).addEventListener('change', function(ev) {
if (ev.target.value * 1 < 0) {
return;
}
var country = document.getElementById('country');
var state = document.getElementById('state');
var city = ev.target;
if (json.hasOwnProperty(country.value) && json.hasOwnProperty(state.value) && json.hasOwnProperty(city.value)) {
console.log('country: %s state: %s city: %s', json[country.value]['country'], json[state.value]['state'], json[city.value]['city']);
}
})
})
})
});
<form name="myform" id="myForm">
<select name="opttwo" id="country" size="1">
<option value="-1" selected="selected">Please select state </option>
</select>
<br>
<br>
<select name="optone" id="state" size="1">
<option value="-1" selected="selected">Please Select country first</option>
</select>
<br>
<br>
<select name="optthree" id="city" size="1">
<option value="-1" selected="selected">Please select country first</option>
</select>
</form>
You need to check if there is already a select element with the same content before adding it again or you will end up with duplicates.
Check this thread: https://stackoverflow.com/a/9791018/5211055
Related
This question already has answers here:
Filter array of objects on all properties value
(3 answers)
Filter array of objects by multiple properties and values
(4 answers)
Closed 1 year ago.
I am trying to filter through a few objects in a massive array, please find a few lines of it below:
var dest = [{
"city": "Glendale",
"country": "Armenia",
"admin_name": "Adana Eyalet"
}, {
"city": "Globe",
"country": "United States, USA",
"admin_name": "Arizona"
}, {
"city": "Kingman-Butler",
"country": "United Kingdom",
"admin_name": "Wales"
}]
And I have only one input field to search through these objects - city, country.
I am using the following code:
var admin_name = dest.filter(function(item) {
return item['admin_name'].toLowerCase().indexOf(searchText.toLowerCase()) != -1
});
But haven't got a clue how to achieve my task. Sorry just started learning javascript.
Thank you for your help.
check this one:
var dest = [
{ city: "Glendale", country: "Armenia", admin_name: "Adana Eyalet" },
{ city: "Globe", country: "United States, USA", admin_name: "Arizona" },
{ city: "Kingman-Butler", country: "United Kingdom", admin_name: "Wales" },
];
function searchInAllProp(object, textsearch) {
for (a in object)
if (object[a].includes(textsearch))
return object;
return undefined;
}
let f = dest.filter(t => searchInAllProp(t, "United"));
console.log(f);
Had too much time to make it interactive.
const searchBtn = document.querySelector("#search-btn");
var dest = [
{ "city": "Glendale", "country": "Armenia", "admin_name": "Adana Eyalet" },
{ "city": "Globe", "country": "United States, USA", "admin_name": "Arizona" },
{ "city": "Kingman-Butler", "country": "United Kingdom", "admin_name": "Wales" }
];
searchBtn.addEventListener('click', () => {
const searchText = document.querySelector("#search-text").value;
const radio = document.querySelectorAll("input[type=radio]");
const arr = Array.from(radio);
const searchKey = arr.find(item => item.checked).id;
if(searchKey) {
const filteredArray = dest.filter(item => {
return item[searchKey].toLowerCase() === searchText.toLowerCase()
});
document.querySelector('span').innerHTML = filteredArray.length ? JSON.stringify(filteredArray) : "No results found";
}
});
<input type="text" id="search-text" />
<br />
<br />
<input type="radio" id="city" name="search-param">
<label>City</label>
<input type="radio" id="country" name="search-param">
<label>Country</label>
<br />
<br />
<button type="button" id="search-btn"> Search !! </button>
<br />
<br />
<span id="results"></span>
How can I make it so when I select an option it will only populate that one area?
I only want the specific places in that area.
example picture.]
Example of the output (1)
Example of the output (2)
this is the json code that I want to have a function and connect the two or more files.
json file 1
{
"code": "010000000",
"name": "Ilocos Region",
"altName": "Region I"
}
json file 2
{
"code": "012800000",
"name": "Ilocos Norte",
"altName": null,
"region": "010000000"
},
{
"code": "012900000",
"name": "Ilocos Sur",
"altName": null,
"region": "010000000"
},
{
"code": "013300000",
"name": "La Union",
"altName": null,
"region": "010000000"
},
{
"code": "015500000",
"name": "Pangasinan",
"altName": null,
"region": "010000000"
}
here is the code
html part
<div class="container form-group" style="width:600px; margin-top: 10vh">
<form action="" method="GET" id="addform">
<div class="form-group">
<select name="region" id="region" class="form-control input-sm" required>
<option value="">Select Region</option>
</select>
</div>
<div class="form-group">
<select name="province" id="province" class="form-control input-sm" required>
<option value="">Select Province</option>
</select>
</div>
</form>
</div>
<script>
$(function(){
let regionOption;
let provinceOption;
//FOR REGION
$.getJSON('regions.json', function(result){
regionOption += `<option value="">Select Region</option>`;
$.each(result, function(i, region){
regionOption += `<option value='${region.code}'> ${region.altName}</option>`;
});
$('#region').html(regionOption);
});
//FOR PROVINCE
$('#region').change(function(){
$.getJSON('provinces.json', function(result){
provinceOption += `<option value="">Select Province</option>`;
$.each(result, function(region, province){
provinceOption += `<option value='${province.name}'> ${province.name}</option>`;
});
$('#province').html(provinceOption);
});
});
});
</script>
my failed attempt is this part :
$('#region').change(function(){
if($(this).val() === $(this).val()){
$.getJSON('provinces.json', function(result){
provinceOption += `<option value="">Select Province</option>`;
$.each(result, function(region, province){
provinceOption += `<option value='${province.name}'> ${province.name}</option>`;
});
$('#province').html(provinceOption);
});
}
});
You can use .filter() to filter your json return inside ajax then inside this compare value of select-box with all values of region if they matches get that data . Finally loop through filter datas and show them inside your select-box.
Demo Code :
//just for demo :)
var result = [{
"code": "010000000",
"name": "Ilocos Region",
"altName": "Region I"
}, {
"code": "010000002",
"name": "Ilocos Region2",
"altName": "Region 2"
}]
var json2 = [
{
"code": "012800000",
"name": "Ilocos Norte",
"altName": null,
"region": "010000000"
},
{
"code": "012900000",
"name": "Ilocos Sur",
"altName": null,
"region": "010000000"
},
{
"code": "013300000",
"name": "La Union",
"altName": null,
"region": "010000002"
},
{
"code": "015500000",
"name": "Pangasinan",
"altName": null,
"region": "010000002"
}
]
$(function() {
let regionOption;
let provinceOption;
//FOR REGION
/* $.getJSON('regions.json', function(result) {*/
regionOption += `<option value="">Select Region</option>`;
$.each(result, function(i, region) {
regionOption += `<option value='${region.code}'> ${region.altName}</option>`;
});
$('#region').html(regionOption);
/* });*/
$('#region').change(function() {
var values = $(this).val()
var provinceOption = ""
/*$.getJSON('provinces.json', function(json2) {*/
//filter your json return..
var items = $(json2)
.filter(function(i, n) {
return n.region === values; //get value where region is same
});
provinceOption += `<option value="">Select Province</option>`;
//loop through dates
$.each(items, function(region, province) {
provinceOption += `<option value='${province.name}'> ${province.name}</option>`;
});
$('#province').html(provinceOption);
/* });*/
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="container form-group" style="width:600px; margin-top: 10vh">
<form action="" method="GET" id="addform">
<div class="form-group">
<select name="region" id="region" class="form-control input-sm" required>
<option value="">Select Region</option>
</select>
</div>
<div class="form-group">
<select name="province" id="province" class="form-control input-sm" required>
<option value="">Select Province</option>
</select>
</div>
</form>
</div>
I have a collection of objects in JSON that look like this and is assigned to the $rootScope.filteredData object:
{
"Id": 1,
"Compound": "Compound Name",
"Compound_2": "",
"Number": "XXXX-016",
"Phase": "2",
"TherapeuticArea": "Therapy Area",
"Locations": [{
"Region": "USA",
"Sites": [{
"Id": 306,
"TrialId": 3,
"SiteName": "Arizona PC - HAL",
"Address1": "",
"Address2": "4555 W Lowland Ave # 400",
"City": "Phoenix",
"State": "AZ",
"ZipCode": "99999",
"Province": "USA",
"Latitude": "66.5062203",
"Longitude": "-52.033464",
"Region": "USA"
}, {
"Id": 307,
"TrialId": 3,
"SiteName": "Arizona Associates, PC - HOPE",
"Address1": "",
"Address2": "811 S. Wilmot Rd. Suite 209",
"City": "Tucson",
"State": "AZ",
"ZipCode": "99999",
"Province": "USA",
"Latitude": "14.2140875",
"Longitude": "-120.8579021",
"Region": "USA"
}, {
"Id": 308,
"TrialId": 3,
"SiteName": "Benaroya Research Institute/Virginia Mason Medical Center",
"Address1": "",
"Address2": "1100 Tenth Avenue",
"City": "Seattle",
"State": "WA",
"ZipCode": "99999",
"Province": "USA",
"Latitude": "41.6094749",
"Longitude": "-163.3279078",
"Region": "USA"
}]
}]
}
I have 3 select lists that show all of the values in the "Compound", "Phase" and "TherapeuticArea" fields, and 3 select lists that show the Region, State and City. Selecting an item from each select list allows you filter the view of this information based on those six values.
I'm filtering these items currently in markup with Angular's built in filters, but need to rewrite this in code. Using .forEach, I'm able to get the filtering working for each item individually, but not cooperatively like it does with the Angular filter's. For example, if I filter on just "Compound" or "Phase", I get those results as I should. But if I filter on "Compound" AND "Phase" or any combination of the three filters, I'm no getting the results that I expect.
I have an inner .forEach that does another loop thru the selections to get the locations lat/lng (which is fed to another method that plots them on a map). That part seems to be working like it should. But the outer part does not.
Here's the code:
$scope.mapSelections = function(region, state, city, therapy, phase, compound) {
$rootScope.filteredPins = [];
if (!$scope.selectRegion) {
var region = '';
} else {
var region = $scope.selectRegion.Region;
}
if (!$scope.selectState) {
var state = '';
} else {
var state = $scope.selectState.StateName;
}
if (!$scope.selectCity) {
var city = '';
} else {
var city = $scope.selectCity.CityName;
}
if (!$scope.selectTherapy) {
var therapy = '';
} else {
var therapy = $scope.selectTherapy;
}
if (!$scope.selectPhase) {
var phase = '';
} else {
var phase = $scope.selectPhase;
}
if (!$scope.selectCompound) {
var compound = '';
} else {
var compound = $scope.selectCompound;
}
$rootScope.filteredData.forEach(function(itemElement, itemIndex) {
if ((itemElement.TherapeuticArea === therapy && therapy != '') || (itemElement.Compound === compound && compound != '') || (itemElement.Phase === phase && phase != '')) {
console.log('you have a hit on : ' + therapy + ' / Phase: ' + phase + ' / Compound: ' + compound);
itemElement.Locations.forEach(function(locationElement, locationIndex) {
if (locationElement.Region === region || !region) {
locationElement.Sites.forEach(function(siteElement, siteIndex) {
if ((siteElement.State == state && !city) || (siteElement.City == city && siteElement.State == state) || (!state && !city)) {
if (siteElement.Longitude != '' && siteElement.Latitude != '') {
$rootScope.filteredPins.push(siteElement);
$rootScope.filteredDataMapItems.push(itemElement);
// console.table(filteredPins)
return false;
}
}
});
}
});
}
});
};
<column>
<select name="selectRegion" class="form-control" ng-model="selectRegion" ng-change="regionSelected(); mapSelections(selectRegion.Region, null, null, selectTherapy, selectPhase, selectCompound)" ng-options="location as location.Region for location in locationObject | orderBy: location.Region:reverse track by location.Region">
<option value="">Select Region</option>
</select>
<select name="selectState" class="form-control" ng-disabled="!selectRegion" ng-model="selectState" ng-change="mapSelections(selectRegion.Region, selectState.StateName, null, selectTherapy, selectPhase, selectCompound)" ng-options="state as state.StateName for state in selectRegion.States | unique: 'state.StateName' | orderBy: 'StateName' ">
<option value="">{{regionSelectMsg}}</option>
</select>
<select name="selectCity" class="form-control" ng-disabled="!selectState" ng-model="selectCity" ng-change="mapSelections(selectRegion.Region, selectState.StateName, selectCity.CityName, selectTherapy, selectPhase, selectCompound)" ng-options="city as city.CityName for city in selectState.Cities | unique: 'city.CityName' | orderBy: 'CitytName' ">
<option value="">Select City</option>
</select>
</column>
<column>
<select name="selectTherapy" class="form-control" ng-model="selectTherapy" ng-options="data.TherapeuticArea as data.TherapeuticArea for data in dataObject | unique: 'TherapeuticArea' | orderBy: 'TherapeuticArea' " ng-change="mapSelections(null, null, null, selectTherapy, selectPhase, selectCompound)">
<option value="">Select Therapeutic Area</option>
</select>
<select name="selectPhase" class="form-control" ng-model="selectPhase" ng-options="data.Phase as ('Phase ' + data.Phase) for data in dataObject | unique: 'Phase' | orderBy: 'Phase' : reverse " ng-change="mapSelections(null, null, null, selectTherapy, selectPhase, selectCompound)">
<option value="">Select Phase</option>
</select>
<select name="selectCompound" class="form-control" ng-model="selectCompound" ng-options="data.Compound as data.Compound + ' ' + data.Compound_2 for data in dataObject | unique: 'Compound' | orderBy: 'Compound' " ng-change="mapSelections(null, null, null, selectTherapy, selectPhase, selectCompound)">
<option value="">Select Compound</option>
</select>
</column>
I'm also using underscoreJS in this project, and if there's an underscore method that is best for filtering these types of conditions, I'm open to using that.
I just needed to keep the filtered results on the same object that I was filtering on, so each iterative filter further whittled down the object to the desired data set.
if (therapy != '') {
filteredPins = _.filter(filteredPins, function(item) {
return item.TherapeuticArea === therapy;
});
}
if (phase != '') {
filteredPins = _.filter(filteredPins, function(item) {
return item.Phase === phase;
});
}
if (compound != '') {
filteredPins = _.filter(filteredPins, function(item) {
return item.Compound === compound;
});
}
I'am trying to create search box for state districts and villages , but I'am enable to fetch data into combobox.
I have tried so many other way to get data into select boxes they doesn't work. Below is the code I've so far:
HTML:
<div class="dummy__item">
<select name="state_id" id="state_id" tabindex="1">
<option value="">-- Select state --</option>
</select>
</div>
<div class="dummy__item">
<select name="district_id" id="district_id" tabindex="2">
<option value="">-- Select district --</option>
</select>
</div>
<div class="dummy__item">
<select name="village_id" id="village_id" tabindex="3">
<option value="">-- Select village --</option>
</select>
</div>
JS:
<!-- language: lang-js -->
function loadlist(selobj, url) {
$(selobj).empty();
$(selobj).append('<option value="0">--Select Category--</option>')
$(selobj).append(
$.map(jsonList, function(el, i) {
return $('<option>').val(el.slno).text(el.state)
}));
}
loadlist($('select#state_id').get(0), jsonList);
You can do the following (Check the revision history for a shorter version which made use of underscorejs):
The comments should help you get an idea. check https://api.jquery.com/ for detailed information regarding the jQuery methods used.
$(function() {
insert($('#state_id'), plucker(records, 'state'));
//------------------------^ grabs unique states
//--^ populate state list on DOM ready
$('select').on('change', function() {
var category = this.id.split('_id')[0];
var value = $(this).find('option:selected').text();
switch (category) {
case 'state':
{
insert($('#district_id'), plucker(filter(records, 'state', value),'district'));
//-^ insert plucked results to DOM
//------------------------^ plucks districts from filter results
//--------------------------------^ filters districts belonging to selected state
break;
}
case 'district':
{
insert($('#village_id'), plucker(filter(records, 'district', value),'village'));
break;
}
}
});
function plucker(arr, prop) {
// grabs unique items from the required property such as state, district etc from the results
return $.map(arr, function(item) {
return item[prop]
}).filter(function(item, i, arr) {
return arr.indexOf(item) == i;
});
}
function filter(arr, key, value) {
// filters the records matching users selection
return $.grep(arr, function(item) {
return item[key] == value;
});
}
function insert(elm, arr) { // inserts the results into DOM
elm.find('option:gt(0)').remove();
$.each(arr, function(i,item) {
elm.append($('<option>', {
value: i,
text: item
}));
});
}
});
var records = [{
"slno": "1",
"state": "Maharashtra",
"constituency": "Parbhani",
"mp": "Shri Sanjay Haribhau Jadhav",
"district": "Parbhani",
"block": "Jintur",
"village": "Kehal",
"latitude": "77.7",
"longitude": "19.33"
}, {
"slno": "2",
"state": "Maharashtra",
"constituency": "Shirur",
"mp": "Shri Shivaji Adhalrao Patil",
"district": "Pune",
"block": "Shirur",
"village": "Karandi",
"latitude": "77.7",
"longitude": "19.33"
}, {
"slno": "3",
"state": "Maharashtra",
"constituency": "Amravati",
"mp": "Shri Anandrao Vithoba Adsul",
"district": "Amravati",
"block": "Amravati",
"village": "Yavli Shahid",
"latitude": "77.7",
"longitude": "19.33"
}]
$(function() {
insert($('#state_id'), plucker(records, 'state'));
//------^ populate states list on DOM ready
$('select').on('change', function() {
var category = this.id.split('_id')[0];
var value = $(this).find('option:selected').text();
switch (category) {
case 'state':
{
insert($('#district_id'), plucker(filter(records, 'state', value), 'district'));
break;
}
case 'district':
{
insert($('#village_id'), plucker(filter(records, 'district', value), 'village'));
break;
}
}
});
function plucker(arr, prop) {
// grabs unique items from the required property such as state, district etc from the results
return $.map(arr, function(item) {
return item[prop]
}).filter(function(item, i, arr) {
return arr.indexOf(item) == i;
});
}
function filter(arr, key, value) {
// filters the records matching users selection
return $.grep(arr, function(item, i) {
return item[key] === value;
});
}
function insert(elm, arr) {
// inserts the results into DOM
elm.find('option:gt(0)').remove();
$.each(arr, function(i, item) {
elm.append($('<option>', {
value: i,
text: item
}));
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dummy__item">
<select name="state_id" id="state_id" tabindex="1">
<option value="">-- Select state --</option>
</select>
</div>
<div class="dummy__item">
<select name="district_id" id="district_id" tabindex="2">
<option value="">-- Select district --</option>
</select>
</div>
<div class="dummy__item">
<select name="village_id" id="village_id" tabindex="3">
<option value="">-- Select village --</option>
</select>
</div>
In your above code you have made the following mistake,
1.Extra close bracket
$.map(jsonList, function (el, i) {
return $('<option>').val(el.slno).text(el.state)
}));
Update it as
$.map(jsonList, function (el, i) {
return $('<option>').val(el.slno).text(el.state)
});
The looping of json object
$.map(jsonList.listval, function (el, i) {
$('#state_id').append('<option value="'+el.slno+'" attState="'+el.state+'">'+el.state+'</option>');
});
To avoid multiple times the same state repetition, before inserting the option you need to check if the entry is already exist in option if not exist then add it to the select, for this I have introduced a new option attribute "attState". Please look in to the code you will understand what I have done..
$.map(jsonList.listval, function (el, i) {
if ($("#yourSelect option[attState='" + el.state + "']").length == 0) {
$('#yourSelect').append('<option value="' + el.slno + '" attState="' + el.state + '">' + el.state + '</option>');
}
});
For reference refer
Try:
function createOptiolist(list, name) {
var state = list.map(function(obj) {
return obj[name];
});
return state = state.filter(function(v, i) {
return state.indexOf(v) == i;
});
}
var state = createOptiolist(jsonList.listval, "state");
$.each(state, function(i, el) {
$('#state_id').append('<option value="' + el + '">' + el + '</option>');
});
$('#state_id').on('change', function() {
var state = $(this).find('option:selected').val();
$('#district_id').empty();
$.each(jsonList.listval, function(i, el) {
if (el.state == state) {
$('#district_id').append('<option value="' + el.district + '">' + el.district + '</option>');
}
})
});
$('#district_id').on('change', function() {
var district = $(this).find('option:selected').val();
$('#village_id').empty();
$.each(jsonList.listval, function(i, el) {
if (el.district == district) {
$('#village_id').append('<option value="' + el.slno + '">' + el.village + '</option>');
}
})
});
DEMO
DEMO with ajax
Try this plz
HTML
<div class="dummy__item">
<select name="state_id" id="state_id" tabindex="1">
<option value="">-- Select state --</option>
</select>
</div>
<div class="dummy__item">
<select name="district_id" id="district_id" tabindex="2">
<option value="">-- Select district --</option>
</select>
</div>
<div class="dummy__item">
<select name="village_id" id="village_id" tabindex="3">
<option value="">-- Select village --</option>
</select>
</div>
JQUERY
$(document).ready(function(){
// JSON list
var jsonList = {"listval" : [
{
"slno": "1",
"state": "Maharashtra",
"constituency": "Parbhani",
"mp": "Shri Sanjay Haribhau Jadhav",
"district": "Parbhani",
"block": "Jintur",
"village": "Kehal",
"latitude": "77.7",
"longitude": "19.33"
},
{
"slno": "2",
"state": "Maharashtra",
"constituency": "Shirur",
"mp": "Shri Shivaji Adhalrao Patil",
"district": "Pune",
"block": "Shirur",
"village": "Karandi",
"latitude": "77.7",
"longitude": "19.33"
},
{
"slno": "3",
"state": "TEXAS",
"constituency": "XYZ",
"mp": "Shri ABC",
"district": "dist1",
"block": "block1",
"village": "Yavli Shahid",
"latitude": "77.7",
"longitude": "19.33"
},
{
"slno": "4",
"state": "Maharashtra",
"constituency": "Amravati",
"mp": "Shri Anandrao Vithoba Adsul",
"district": "Amravati",
"block": "Amravati",
"village": "Yavli Shahid",
"latitude": "77.7",
"longitude": "19.33"
}]}
// JSON LIST
function loadlist(selobj, url) {
var categories = [];
$(selobj).empty();
$(selobj).append('<option value="0">--Select Category--</option>')
$(selobj).append(
$.map(jsonList.listval, function (el, i) {
if ($.inArray(el.state, categories)==-1) {
categories.push(el.state);
return $('<option>').val(el.slno).text(el.state);
console.log($(el.state));}
}));
}
loadlist($('#state_id').get(0), jsonList);
});
I know that there are a lot of this questions being posted online but I still have difficulty finding what I need.
Currently I have found something that is doing 3 chained dropdown selection maximum. I needed to have 4 and I have tried editing the script but it's not working.
Below is the code that I have edited, is there anything wrong with my code?
<html>
<head>
<script type="text/javascript">
// State lists
var states = new Array();
states[0] = new Array('Alberta','British Columbia','Ontario');
states[1] = new Array('Baja California','Chihuahua','Jalisco');
states[2] = new Array('California','Florida','New York');
// Province lists
var provinces = new Array();
provinces[0] = new Array();
provinces[0][0] = new Array("Province1", "Province2");
// City lists
var cities = new Array();
cities[0][0] = new Array();
cities[0][0][0] = new Array('Edmonton','Calgary');
cities[0][0][1] = new Array('Victoria','Vancouver');
function setStates(){
cntrySel = document.getElementById('country');
stateList = states[cntrySel.selectedIndex];
changeSelect('state', stateList);
setProvinces();
}
function setProvinces(){
cntrySel = document.getElementById('country');
stateSel = document.getElementById('state');
provinceList = provinces[cntrySel.selectedIndex][stateSel.selectedIndex];
changeSelect('province', provinceList);
setCities();
}
function setCities(){
cntrySel = document.getElementById('country');
stateSel = document.getElementById('state');
provinceList = document.getElementById('province');
cityList = cities[cntrySel.selectedIndex][stateSel.selectedIndex][provinceList.selectedIndex];
changeSelect('city_town_district', cityList);
}
function changeSelect(fieldID, newList) {
selectField = document.getElementById(fieldID);
selectField.options.length = 0;
for (i=0; i<newList.length; i++) {
selectField.options[selectField.length] = new Option(newList[i], newList[i], newList[i]);
}
}
</script>
</head>
<body onload="setStates();">
<form name="test">
Country:
<select name="country" id="country" onchange="setStates();">
<option value="Canada">Canada</option>
<option value="Mexico">Mexico</option>
<option value="United States">United States</option>
</select>
<br>
State:
<select name="state" id="state" onchange="setProvinces();">
<option value="">Please select a State</option>
</select>
<br>
Province:
<select name="province" id="province" onchange="setCities();">
<option value="">Please select a Province</option>
</select>
<br>
City:
<select name="city_town_district" id="city_town_district">
<option value="">Please select a City</option>
</select>
</form>
</body>
</html>
Any help will be much appreciated! Thanks in advance!
Old question, one answer and everybody have to do this sometimes.
The year is 2018 and I find a easy way to do this. Easy to add, edit and receive data from server. Bye!
JSFiddle
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<select name="slc1" id="slc1" onchange="_1sel();"></select>
<select name="slc2" id="slc2" onchange="_2sel();"></select>
<select name="slc3" id="slc3" onchange="_3sel();"></select>
<select name="slc4" id="slc4"></select>
<script>
//just call the method when the select change
var slc1 = document.getElementById("slc1");
var slc2 = document.getElementById("slc2");
var slc3 = document.getElementById("slc3");
var slc4 = document.getElementById("slc4");
var dataObj = {//is a valid json
"brazil": {
"sp": {
"sp1": ["sp1A", "sp1B"],
"sp2": ["sp2A"]
},
"mg": {
"mg1": ["mg1A", "mg1B"],
"mg2": ["mg2A", "mg1B"]
},
"rj": {
"rj1": ["rj1A", "rj1B", "rj1C"],
"rj2": ["rj2A", "rj1B"]
}
},
"usa": {
"ny": {
"ny1": ["ny1A","ny1B","ny1C"],
"ny2": ["ny2A"]
},
"tx": {
"tx1": ["tx1A"]
}
},
"uk": {
"ld": {
"ld1": ["ld1A","ld1B","ld1C"],
"ld2": ["ld2A"]
},
"hm": {
"hm1": ["hm1A", "hm1B"]
}
}
}
let ctrs = Object.keys(dataObj);//countries - Object.keys return an array
cmo(ctrs, slc1);//push values to select one
_1sel();//call the first method of chain
//slc1.value = "usa"
//slc1.dispatchEvent(new Event('change'));
function _1sel() {
slc2.innerHTML = "";//clear the target select
let cities = Object.keys(dataObj[slc1.value]);//get the cities from country as array
cmo(cities, slc2);//push values to select two
_2sel();//call the second method of chain
}
function _2sel() {
slc3.innerHTML = "";//clear
let zones = Object.keys(dataObj[slc1.value][slc2.value]);//get the zones from country and city as array
cmo(zones, slc3);//push values to select three
_3sel();//call the third method of chain
}
function _3sel() {
slc4.innerHTML = "";//clear
let staffs = dataObj[slc1.value][slc2.value][slc3.value];//no Obj.keys here, just get the array of values
cmo(staffs, slc4);//push values to select four
}
function cmo(arr, s) {//create options and add to select
arr.forEach(o => {
let opt = document.createElement("option");
opt.value = o;
opt.innerHTML = o;
s.add(opt);
});
}
</script>
</body>
</html>
This is not perfect by any means but it should get you going. Instead of having unrelated arrays I suggest you use some object oriented principles. I've chosen to use JSON to describe the relationships in the data. The other advantage to using JSON is that many server side languages have JSON serializers available to them.
I have kept as much of your code as possible so there is some familiarity for you. However inline event handling is not considered best practice these days. You should look at Event Listeners/Handlers instead. Or if it was me I would be using jQuery as it irons out much of the cross browser issues you can come across.
/*Use JSON to describe data and its relationship*/
var countries = [{
"CountryName": "Canada",
"States": [{
"StateName": "British Columbia",
"Provences": [{
"ProvenceName": "BC P1",
"Cities": ["Vancouver"]
}, {
"ProvenceName": "BC P2",
"Cities": ["Whistler"]
}]
}, {
"StateName": "Ontario ",
"Provences": [{
"ProvenceName": "Ot 1",
"Cities": ["Ontario"]
}, {
"ProvenceName": "Ot 2",
"Cities": ["Toronto"]
}]
}]
}, {
"CountryName": "United States",
"States": [{
"StateName": "New York",
"Provences": [{
"ProvenceName": "NY P1",
"Cities": ["New York", "New Jersy"]
}, {
"ProvenceName": "NY P2",
"Cities": ["Buffalo"]
}]
}, {
"StateName": "California",
"Provences": [{
"ProvenceName": "South",
"Cities": ["Los Angeles", "San Dieago"]
}, {
"ProvenceName": "North",
"Cities": ["San Francisco"]
}]
}]
}];
var selectedCountry;
var selectedState;
var selectedProvence;
var stateList = document.getElementById("state");
var provenceList = document.getElementById("province");
var cityList = document.getElementById("city_town_district");
function setStates(selectedIndex) {
selectedCountry = countries[selectedIndex];
stateList.options.length = 0;
for (i = 0; i < selectedCountry.States.length; i++) {
stateList.options[stateList.length] = new Option(selectedCountry.States[i].StateName, selectedCountry.States[i].StateName, selectedCountry.States[i].StateName);
}
setProvinces(0);
}
function setProvinces(selectedIndex) {
selectedState = selectedCountry.States[selectedIndex];
console.log(selectedState)
provenceList.options.length = 0;
for (i = 0; i < selectedState.Provences.length; i++) {
provenceList.options[provenceList.length] = new Option(selectedState.Provences[i].ProvenceName, selectedState.Provences[i].ProvenceName, selectedState.Provences[i].ProvenceName);
}
setCities(0);
}
function setCities(selectedIndex) {
selectedProvence = selectedState.Provences[selectedIndex];
cityList.options.length = 0;
for (i = 0; i < selectedProvence.Cities.length; i++) {
cityList.options[cityList.length] = new Option(selectedProvence.Cities[i], selectedProvence.Cities[i], selectedProvence.Cities[i]);
}
}
Country:
<select name="country" id="country" onchange="setStates(this.selectedIndex);">
<option value="Canada">Canada</option>
<option value="United States">United States</option>
</select>
<br>State:
<select name="state" id="state" onchange="setProvinces(this.selectedIndex);">
<option value="">Please select a State</option>
</select>
<br>Province:
<select name="province" id="province" onchange="setCities(this.selectedIndex);">
<option value="">Please select a Province</option>
</select>
<br>City:
<select name="city_town_district" id="city_town_district">
<option value="">Please select a City</option>
</select>