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

时间:2015-11-12 14:24:37

标签: javascript

从我的代码中可以看出,我是从其他网站上看到的。

我想在页面中添加第四个下拉菜单。它需要首先下降。类型下拉。

我的代码只允许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();
});

1 个答案:

答案 0 :(得分:0)

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

如果是这样,您开始使用的脚本至少有两种方式与您想要的结果不同:

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

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

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' },
    ...
];

之后,定义不同的过滤器。对于每个已过滤的属性,我假设存在select且对应class

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

完成这些操作后,迭代选项,在数据源中找到该选项的唯一值并填充下拉列表。此外,为每个下拉列表添加一个on change listener。

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中。如果他们处于领先地位,您需要将调用推迟到updatePrice,以及设置下拉列表,直到DOMReady。

Fiddle

更新:对于IE8兼容性,便捷函数Array.prototype.forEach已被重写为常规for循环; Array.prototype.reduceArray.prototype.filterObject.prototype.keys已被大致模仿其行为的函数所取代。

IE8-updated fiddle