jQuery foreach循环顺序

时间:2016-04-18 19:03:22

标签: jquery arrays loops foreach

我有一对选择框,用户必须先选择国家/地区,然后选择该国家/地区的城市或地区:

<select name="ListingCountry" id="ListingCountry">
 <option value="0">-- Choose the country --</option>
 <option value="1" selected="selected">United Kingdom</option>
</select>
<select name="ListingCity" id="ListingCity" class="city">
 <option value="0">-- Choose the city or region --</option>
</select>

第二个<select>需要根据第一个选择动态更新 - 即只选择英国时显示的英国城市和地区。

列表是从数据库生成的,并设置为数组:

var cityOptions =
{
 1 :
 [
  {
   37: "London",
   1: "Bedfordshire",
   2: "Berkshire",
   3: "Birmingham",
   ...
  }
 ]
};
朝向顶部的

1引用国家/地区ID。

ID号由数据库自动生成。我希望资本始终位于列表的顶部,并通过使用CityOrder字段并按CityOrder descending排序来在阵列打印中实现此目的 - 因此为什么伦敦(CityOrder 1}的CityOrder)位于列表的顶部,尽管其ID高于0 function updateCityOptions(currentCity) { var $countryAll = $("#ListingCity"); var $countrySel = $("#ListingCountry option:selected").val(); if($countrySel!=0) { $('#ListingCity option:gt(0)').remove(); $.each(cityOptions[$countrySel], function(k,v) { $.each(cityOptions[$countrySel][k], function(k2,v2) { if(k2==currentCity) { $countryAll.append($('<option selected="selected"></option>').attr("value", k2).text(v2)); } else { $countryAll.append($('<option></option>').attr("value", k2).text(v2)); } }); }); $(".city").fadeIn(300); } else { $('#ListingCity option:gt(0)').remove(); $(".city").fadeOut(300); } } 的其他ID。

然后我使用jQuery动态更新列表:

select

问题在于,选择国家时{{1}}框的顺序似乎是数组的数字顺序,而不是它在DOM中打印的顺序 - 即贝德福德郡出现列表中的第一个(身份证号码1)和伦敦在中间某处丢失。

任何线索?

2 个答案:

答案 0 :(得分:1)

对象属性不按您期望的顺序存储。当你迭代对象属性时 - 比如for ... in,它对对象执行{ 37: "London", 1: "Bedfordshire", 2: "Berkshire", 3: "Birmingham", ... } - 顺序将取决于几个因素。首先,它取决于您是否在ES6之前的JavaScript上运行:然后无法保证任何确定的顺序。

ES6对此进行了更改,请参阅"Sort JavaScript Object by Key",当对象属性为数字时,它们将按数字顺序迭代。

尽管如此,对于订单很重要的所有列表,我建议使用数组。而不是:

[
   { id: 37, name: "London"},
   { id: 1, name: "Bedfordshire"},
   { id: 2, name: "Berkshire"},
   { id: 3, name: "Birmingham"},
   ...
]

制作并使用以下内容:

<form id="msg_1" action="" method="post">
  <input type="text" data-uid="1" name="post_msg">
</form>
<form id="msg_2" action="" method="post">
  <input type="text" data-uid="2" name="post_msg">
</form>
<form id="msg_3" action="" method="post">
  <input type="text" data-uid="3" name="post_msg">
</form>

...并使您的代码适应该结构。

答案 1 :(得分:0)

我看了一下这一点,起初认为它应该与其他帖子类似,但是你不是按ID或名称(文本)排序,而是按其他值排序。为了促进这一点,我创建了一个包含所有国家和城市的对象,然后将它们放入。然后我使用sortOrder进行排序,将其作为data-sort推送到选项列表中,并执行以下操作:排序

我看到你的currentCity,但这可能会因国家变化而改变?因此,我通过在城市上放置isDefault:true为每个国家/地区设置“默认”。

我也从列表中推送了这些国家,默认情况下也是如此。

这对你的情况来说可能有些过分,但从中得到你想要的东西。

创建命名空间

var myApp = myApp || {};// create a namespace to use. 

添加国家/地区对象:

myApp.countries = [{
  "name": "United Kingdom",
  isDefault: true,
  id: 1,
  "cities": [{
    id: 1,
    name: "Bedfordshire",
    "sortOrder": 1,
    "isCapital": false
  }, {
    id: 2,
    name: "Berkshire",
    "sortOrder": 2,
    "isCapital": false
  }, {
    id: 3,
    name: "Birmingham",
    "sortOrder": 3,
    "isCapital": false
  }, {
    id: 4,
    name: "Brighton",
    "sortOrder": 4,
    "isCapital": false,
     isDefault:true
  }, {
    id: 5,
    name: "Buckinghamshire",
    "sortOrder": 6,
    "isCapital": false
  }, {
    id: 6,
    name: "Appleton",
    "sortOrder": 5,
    "isCapital": false
  }, {
    id: 37,
    name: "London",
    "sortOrder": 0,
    "isCapital": true
  }]
}, {
  "name": "Hackem",
  id: 2,
  "cities": [{
    id: 1,
    name: "Somecity",
    "sortOrder": 1,
    "isCapital": false
  }, {
    id: 2,
    name: "Waterton",
    "sortOrder": 2,
    "isCapital": false
  }, {
    id: 3,
    name: "Acre City",
    "sortOrder": 3,
    "isCapital": false
  }, {
    id: 4,
    name: "Jackson",
    "sortOrder": 4,
    "isCapital": false
  }, {
    id: 5,
    name: "Tolkenshire",
    "sortOrder": 6,
    "isCapital": false
  }, {
    id: 6,
    name: "Capital City",
    "sortOrder": 0,
    "isCapital": true
  }, {
    id: 37,
    name: "Paris",
    "sortOrder": 4,
    "isCapital": false
  }]
}, {
  "name": "NewCountry",
  id: 3,
  "cities": [{
    id: 1,
    name: "Skycity",
    "sortOrder": 1,
    "isCapital": false
  }, {
    id: 2,
    name: "DirtCity",
    "sortOrder": 2,
    "isCapital": false
  }, {
    id: 3,
    name: "Airville",
    "sortOrder": 3,
    "isCapital": false
  }, {
    id: 6,
    name: "Cape Town",
    "sortOrder": 0,
    "isCapital": true
  }, {
    id: 37,
    name: "Walla Walla",
    "sortOrder": 4,
    "isCapital": false
  }]
}];

将一些函数添加到要使用的命名空间:

myApp.arrayObj = myApp.arrayObj || {
  lookup: function(myArray, searchTerm, property, firstOnly) {
    var found = [];
    for (var i = 0; i < myArray.length; i++) {
      if (myArray[i][property] === searchTerm) {
        found.push(myArray[i]);
        if (firstOnly) break; //if only the first 
      }
    }
    return found;
  },
  updateCityOptions: function(countries) {
    var $cityAll = $("#ListingCity");
    // lookup by text
    var $countryText = $("#ListingCountry option:selected").text();
    var ac = this.lookup(countries, $countryText, "name", true)[0].cities;
    // lookup by id (alternate approach)
    // var $countryId = $("#ListingCountry option:selected").val();
    // var ac = this.lookup(countries, $countryId , "id", true)[0].cities;
    if (ac) {
      $('#ListingCity option:gt(0)').remove();
      var opt = '<option></option>';
      var newOptions = "";
      $.each(ac, function(k2, v2) {
       // var sel = currentCity == v2.name ? ' selected="selected" ' : "";
        var sel = v2.isDefault ? ' selected="selected" ' : "";
        opt = '<option data-sort="' + v2.sortOrder + '"' + sel + ' value="' + v2.id + '">' + v2.name + '</option>';
        newOptions += opt;
      });
      $cityAll.append(newOptions); //hit the DOM just once
      $cityAll.sortOptions(); // sort what we put in
      $(".city").fadeIn(300);
    } else {
      $cityAll.find('option:gt(0)').remove();
      $(".city").fadeOut(300);
    }
    $cityAll.trigger('change');// because it changed
  },
  setCountries: function(nation) {
    var $countries = $("#ListingCountry");
    $countries.find('option:gt(0)').remove();
    var opt = '';
    var newOptions = "";
    $.each(nation, function(k2, v2) {
      var sel = v2.isDefault ? ' selected="selected" ' : "";
      opt = '<option data-sort="' + v2.sortOrder + '"' + sel + ' value="' + v2.id + '">' + v2.name + '</option>';
      newOptions += opt;
    });
    $countries.append(newOptions); //hit the DOM just once
  }
};

创建密钥排序功能:

// sort the select
$.fn.sortOptions = function() {
  $(this).each(function() {
    var op = $(this).children("option");
    op.sort(function(a, b) {
      return $(a).data('sort') > $(b).data('sort') ? 1 : -1;
    })
    return $(this).empty().append(op);
  });
}

启动代码:

myApp.arrayObj.setCountries(myApp.countries);
// could be done is way  but we trigger the country change which does this
// myApp.arrayObj.updateCityOptions(myApp.countries);

处理国家/地区更改事件:

$('#ListingCountry').on('change', function() {
  myApp.arrayObj.updateCityOptions(myApp.countries);
}).trigger('change');

修改:请注意,如果您只想将"isCapital": false保留在一个上,则可以删除所有"isCapital": true,并且它的工作方式相同。

可在此处播放的示例:https://jsfiddle.net/MarkSchultheiss/okk22ovq/2/

编辑:奖金;备用排序选项

// sort the select
$.fn.sortOptionsByText = function() {
  $(this).each(function() {
    var op = $(this).children("option");
    op.sort(function(a, b) {
      return a.text > b.text ? 1 : -1;
    })
    return $(this).empty().append(op);
  });
}

// sort the select
$.fn.sortOptionsByValue = function() {
  $(this).each(function() {
    var op = $(this).children("option");
    op.sort(function(a, b) {
      return a.value > b.value ? 1 : -1;
    })
    return $(this).empty().append(op);
  });
}

// sort the select **IF** we had a "mostused" data-mostused value
// sort the select
$.fn.sortOptions = function() {
  $(this).each(function() {
    var op = $(this).children("option");
    op.sort(function(a, b) {
      return $(a).data('mostused') > $(b).data('mostused') ? 1 : -1;
    })
    return $(this).empty().append(op);
  });
}