当所有下拉列表相互链接时,如何过滤下拉列表中的值?

时间:2016-03-24 14:14:46

标签: javascript jquery html arrays json

我有三个下降。对于国家,地区/州和城市,如下:

enter image description here

以下是标记:

            <div class="form-group"> 
                <label for="country">Country</label>
                <select class="form-control" id="country">

                </select>               
            </div>
            <div class="form-group"> 
                <label for="region">Region</label>
                <select class="form-control" id="region">

                </select>
            </div>
            <div class="form-group"> 
                <label for="city">City</label>
                <select class="form-control" id="city">

                </select>
            </div>

在选择三个下拉列表中的任何一个中的值时,需要根据所有三个下拉列表中的选定值在任何时间点过滤其他两个下拉列表中的可用选项。 请注意:我使用的是jQuery。

到目前为止,我已经根据唯一一个更改的下拉值而不是考虑所有内容进行过滤,并且当用户转到Country时也会过滤值 - &gt;区域到 - &gt;市。如果用户自下而上,如何考虑其他下拉列表中的值以及过滤值,请说明City - &gt;地区 - &gt;国家也是?

$("#country").on('change', function(){

    var selectedCntry = $("#country option:selected").val();

    console.log(selectedCntry);
    var ddRegions = [];
    var ddCities = [];

    $.each(ddVals, function(i,val){
        if( val.country == selectedCntry){
            ddRegions.push(val.region);
            ddCities.push(val.city);
        }
    });

    if(ddRegions.length > 0){
            var regions = "<option value='none'>    Select Region </option>";
            $.each(ddRegions, function(i,val){

                regions += "<option value="+"'"+val+"'"+">"+val+"</option>";

            });

            $("#region").html(regions);
    }

    if(ddCities.length > 0){
         var cities = "<option value='none'>    Select City </option>";
         $.each(ddCities, function(i,val){
             cities += "<option value="+"'"+val+"'"+">"+val+"</option>";

         });
        $("#city").html(cities);
    }


});

$("#region").on("change",function(){
    var selectedReg = $("#region option:selected").val();
    console.log(selectedReg);

    var ddRegionBasedCity = [];

    $.each(ddVals, function(i,val){
        if( val.region == selectedReg){

            ddRegionBasedCity.push(val.city);
        }
    });

    if(ddRegionBasedCity.length > 0){
         var cities = "<option value='none'>    Select City </option>";
         $.each(ddRegionBasedCity, function(i,val){
             cities += "<option value="+"'"+val+"'"+">"+val+"</option>";

         });
        $("#city").html(cities);
    }


});

这里&#34; ddVals&#34;是一个带有json对象的数组的变量,我从中过滤这些值作为下拉列表中的选项。该数组如下所示:

[{
    "city": "Houston",
    "country": "United States",
    "region": "Texas"
}, {
    "city": "Oegstgeest",
    "country": "Netherlands ",
    "region": "South Holland"
}, {
    "city": "Houston",
    "country": "United States",
    "region": "Texas"
}, {
    "city": "Wellington",
    "country": "New Zealand ",
    "region": "-"
}, {
    "city": "London",
    "country": "United Kingdom",
    "region": "Great Britain"
}, {
    "city": "Federal Way",
    "country": "United States",
    "region": "Washington"
}, {
    "city": "Armonk",
    "country": "United States",
    "region": "New York"
}, {
    "city": "San Ramon",
    "country": "United States",
    "region": "California"
}, {
    "city": "New York City",
    "country": "United States",
    "region": "New York"
}, {
    "city": "Roseland",
    "country": "United States",
    "region": "New Jersey"
}]

2 个答案:

答案 0 :(得分:1)

我会去找一个sep。过滤功能:

// data is your location data (used in the filter method)
// might be better to remove this from global namespace.
var data = [{
  "city": "Houston",
  "country": "United States",
  "region": "Texas"
}];


/* @param filterBy the key for your ojects (city, country)
 * @param filterVal the value to check for
 */
function filterData( filterBy, filterVal) {
  return data.map(function(row) {return row}).filter(function(value) {
      if(value[filterBy] == filterVal) {
        return true;
      }
      return false;
  });
}

此功能可用于根据每个选择获取所有三个字段的过滤数组。以下jquery代码是未经测试的,更多伪代码用于演示如何使用过滤器:

$(".form-control select").on('change', function() {
    // using the field id as object-key.
    // second, call filterdata with the key and the current val.
    var identifier = this.id,
        fData = filterData( identifier, $(this).val());

    // now all you need to do is to loop over all your fields
    // and update all select fields by using the filtered Data..
    $(".form-control select").each(function() {
        var cid = this.id, c = '', 
        emptyText = $(this).find("option[value='']").text();
        // get the 'Please Select' for each field
        c += '<option value="">' + emptyText + '</option>';
        // loop over all available data elements of the filtered data
        // if the object-key is the same as current id, 
        // add a selection...
        for( var i=0, l = fData.length; i < l; i++) {
          foreach( prop in fData[i]) {
            if (prop == cid) {
              c +="<option value="+"'"+fData[i][cid]+"'"+">"+
                fData[i][cid]+"</option>";
            }
          } 
        }
        $(this).html(c);
    });
});

正如我所说,jQuery代码未经测试,但您可以通过直接调用它来轻松验证过滤方法,例如:

console.log(filterData( 'city', 'Roseland'));
console.log(filterData( 'region', 'New Jersey'));
console.log(filterData( 'country', 'United States'));

除此之外,由于下面的注释,这里是另一个可以一次处理所有字段值的过滤方法。您需要做的就是收集所有字段(及其键)的当前值,将其存储在对象中,filter方法将返回匹配的数据。 conditionAll是一个布尔标志,用于确定所有过滤器是否必须匹配(true)或仅一个(false)。

function multiFilterData( filters, conditionAll ) {
  return data.map(function(row) {return row}).filter(function(value) {
    for(var key in filters) {
      if( conditionAll && value[key] != filters[key]) {
        return false;
      } else if( !conditionAll && value[key] == filters[key]) {
        return true;
      }
    }
    return (conditionAll) ? true : false;
  });
}


// all conditions must fit (this won't work in many cases)
console.log(multiFilterData( {city:'Roseland',region:'-', country:'-'}, true ));
// one condition must fit
console.log(multiFilterData( {city:'Roseland',region:'-', country:'-'}, false ));

答案 1 :(得分:0)

我终于使用lodash来过滤json数据。它使我的任务变得非常容易和直接。我刚刚创建了一个函数,并在每个下拉列表的更改时调用它。下面的函数是从每个下拉列表中获取所选值,并将其传递给lodash提供的_filter方法。它现在返回过滤器,与传递的值匹配的有限json数据。后来我正在迭代生成标记并将其注入文档。同时,我通过设置它来保持selectedValue在每个下拉列表中保持不变。

function filterDropDown(ddVals){

    var selCity = $('#city').find(":selected").val();
    var selRegion = $('#region').find(":selected").val();
    var selCountry = $('#country').find(":selected").val();


    var selData = {};

    if( selCity !== "none"){
        selData['city'] = selCity;
    } 
    if(selRegion !== "none"){
        selData['region'] = selRegion;
    }
    if(selCountry !== "none"){
        selData['country'] = selCountry;
    }




    var filteredObj = _.filter(ddVals, selData);


    var ddCountries = [];
    var ddRegions = [];
    var ddCities = [];


    $.each(filteredObj, function(i,val){

        if(ddCountries.indexOf(val.country) == -1){
            ddCountries.push(val.country);
        }

        if(ddRegions.indexOf(val.region) == -1){
            ddRegions.push(val.region);
        }

        if(ddCities.indexOf(val.city) == -1){
            ddCities.push(val.city);
        }


    });

    if(ddCountries.length > 0){
        var countries = "<option value='none'>    Select Country </option>";
        $.each(ddCountries, function(i,val){
                countries += "<option value="+"'"+val+"'"+">"+val+"</option>";
        });
        $("#country").html(countries);
        $("#country option[value='"+selCountry+"']").prop('selected', true);
    }
    if(ddRegions.length > 0){
        var regions = "<option value='none'>    Select Region </option>";
        $.each(ddRegions, function(i,val){
                regions += "<option value="+"'"+val+"'"+">"+val+"</option>";
        });
        $("#region").html(regions);
        $("#region option[value='"+selRegion+"']").prop('selected', true);
     }
     if(ddCities.length > 0){
        var cities = "<option value='none'>    Select City </option>";
        $.each(ddCities, function(i,val){
             cities += "<option value="+"'"+val+"'"+">"+val+"</option>";
        });
        $("#city").html(cities);
        $("#city option[value='"+selCity+"']").prop('selected', true);
     }


}