Javascript Chain Dropdown选择

时间:2015-01-27 04:20:24

标签: javascript html

我知道有很多问题在网上发布,但我仍然很难找到我需要的东西。

目前我发现了最多可以进行3链式下拉选择的内容。我需要有4个并且我已经尝试过编辑脚本但它没有工作。

以下是我编辑的代码,我的代码有什么问题吗?

    <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>

任何帮助将不胜感激!提前谢谢!

2 个答案:

答案 0 :(得分:0)

这无论如何都不是完美的,但它应该让你前进。我建议您使用一些面向对象的原则,而不是使用不相关的数组。我选择使用JSON来描述数据中的关系。使用JSON的另一个好处是许多服务器端语言都可以使用JSON序列化程序。

我保留了尽可能多的代码,因此对您有一定的了解。但是,如今内联事件处理不被视为最佳实践。你应该看一下Event Listeners/Handlers。或者,如果是我,我会使用jQuery,因为它可以解决您可能遇到的大部分跨浏览器问题。

/*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>

答案 1 :(得分:0)

老问题,一个答案,每个人有时都必须这样做。 今年是2018年,我找到了一种简便的方法。易于添加,编辑和接收来自服务器的数据。再见! 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>