Сортировка таблицы HTML

Поэтому я в основном выполняю запрос mysql, который извлекает данные из моей базы данных и отображает их в удобной для чтения форме для моих пользователей.

Name-----Address----Sales Person

Вы понимаете суть. А теперь я хочу позволить пользователю сортировать HTML-таблицу, скажем, по продажам. Как я могу легко сделать это, используя выпадающее меню?

<div class='menu'>
  <ul>
    <li><a href='#'><span>Sales Person</span></a>
      <ul>
        <li><a href='#'><span>Melissa</span></a></li>
        <li><a href='#'><span>Justin</span></a></li>
        <li><a href='#'><span>Judy</span></a></li>
        <li><a href='#'><span>Skipper</span></a></li>
        <li><a href='#'><span>Alex</span></a></li>
      </ul>
    </li>
  </ul>
</div>

Ответ 1

Проверьте, можете ли вы использовать любой из перечисленных ниже плагинов JQuery. Просто потрясающе и предоставляет широкий спектр вариантов для работы, и меньше проблем для интеграции. :)

https://github.com/paulopmx/Flexigrid - Flexgrid
http://datatables.net/index - таблицы данных.
https://github.com/tonytomov/jqGrid

Если нет, вам нужно иметь ссылку на те заголовки таблиц, которые вызывают сценарий на стороне сервера, чтобы вызвать сортировку.

Ответ 2

Другой подход к сортировке таблицы HTML. (на основе W3.JS HTML Sort)

let tid = "#usersTable";
let headers = document.querySelectorAll(tid + " th");

// Sort the table element when clicking on the table headers
headers.forEach(function(element, i) {
  element.addEventListener("click", function() {
    w3.sortHTML(tid, ".item", "td:nth-child(" + (i + 1) + ")");
  });
});
th {
  cursor: pointer;
  background-color: coral;
}
<script src="https://www.w3schools.com/lib/w3.js"></script>
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet" />
<p>Click the <strong>table headers</strong> to sort the table accordingly:</p>

<table id="usersTable" class="w3-table-all">
  <!--     
  <tr>
    <th onclick="w3.sortHTML('#usersTable', '.item', 'td:nth-child(1)')">Name</th>
    <th onclick="w3.sortHTML('#usersTable', '.item', 'td:nth-child(2)')">Address</th>
    <th onclick="w3.sortHTML('#usersTable', '.item', 'td:nth-child(3)')">Sales Person</th>
  </tr> 
  -->
  <tr>
    <th>Name</th>
    <th>Address</th>
    <th>Sales Person</th>
  </tr>

  <tr class="item">
    <td>user:2911002</td>
    <td>UK</td>
    <td>Melissa</td>
  </tr>
  <tr class="item">
    <td>user:2201002</td>
    <td>France</td>
    <td>Justin</td>
  </tr>
  <tr class="item">
    <td>user:2901092</td>
    <td>San Francisco</td>
    <td>Judy</td>
  </tr>
  <tr class="item">
    <td>user:2801002</td>
    <td>Canada</td>
    <td>Skipper</td>
  </tr>
  <tr class="item">
    <td>user:2901009</td>
    <td>Christchurch</td>
    <td>Alex</td>
  </tr>

</table>

Ответ 3

При сортировке таблиц HTML в браузере используется простой, неукрашенный Javascript.

Основной процесс:

  1. добавить обработчик кликов к каждому заголовку таблицы
  2. обработчик кликов отмечает индекс столбца для сортировки
  3. таблица преобразуется в массив массивов (строк и ячеек)
  4. этот массив отсортирован с помощью функции сортировки javascript
  5. данные из отсортированного массива вставляются обратно в HTML таблица

Таблица должна, конечно, быть хорошим HTML. Примерно так...

<table>
 <thead>
  <tr><th>Name</th><th>Age</th></tr>
 </thead>
 <tbody>
  <tr><td>Sioned</td><td>62</td></tr>
  <tr><td>Dylan</td><td>37</td></tr>
  ...etc...
 </tbody>
</table>

Итак, сначала добавим обработчики кликов...

const table = document.querySelector('table'); //get the table to be sorted

table.querySelectorAll('th') // get all the table header elements
  .forEach((element, columnNo)=>{ // add a click handler for each 
    element.addEventListener('click', event => {
        sortTable(table, columnNo); //call a function which sorts the table by a given column number
    })
  })

Сейчас это не сработает, потому что функция sortTable, вызываемая в обработчике событий, не существует.

Давайте напишем это...

function sortTable(table, sortColumn){
  // get the data from the table cells
  const tableBody = table.querySelector('tbody')
  const tableData = table2data(tableBody);
  // sort the extracted data
  tableData.sort((a, b)=>{
    if(a[sortColumn] > b[sortColumn]){
      return 1;
    }
    return -1;
  })
  // put the sorted data back into the table
  data2table(tableBody, tableData);
}

Итак, теперь мы добрались до сути проблемы, нам нужно сделать функции table2data, чтобы получить данные из таблицы, и data2table, чтобы вернуть их после сортировки.

Вот они...

// this function gets data from the rows and cells 
// within an html tbody element
function table2data(tableBody){
  const tableData = []; // create the array that'll hold the data rows
  tableBody.querySelectorAll('tr')
    .forEach(row=>{  // for each table row...
      const rowData = [];  // make an array for that row
      row.querySelectorAll('td')  // for each cell in that row
        .forEach(cell=>{
          rowData.push(cell.innerText);  // add it to the row data
        })
      tableData.push(rowData);  // add the full row to the table data 
    });
  return tableData;
}

// this function puts data into an html tbody element
function data2table(tableBody, tableData){
  tableBody.querySelectorAll('tr') // for each table row...
    .forEach((row, i)=>{  
      const rowData = tableData[i]; // get the array for the row data
      row.querySelectorAll('td')  // for each table cell ...
        .forEach((cell, j)=>{
          cell.innerText = rowData[j]; // put the appropriate array element into the cell
        })
      tableData.push(rowData);
    });
}

И это должно сделать.

Несколько вещей, которые вы, возможно, захотите добавить (или причины, по которым вы можете использовать готовое решение): возможность изменить направление и тип сортировки, т.е. вы можете отсортировать некоторые столбцы численно ("10" > "2" - это ложь, потому что это строки, вероятно, не то, что вы хотите). Возможность пометить столбец как отсортированный. Какая-то проверка данных.

Ответ 4

Еще один параметр, использующий плагин jquery, breedjs: Если вы поместите данные в объект js, вы можете сделать так:

var data = {
    people: [
        {name: 'a', address: 'c', salesperson: 'b'},
        {name: 'b', address: 'b', salesperson: 'a'},
        {name: 'c', address: 'a', salesperson: 'c'},
    ]
};

breed.run({
    scope: 'people',
    input: data
});

HTML:

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Address</th>
            <th>Sales Person</th>
        </tr>
    </thead>
    <tbody>
        <tr b-scope="people" b-loop="person in people">
            <td b-sort="name">{{person.name}}</td>
            <td b-sort="address">{{person.address}}</td>
            <td b-sort="salesperson">{{person.salesperson}}</td>
        </tr>
    </tbody>
</table>

Теперь, каждый раз, когда вы хотите сортировать продавцом, просто назовите его:

breed.sort({
    scope: 'people',
    selector: 'salesperson'
});

Если вы хотите сортировать, нажав <th>, сделайте следующее:

$("th").click(function(){
    breed.sort({
        scope: 'people',
        selector: $(this).attr('sort')
    });
});

И измените это на HTML:

<th sort='name'>Name</th>
<th sort='address'>Address</th>
<th sort='salesperson'>Sales Person</th>

Рабочий пример на скрипке

Ответ 5

Вот еще одна библиотека.

Требуются изменения:
1. Добавить сортируемую JS
2. Добавьте имя класса sortable в таблицу.

<script src="https://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
<table class="sortable">

Щелкните заголовки таблицы, чтобы отсортировать таблицу соответствующим образом:

<script src="https://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>

<table class="sortable">
  <tr>
    <th>Name</th>
    <th>Address</th>
    <th>Sales Person</th>
  </tr>

  <tr class="item">
    <td>user:2911002</td>
    <td>UK</td>
    <td>Melissa</td>
  </tr>
  <tr class="item">
    <td>user:2201002</td>
    <td>France</td>
    <td>Justin</td>
  </tr>
  <tr class="item">
    <td>user:2901092</td>
    <td>San Francisco</td>
    <td>Judy</td>
  </tr>
  <tr class="item">
    <td>user:2801002</td>
    <td>Canada</td>
    <td>Skipper</td>
  </tr>
  <tr class="item">
    <td>user:2901009</td>
    <td>Christchurch</td>
    <td>Alex</td>
  </tr>

</table>

Ответ 6

Таблицы на основе Flexbox можно легко отсортировать с помощью свойства flexbox "order".

Вот пример:

HTML

<div id="table">
 <div>Melissa</div>
        <div>Justin</div>
        <div>Judy</div>
        <div>Skipper</div>
       <div>Alex</div>
</div>
<button id="sort"> sort </button>

CSS

#table{
  display:flex;
  flex-direction:column
}

JS

function sortTable(){
  let table = document.querySelector("#table")
  let children = [...table.children]
  let sortedArr = children.map(e=>e.innerText).sort((a,b)=>a.localeCompare(b));

 children.forEach(child=>{
    child.style.order = sortedArr.indexOf(child.innerText)
  })
}

document.querySelector("#sort").addEventListener("click",sortTable)

Объяснение

Функция sortTable извлекает данные таблицы в массив, который затем сортируется в алфавитном порядке. После этого мы перебираем элементы таблицы и назначаем свойство CSS order, равное индексу данных элемента в нашем отсортированном массиве.