无论是数字,字母还是日期,都可以通过单击标题标记对表进行排序

时间:2017-10-25 03:33:45

标签: javascript sorting

我试图按排序我的桌子(只有纯,不是库而不是框架,只有纯。)

每个列通过单击每个标题标记排序,当前排序是按字母顺序排列的,但我需要排序将是数字或字母或日期,无论它如何。数据是来自另一方的Json,可以包含数字或字母或日期列。

这是我的排序代码:

function sortMainTable(_num) {
  var table, rows, sw, i, x, y;
  table = document.getElementById("mainTable");
  sw = true;
  while (sw) {
    sw = false;
    rows = table.getElementsByTagName("tr");
    for (i = 1; i < (rows.length - 1); i++) {
      x = rows[i].getElementsByTagName("td")[_num];
      y = rows[i + 1].getElementsByTagName("td")[_num];
      if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        sw = true;
        break;
      }
    }
  }
}

示例

places = [{
    "city": "Los Angeles",
    "country": "USA",
    "price:": "130.90",
    "date": "02/12/2015"
  },
  {
    "city": "Boston",
    "country": "USA",
    "price:": "11.40",
    "date": "10/04/2014",
  },
  {
    "city": "Chicago",
    "country": "USA",
    "price:": "320.40"
    "date": "06/05/2017",
  },
]

正如我上面所说,我需要排序将是数字或字母或日期,无论它如何。 (如果列是数字,表格排序按数字列排序,如果列是按字母顺序排列的,则表格排序按字母顺序排序,如果列是日期,则表格排序按日期排序列)

有什么想法吗?

感谢。

2 个答案:

答案 0 :(得分:0)

你想要的最有可能是natural sort。在哪里可以对字母数字进行排序,然后#34;自然而然地#34;。 npm上有无数的选项供您参考。谷歌的第一个热门是javascript-natural-sort。这应该指向正确的方向。

一旦你有了这个,我会将一个事件处理程序绑定到你的表头,它会传递你想要.sort()的列名,然后根据该键对你的places数组进行自然排序,然后重新放回桌子。

答案 1 :(得分:0)

JavaScript 中,您可以使用原生Array.sort()对对象数组进行排序。

  

sort()方法对数组中的元素进行排序并返回   数组。排序不一定稳定。默认排序顺序   是根据字符串Unicode代码点。

     

<强>参数

     

compareFunction 可选 指定定义的函数   排序顺序。如果省略,则根据每个数组对数组进行排序   根据字符串,字符的Unicode代码点值   转换每个元素。

     

返回值

     

排序后的数组。请注意,数组已就地排序,   并且没有复制。

places 变量中,您必须比较:

  • 字符串:在比较功能中使用 > < 符号。
  • 数字:在比较功能中使用 - 符号。
  • 日期:您可以使用:02/12/2015将字符串日期(1423717200000)转换为等效的时间戳(new Date("02/12/2015").getTime())。因此,您可以在比较功能中使用 - 符号。

我已将您的代码重写为:

  1. 使用 places 变量数据呈现表格,动态无需订购。
  2. 在数据分类时是否呈现数据。
  3. 在标题中设置排序控件。
  4. 编写辅助函数,根据keydatatype参数对数组进行排序。返回已排序的数据。
  5. (function() {
      var places = [{
        "city": "Los Angeles",
        "country": "USA",
        "price": "130.90",
        "date": "02/12/2015"
      }, {
        "city": "Boston",
        "country": "USA",
        "price": "11.40",
        "date": "10/04/2014",
      }, {
        "city": "Chicago",
        "country": "USA",
        "price": "320.40",
        "date": "06/05/2017",
      }];
    
      // 4.
      function sortByKey(key, data, type) {
        if (key === "price") {
          if (type === "asc") { // ↑
            data.sort(function(a, b) {
              return (a[key] * 1) > (b[key]);
            });
          } else { // ↓
            data.sort(function(a, b) {
              return (a[key] * 1) < (b[key]);
            });
          }
        } else if (key === "date") {
          if (type === "asc") {
            data.sort(function(a, b) {
              return new Date(a[key]).getTime() - new Date(b[key]).getTime();
            });
          } else {
            data.sort(function(a, b) {
              return new Date(b[key]).getTime() - new Date(a[key]).getTime();
            });
          }
        } else {
          if (type === "asc") {
            data.sort(function(a, b) {
              return a[key] > b[key];
            });
          } else {
            data.sort(function(a, b) {
              return a[key] < b[key];
            });
          }
        }
        return data;
      }
    
      // 3.
      function setSorterControl(data) {
        // Remove the span class after sorting.
        function reset() {
          var elems = document.querySelectorAll("#mainTable th span"), i, len = elems.length, obj;
          for (i = 0; i < len; i++) {
            obj = elems[i];
            obj.removeAttribute("class");
          }
        }
        
        /*
          Render the sorted data in the tbData element.
          Set the data-type attribute with the proper value after click in the header control.
          Set the proper span class when its clicked to sort the data.
         */
        function sorter(e) {
          var tbData = document.getElementById("tbData"), elem = e.target;
          tbData.innerHTML = sortTable(sortByKey(elem.getAttribute("data-key"), data, elem.getAttribute("data-type")));
          elem.setAttribute("data-type", elem.getAttribute("data-type") === "asc" ? "desc" : "asc");
          reset();
          elem.children[0].className = elem.getAttribute("data-type") === "asc" ? "desc" : "asc";
    
        }
        var elems = document.querySelectorAll("#mainTable th"), i, len = elems.length, obj;
        for (i = 0; i < len; i++) {
          obj = elems[i];
          obj.onclick = sorter;
        }
      }
      
      // 1.
      function renderTable(data, type) {
        var html = "", i, header = Object.keys(data[0]), lenHeader = header.length;
        html += "<thead><tr>";
        for (i = 0; i < lenHeader; i++) {
          html += "<th data-key=\"";
          html += header[i];
          html += "\" data-type=\"asc\">";
          html += header[i];
          html += "<span></span></th>";
        }
        html += "</tr></thead><tbody id=\"tbData\">";
        html += sortTable(data);
        html += "</tbody>";
        return html;
      }
    
      // 2.
      function sortTable(data) {
        var html = "",
          i, j, len = data.length,
          header = Object.keys(data[0]),
          lenHeader = header.length;
        for (i = 0; i < len; i++) {
          html += "<tr>";
          for (j = 0; j < lenHeader; j++) {
            html += "<td>";
            html += data[i][header[j]];
            html += "</td>";
          }
          html += "</tr>";
        }
        return html;
      }
      document.getElementById("mainTable").innerHTML = renderTable(places);
      setSorterControl(places);
    })();
    #mainTable {
      border: solid 1px #ccc;
      border-collapse: collapse;
    }
    
    #mainTable th,
    #mainTable td {
      padding: 5px;
    }
    
    #mainTable th {
      background-image: linear-gradient(#bcbebf, #eff3f7);
      cursor: pointer;
    }
    
    #mainTable th span {
      pointer-events: none;
    }
    
    #mainTable th span:before {
      content: "↕";
    }
    
    #mainTable th span.asc:before {
      content: "↑";
    }
    
    #mainTable th span.desc:before {
      content: "↓";
    }
    <table id="mainTable" border="1"></table>

    enter image description here