如何对表格进行水平排序

时间:2019-04-09 21:45:24

标签: jquery

我正在尝试对表格进行水平排序。

排序包括单击标题,因此应该对元素进行排序。

我尝试了下面的代码

但是排序不正确。 没有任何插件,对此有什么合适的解决方案?

@objc func answerTheQuestion(_sender:UIButton) {

   print("aa")

   if let questionsAnswers = self.quizzes?.quizzes[self.randomNumber!]["questions"] as?  [[String:Any]] {

    if (questionsAnswers[self.randomQuestion!]["question"] as? String) != nil { 

       if let correctAnswer = questionsAnswers[self.randomQuestion!]["correct_answer"] as? String {
           if _sender.titleLabel?.text == correctAnswer {
              _sender.backgroundColor = UIColor.green
           } else {
            _sender.backgroundColor = UIColor.red
           }
       }
    }
  } 
}
$('th').click(function() {
  var rows = $('tr');

  rows.eq(0).find('td').sort(function(a, b) {
    return $.text([a]) > $.text([b]) ? 1 : -1;
  }).each(function(newIndex) {
    var originalIndex = $(this).index();
    rows.each(function() {
      var td = $(this).find('td');
      if (originalIndex !== newIndex)
        td.eq(originalIndex).insertAfter(td.eq(newIndex));
    });
  });
})

2 个答案:

答案 0 :(得分:1)

这是我想出的解决方案的版本。

  1. 它要做的第一件事是从表中获取所有数据并将其加载到变量中,因此我们只需要一次从页面中获取所有数据。
  2. 接下来要做的是创建click事件侦听器。由于将所有tr元素一起替换,因此我将其作为委托。
    1. 事件监听器要做的第一件事是检查哪个th的innerHTML是被单击的。如果它是字符串字段之一,则对字符串进行localeCompare。否则,如果它是数字价格,我会简单地减去它们进行排序。
    2. 我要做的最后一件事是用新行替换表的全部内容。新行是从排序的数据生成的。我选择将表的全部内容替换为生成的新行,因为新行是在DOM片段中构造的,并且此时DOM的唯一接触点是表的所有子项的唯一替换。因此,与一次替换一行或一次更新每一行的一列相比,它的性能更高。

var $tableRows = $('#myTable tr');
var preloadData = $tableRows.first().find('td').map(function(index){
  return {
    product: $tableRows.eq(0).find('td').eq(index).html().trim()
    , price: parseInt($tableRows.eq(1).find('td').eq(index).html().trim(), 10)
    , originCountry: $tableRows.eq(2).find('td').eq(index).html().trim()
  }
}).get();

$(document).on('click', '#myTable tr', function(e){
  var sortDesc = e.target.classList.contains('asc');
  var sortingRow
  
  if (e.target.innerHTML === 'Product') {
    sortingRow = 0;
    
    preloadData.sort(function(a, b){
      if (sortDesc) return b.product.localeCompare(a.product);
      
      return a.product.localeCompare(b.product);
    });
  } else if (e.target.innerHTML === 'Price($)') {
    sortingRow = 1;
    
    preloadData.sort(function(a, b){
      if (sortDesc) return b.price - a.price;
      
      return a.price - b.price;
    });
  } else {
    sortingRow = 2;
    
    preloadData.sort(function(a, b){
      if (sortDesc) return b.originCountry.localeCompare(a.originCountry);
      
      return a.originCountry.localeCompare(b.originCountry);
    });
  }
  
  $('#myTable').html(
    preloadData.reduce(function($rows, columnData, index){
      if (index < 1) {
        $rows.eq(0).append('<th>Product</th>');
        $rows.eq(1).append('<th>Price($)</th>');
        $rows.eq(2).append('<th>Origin Country</th>');
        
        if (!sortDesc) $rows.eq(sortingRow).find('th').addClass('asc');
      }
      
      $rows.eq(0).append('<td>'+ columnData.product +'</td>');
      $rows.eq(1).append('<td>'+ columnData.price +'</td>');
      $rows.eq(2).append('<td>'+ columnData.originCountry +'</td>');
      
      return $rows;
    }, $('<tr><tr><tr>'))
  );
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable">
  <tr>
    <th>Product</th>
    <td>Golden Watch</td>
    <td>Silver Watch</td>
    <td>Car 2018</td>
    <td>Wooden Table</td>
    <td>Sport Car 2019</td>
    <td>Perfume</td>
    <td>Car 2010</td>
    <td>Piano</td>


  </tr>
  <tr>
    <th>Price($)</th>
    <td>1000</td>
    <td>600</td>
    <td>60000</td>
    <td>50</td>
    <td>100000</td>
    <td>100</td>
    <td>10000</td>
    <td>250000</td>

  </tr>
  <tr>
    <th>Origin Country</th>
    <td>Switzerland</td>
    <td>USA</td>
    <td>Germany</td>
    <td>Sweden</td>
    <td>Italy</td>
    <td>France</td>
    <td>England</td>
    <td>Austria</td>

</table>

编辑:将asc类的设置添加到升序排序的行上。如果再次单击它,它将翻转以降序排列。

答案 1 :(得分:0)

这是一种通用方法,不需要关心多少行或标签是什么。

它首先创建rowData数组,其中每个子数组都是具有原始列号和每个单元格中的文本的对象的数组。在创建时;数据属性已添加到每个单元格,因此它知道它是用于保持列关系的永久列号

这些是首先进行排序的,因此可以创建一个对象来存储具有新排序索引的原始列号。然后,随着每行单元格的排序

// store row data arrays for easy sorting
var rowData = $('tr').map(function(rIdx, row) {
  return [$(row).children('td').map(function(cIdx, cell) {
    // store col # on each cell to use later for matching column sort order
    $(cell).data('col', cIdx + 1);
    // these objects used to keep original column numbers with sorted text
    return {
      col: cIdx + 1,
      text: cell.textContent
    }
  }).get()];
}).get();

var $th=$('#myTable th'),
  $rows = $('#myTable tr');


$th.click(function() {
   var $cell = $(this),
   rIdx = $cell.parent().index(),
   isSorted = $cell.hasClass('sorted'),
   dir = isSorted ? $cell.hasClass('asc') ? 'dsc':'asc' :'asc';
   
   $cell.removeClass('asc dsc').addClass('sorted '+ dir);  
  
   $th.not(this).removeClass('sorted asc dsc');  
 
  $rows.each(function() {
    var sortedCells = $(this).children('td').sort(rowCellSorter(rIdx, dir));
    $(this).append(sortedCells)
  });
});

function rowCellSorter(rIdx, dir) {
  var sortOrder = getSorterOrder(rIdx, dir);
  return function(a, b) {
    var aCol = $(a).data('col'),
      bCol = $(b).data('col')
    return sortOrder[aCol] - sortOrder[bCol]
  }
}

function getSorterOrder(rIdx, dir) {
  var dataRow = rowData[rIdx].slice().sort(dataRowSorter);
  
  if(dir === 'dsc'){
      dataRow.reverse()
  }
  // object with column num as keys, sort index as values
  return dataRow.reduce(function(a, c, i) {
    a[c.col] = i;
    return a;
  }, {});

}

function dataRowSorter(a, b) {
  if (isNaN(a.text)) { // text sort
    return a.text.localeCompare(b.text)
  } else { // num sort
    return a.text - b.text
  }
}
.asc:after{
  content:' > '
}

.dsc:after{
  content:' < '
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable">
  <tr>
    <th>Product</th>
    <td>Golden Watch</td>
    <td>Silver Watch</td>
    <td>Car 2018</td>
    <td>Wooden Table</td>
    <td>Sport Car 2019</td>
    <td>Perfume</td>
    <td>Car 2010</td>
    <td>Piano</td>


  </tr>
  <tr>
    <th>Price($)</th>
    <td>1000</td>
    <td>600</td>
    <td>60000</td>
    <td>50</td>
    <td>100000</td>
    <td>100</td>
    <td>10000</td>
    <td>250000</td>

  </tr>
  <tr>
    <th>Origin Country</th>
    <td>Switzerland</td>
    <td>USA</td>
    <td>Germany</td>
    <td>Sweden</td>
    <td>Italy</td>
    <td>France</td>
    <td>England</td>
    <td>Austria</td>

</table>