简体   繁体   English

如何根据数据属性定位选择选项?

[英]How to target a select option based on data attribute?

I'm new to JavaScript and jQuery.我是 JavaScript 和 jQuery 的新手。 I'm trying to create something for a website I'm working on, but I can't figure this out.我正在尝试为我正在开发的网站创建一些东西,但我无法弄清楚。

How can I get jquery to show or hide a select option of a dropdown, based on the selected data attribute of another dropdown?如何根据另一个下拉列表的选定数据属性让 jquery 显示或隐藏下拉列表的选择选项?

IE, selecting option 2 in the first dropdown will show only options 1 and 3 in the second menu, and vice versa? IE,在第一个下拉菜单中选择选项 2 将只显示第二个菜单中的选项 1 和 3,反之亦然?

$(document).ready(function() {
    $("#make_id").change(function() {
        /* basically if data-make is = to selected data-id option, show option, 
           if it isn't, hide this option. seems, simple, but I can't figure it out... */
    })
})

<select id="make_id" >
  <option value="make option 1" data-id="18">option 1</option>
  <option value="make option 2" data-id="42">option 1</option>
</select>

<select id="model_id" >
  <option value="model option 1" data-make="42">option 1</option>
  <option value="model option 2" data-make="18">option 2</option>
  <option value="model option 3" data-make="42">option 3</option>
</select>
$("#make-id").change(function(e){
    var currentMake = $("#make-id").data("id");
    $("#model-id option").not("[data-make='"+currentMake+"']").hide();
    $("#model-id option").filter("[data-make='"+currentMake+"']").show();
}

In English:用英语:

Whenever make-id changes, get the data-id field from it.每当 make-id 更改时,从中获取 data-id 字段。

Select all the options under model-id then filter for ones that don't have the same data-make value.选择 model-id 下的所有选项,然后过滤那些没有相同 data-make 值的选项。 Hide those.隐藏那些。

Select all the options under model-id then filter for the ones that do have the same data-make value.选择 model-id 下的所有选项,然后筛选具有相同 data-make 值的选项。 Show those.显示那些。

TL;DR TL; 博士

I've changed the way your code works a little to make it work better for the way you want it to.我已经稍微改变了你的代码的工作方式,让它按照你想要的方式更好地工作。 Take a look at this fiddle .看看这个小提琴


So first of all, you can easily define a callback on the change event which can filter the second select box's option visibility.因此,首先,您可以轻松定义更改事件的回调,该回调可以过滤第二个选择框的选项可见性。 One problem you may come into if you do this is that "hidden" options will still be in the select's value if they were previously selected (as in Franz's answer ).如果您这样做,您可能会遇到的一个问题是,如果“隐藏”选项之前被选中(如Franz 的回答),它们仍将位于选择的值中。

Here's a slightly different approach in which everything is emptied and loaded dynamically from a JSON object that you define initially:这是一种稍微不同的方法,其中所有内容都从您最初定义的 JSON 对象中动态清空和加载:

1. Define your JSON object (data model) 1. 定义你的 JSON 对象(数据模型)

This could come from a database as well of course.这当然也可以来自数据库。

var makesAndModels = {
    "makes": [
    {"option_id": 1, "id": 18, "name": "make 1"},
    {"option_id": 2, "id": 42, "name": "make 2"}
  ],
  "models": [
    {"option_id": 1, "make_id": 42, "name": "make 2: model 1"},
    {"option_id": 2, "make_id": 18, "name": "make 1: model 1"},
    {"option_id": 3, "make_id": 42, "name": "make 2: model 2"}
  ]
};

2. Define methods to populate each select 2. 定义填充每个选择的方法

Your rules are simple:你的规则很简单:

  • To populate the makes, you need no conditions要填充品牌,您不需要任何条件
  • To populate the models, you need a make ID (foreign key)要填充模型,您需要一个制造 ID(外键)

function populateMakes() {
  var $make = $('#make_id');
  // Remove all options before starting
  $make.empty();

  // Loop the makes from the JSON data object
  $.each(makesAndModels.makes, function(key, make) {
    // Append new options for each make
    $('#make_id')
      .append(
        $('<option></option>')
          .data('id', make.id) // Assign the data-id attribute
          .attr('value', 'make option ' + make.option_id) // Give it a value
          .text(make.name) // Give it a label
        );
  });
}

The function above is simply emptying the #make_id select box, then looping the makes in the JSON data object and appending a new option element to the makes select for each result, setting the attributes as it goes.上面的函数只是清空#make_id选择框,然后循环 JSON 数据对象中的#make_id并将一个新的option元素附加到每个结果的#make_id select 中,同时设置属性。

Then to populate the models, we do the same thing for models as we did for makes, except we'll ignore any models that are for a different make.然后为了填充模型,我们对模型做与我们对品牌所做的相同的事情,除了我们将忽略用于不同品牌的任何模型。

function populateModels(makeId) {
  // Assign the selector to a variable to repeated use/Don't Repeat Yourself
  var $model = $('#model_id');
  // Remove all models in the select to start
  $model.empty();

  // Loop the models in the JSON object
  $.each(makesAndModels.models, function(key, model) {
    // Ignore any models for other makes
    if (model.make_id != makeId) {
      return;
    }

    // Append the new model to the select
    $model
      .append(
        $('<option></option>')
          .data('make', model.make_id) // Assign its data-make attribute
          .attr('value', 'model option ' + model.option_id) // Give it a value
          .text(model.name) // Give it a label
      );
  });
}

3. Simplified HTML 3. 简化的 HTML

Once you've got that framework, your HTML and event handlers are going to be very simple.一旦你有了那个框架,你的 HTML 和事件处理程序就会变得非常简单。

The HTML select boxes don't need any options since they're populated dynamically, although you may want to leave the ones you have there already in place to help with older browsers or browsers with Javascript turned off (cringe): HTML 选择框不需要任何选项,因为它们是动态填充的,尽管您可能希望保留已有的选项以帮助使用旧浏览器或关闭 Javascript 的浏览器(畏缩):

<!-- These are populated dynamically now! -->
<select id="make_id"></select>
<select id="model_id"></select>

4. Create your jQuery event handler 4. 创建你的 jQuery 事件处理程序

...and glue it all together: ...并将它们粘在一起:

$(document).ready(function() {
  // Populate the makes select box
  populateMakes();

  // Define what should happen when you change the make_id select
  $("#make_id").change(function() {
    // Find the currently selected make's ID from data-id
    var selectedMake = $(this).find('option:selected').data('id');
    populateModels(selectedMake);
  });

  // Trigger a change to populate the models the first time
  $('#make_id').change();
});

The trick above is that once you've populated the makes and defined your event handler for when the makes select box changes, you can to trigger the change event manually - this will cause populateModels() to be called with the first make in the list, and have the models for that make populated too.上面的技巧是,一旦您填充了制造商并定义了制造商选择框更改时的事件处理程序,您就可以手动触发change事件 - 这将导致使用列表中的第一个制造商调用populateModels() ,并且也填充了该模型的模型。

 $(document).ready(function() { $("#make_id").change(function() { if ($(this).val()=='make option 2') $("#model_id").find("option").eq(1).hide(); else $("#model_id").find("option").eq(1).show(); }) })
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <select id="make_id" > <option value="make option 1" data-id="18">option 1</option> <option value="make option 2" data-id="42">option 2</option> </select> <select id="model_id" > <option value="model option 1" data-make="42">option 1</option> <option value="model option 2" data-make="18">option 2</option> <option value="model option 3" data-make="42">option 3</option> </select>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM