将第四个框添加到动态下拉框中

Add fourth box to dynamic drop drop

本文关键字:添加 动态 四个      更新时间:2023-09-26

正如您从我的代码中看到的,我已经从另一个站点获得了它。

我想在页面上添加第四个下拉菜单。它需要第一次降落。类型下拉。

我的代码只允许3个动态下拉列表,它基本上是一个州、城市和国家的下拉列表,我已经修改以满足我的需求。

我已将其添加到jsfiddle 中

<tr>
    <td width="254" style="text-align: left;">
      <p>
        Type:
        <select name="Type" id="Type">
          <option value=""></option>
          <option value="Monthly">Monthly</option>
          <option value="Annually">Annually</option>
        </select>
    </p>
    <tr>
      <td width="254" style="text-align: left;">
        Box:
        <select name="country" id="country" onchange="setStates();">
          <option value=""></option>
          <option value="Sky HD">Sky HD</option>
          <option value="Sky+">Sky+</option>
          <option value="Sky Standard">Sky Standard</option>
        </select>
    </td>
    <td width="252" style="text-align: left;">
      <p>&nbsp;</p>
    </td>
  </tr>
<tr>
  <td style="text-align: left;">
    Product :
    <select name="state" id="state" onchange="setCities();">
      <option value=""></option>
    </select>
  </td>
  <td style="text-align: left;">
    <p>&nbsp; </p>
  </td>
</tr>
<tr>
  <td style="text-align: left;">
    Price :  
    <select name="city" type="text" id="city" />
  </td>
  <td style="text-align: left;">
    &nbsp;
  </td>
</tr>

Javascript代码

/* This script and many more are available free online at
The JavaScript Source!! http://www.javascriptsource.com
Created by: Michael J. Damato | http://developing.damato.net/ */
// State lists
var states = new Array();
states['Sky HD'] = new Array('Platinum', 'Gold', 'Diamond');
states['Sky+'] = new Array('Platinum', 'Gold', 'Diamond');
states['Sky Standard'] = new Array('Platinum', 'Gold', 'Diamond');
// City lists
var cities = new Array();
cities['Sky HD'] = new Array();
cities['Sky HD']['Platinum']          = new Array('£8.49');
cities['Sky HD']['Gold']          = new Array('£7.49');
cities['Sky HD']['Diamond']          = new Array('£6.49');
cities['Sky+'] = new Array();
cities['Sky+']['Platinum']          = new Array('£8.49');
cities['Sky+']['Gold']          = new Array('£7.49');
cities['Sky+']['Diamond']          = new Array('£6.49');
cities['Sky Standard'] = new Array();
cities['Sky Standard']['Platinum']          = new Array('£8.49');
cities['Sky Standard']['Gold']          = new Array('£7.49');
cities['Sky Standard']['Diamond']          = new Array('£6.49');
function setStates() {
  cntrySel = document.getElementById('country');
  stateList = states[cntrySel.value];
  changeSelect('state', stateList, stateList);
  setCities();
}
function setCities() {
  cntrySel = document.getElementById('country');
  stateSel = document.getElementById('state');
  cityList = cities[cntrySel.value][stateSel.value];
  changeSelect('city', cityList, cityList);
}
function changeSelect(fieldID, newOptions, newValues) {
  selectField = document.getElementById(fieldID);
  selectField.options.length = 0;
  for (i=0; i<newOptions.length; i++) {
    selectField.options[selectField.length] = new Option(newOptions[i], newValues[i]);
  }
}
// Multiple onload function created by: Simon Willison
// http://simonwillison.net/2004/May/26/addLoadEvent/
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}
addLoadEvent(function() {
  setStates();
});

如果我正确理解您的数据模型,那么它所基于的脚本并不理想。除了注释中提到的内容外,州/市场景还有一个层次结构,这似乎不适用于您的用例。无论我选择哪一个框,产品列表都是相同的,对吗?这种组合会产生独特的价格吗?

如果是这样的话,您开始使用的脚本与您想要的结果至少在两个方面有所不同:

  • 当另一个下拉列表发生变化时,更新其他下拉列表没有意义
  • 你根本不应该选择价格,所以这不需要是下拉列表

首先,我将定义一个可读的数据源,包括所有选项及其产生的价格:

var prices = [
    { type: 'monthly', box: 'Sky HD', product: 'Platinum', price: '$ 10' },
    { type: 'monthly', box: 'Sky HD', product: 'Gold', price: '$ 20' },
    { type: 'monthly', box: 'Sky HD', product: 'Diamond', price: '$ 30' },
    { type: 'monthly', box: 'Sky+', product: 'Platinum', price: '$ 40' },
    ...
];

之后,定义不同的过滤器。对于每个过滤的属性,我将假设存在一个具有相应classselect

var options = ['type','box','product'];

处理好后,对选项进行迭代,在数据源中找到该选项的唯一值,并填充下拉列表。此外,在每个下拉列表中添加一个on-change侦听器。

options.forEach(function(opt) {
    var drop = document.querySelector('.'+opt);
    var unique = Object.keys(prices.reduce(function(x,y) { return x[y[opt]] = 1, x; }, {}));
    unique.forEach(function(value) {
        var htmlOption = document.createElement('option');
        htmlOption.value = htmlOption.innerText = value;
        drop.options.add(htmlOption);
    });
    drop.onchange = function() {
        updatePrice();
    };
});

剩下的就是定义updatePrice,每次更改任何下拉列表时都会调用它。我们再次迭代所有属性,只筛选出与当前选择相匹配的价格。如果数据源设置正确,那么应该只剩下一个匹配项。你当然可以添加错误处理来验证:

function updatePrice() {
    var matches = prices;
    options.forEach(function(opt) {
        var drop = document.querySelector('.'+opt);
        matches = matches.filter(function(price) { return price[opt] == drop.value; });
    });
    document.querySelector('.price').innerText = matches[0].price;
};

完成。调用updatePrice一次以设置初始值:

updatePrice();

这是假设您的脚本位于body的最后。如果它们在head中,则需要将对updatePrice的调用以及下拉列表的设置推迟到DOMReady。

Fiddle

更新:为了与IE8兼容,方便函数Array.prototype.forEach已被重写为循环的正则函数;CCD_ 8、CCD_ 9和CCD_。

IE8更新了fiddle