JavaScript - 排序SELECT选项

时间:2010-06-30 20:44:57

标签: javascript html select sorting

使用PHP,我扫描目录并列出所有.xml文件。每个XML文件都包含“name”元素和“date”元素。每个XML文件的“name”元素在选择列表中列为选项。这非常合适,但是,每个XML文件中的“date”元素是不同的,并且包含这样的日期格式:mm / dd / yyyy。我想弄清楚怎么做的是根据日期对项目进行排序,最早的日期是列表中的第一个日期,最后的日期是最近的日期。

现在说每个项目的“日期”元素都有不同的值。我需要在最早的日期之前对这些项目进行排序。我不知道如何在某处存储“date”元素数据,以便可以通过JavaScript处理它。如果这是一个非常模糊的描述,我很抱歉,这让我困惑了一段时间,尝试解释是一件令人困惑的事。

已更新

所以现在这就是我的工作:

<select name="sel_id" onchange="this.form.submit()" size="20">
<option value="item1">Item 1</option>
<option value="item2">Item 2</option>
<option value="item3">Item 3</option>
<option value="item4">Item 4</option>
</select>

我想有一件事可以帮助我知道是否有一种方法可以在标签中的某个位置存储日期,除了值属性,看看它是如何被使用的。日期本身并不是一个问题,我有很多想法,它只是将它存储在某个地方,以便它可以被称为客户端。

4 个答案:

答案 0 :(得分:6)

  

更新

您需要:

  • 使用日期的自定义属性
  • 使用sort()函数的自定义比较函数参数
  • 转换为数组以进行排序
  • 转换字符串比较的日期(mm / dd / yyyy - &gt; yyyy-mm-dd)

See it in action

[测试时间:IE 5.5 +,FF 2 +,Chrome 4 +,Safari 4 +,Opera 9.6 +]

<强> HTML:

<select name="sel_id" id="sel_id" size="4">
  <option value="item2" date="02-01-2009">Item 2</option>
  <option value="item3" date="01-05-2010">Item 3</option>
  <option value="item1" date="10-06-2007">Item 1</option>
  <option value="item4" date="04-05-2011">Item 4</option>
</select>

<强>使用Javascript:

// array functions are not working
// on nodeLists on IE, we need to
// to convert them to array
function toArray( obj ) {
  var i, arr = [];
  for ( i = obj.length; i--; ){
    arr[i] = obj[i];
  }
  return arr;
}

// custom compare function for sorting
// by the hidden date element
function sortByDate( el1, el2 ) {
  var a = convertToDate( el1.getAttribute("date") ),
      b = convertToDate( el2.getAttribute("date") );
  if ( a < b ) return -1;
  else if( a > b ) return 1;
  else return 0;
}

// convert date for string comparison
function convertToDate( date ) {
  date = date.split("-");
  return date[2] + "-" + date[0] + "-" + date[1];
}

// select the elements to be ordered
var itemsId = document.getElementById("sel_id"),
    items   = itemsId.getElementsByTagName("option"),
    len     = items.length;

// convert to array, to make sorting possible
items = toArray( items );

// do the item sorting by their date
items = items.sort( sortByDate );

// append them back to the parent in order
for ( var i = 0; i < len; i++ ) {
  itemsId.appendChild( items[i] );
}

答案 1 :(得分:2)

短而甜蜜。该版本还根据OP的要求考虑了mm-dd-yyyy格式的日期。

<form>
  <select id="myList">
    <option value="07-01-2010">Item 2</option>
    <option value="09-21-2009">Item 1</option>
    <option value="08-22-2010">Item 3</option>
  </select>
</form>
<script>
  var list    = document.forms[0].myList,
      opts    = list.options,
      len     = opts.length,
      sorted  = [].slice.call(opts).sort(function(a,b){
        return fixDate(a.value) < fixDate(b.value) ? -1 : 1;
      });

  for (var i=0; i<len; i++) {
    list.appendChild(sorted[i]);
  }

  // convert m-d-y to y-m-d
  function fixDate (d) {
    var a=d.split('-');
    a.unshift(a.pop()); 
    return a.join('-');
  }

</script>

答案 2 :(得分:0)

我会从上面的galambalazs中得到答案,但是使用data属性而不是date属性。因为“data-date”被认为是符合标准的,而“date”只是一个自定义属性。

答案 3 :(得分:-1)

您可以将日期表示为选项值,或使用data attribute将日期存储为选项。

<option value="2010-07-05">..</option>

<option data-date="2010-07-05">..</option>

假设您的选择列表如下所示:

<select id="myList">
    <option value="2010-07-01">Item 1</option>
    <option value="2010-06-21">Item 1</option>
    <option value="2010-08-22">Item 1</option>
    ..
</select>

使用内置Array.sort函数和自定义比较器对节点进行排序,并在排序后将其重新插入选择列表。 See an example here

/**
 * Sorts option elements by value attribute which holds a date
 *
 * @param {HTMLOptionElement} a first option
 * @param {HTMLOptionElement} b second option
 *
 * @returns {Integer}
 */
var sortByDate = function(a, b) {
    return new Date(a.value) - new Date(b.value);
}

var list = document.getElementById("myList");
var options = list.getElementsByTagName("option");
// NodeList that we get in previous step is an array-like
// object but not actually an array. Some call it a fuck-up,
// but regardless we need to convert it to an array.
var optionsArray = Array.prototype.slice.call(options);

// Now that we have an array, we can use the sort method (in-place sorting)
optionsArray.sort(sortByDate);

// re-insert the sorted nodes
for(var i = 0; i < optionsArray.length; i++) {
    list.appendChild(optionsArray[i]);
}
​