При клике на заголовок таблицы отсортировать таблицу
Дано: 4 заказа(массив массивов), в каждом по 5 пунктов(массив объектов)(ручка, карандаш, линейка и т.д.). В каждом пункте 4 параметра: номер пункта, название(ручка, карандаш...)(поля объекта). Данные я отрисовываю в таблицу. После клика по одному из заголовков таблицы(id, название...), нужно отсортировать таблицу по данному критерию. Но вот беда: если текст в заголовках("Номер", "Название"), а название полей в объекте: name, id. Как определить по какому параметру сортировать? Вот, допустим, я кликнул по столбцу "Имя". Как дать понять программе, что нужно сортировать по полю name в объекте?
|
Neo54213,
Цитата:
Цитата:
Сортируйте таблицу https://learn.javascript.ru/task/sort-table |
Ну я написал код таким образом, что таблица отрисовывается и сортируется по имени. После по нажатию на заголовок столбца(th) нужно отсортировать таблицу по указанному критерию(т.е. нажали на th "Название" - сортируем по названию. Нажали на th с текстом "Номер" сортируем по id.
|
Neo54213,
на форуме масса примеров сортировки таблиц, и может вы покажите ваш код? |
|
var headers = ['Номер', 'Название', 'Количество', 'Цена']; var fieldsNames = ['id', 'name', 'count', 'price']; var orders = [ [ { id: 1, name: "Book", count: 3, price: 157 }, { id: 2, name: "Pen", count: 4, price: 85 }, { id: 3, name: "Phone", count: 1, price: 464 }, { id: 4, name: "Pencil", count: 65, price: 314 }, { id: 5, name: "Sharpener", count: 6, price: 96 } ], [ { id: 1, name: "Tape", count: 5, price: 543 }, { id: 2, name: "Textbook", count: 65, price: 314 }, { id: 3, name: "Pencil case", count: 35, price: 346 }, { id: 4, name: "Desk", count: 5, price: 4314 }, { id: 5, name: "Marker", count: 5, price: 145 } ], [ { id: 1, name: "Paper", count: 5, price: 87 }, { id: 2, name: "Chalk", count: 6, price: 435 }, { id: 3, name: "Clock", count: 8, price: 563 }, { id: 4, name: "Ruler", count: 22, price: 457 }, { id: 5, name: "Globe", count: 7, price: 789 } ], [ { id: 1, name: "Chair", count: 2, price: 54 }, { id: 2, name: "Eraser", count: 56, price: 2445 }, { id: 3, name: "Map", count: 11, price: 345 }, { id: 4, name: "Scissors", count: 24, price: 451 }, { id: 5, name: "Notebook", count: 32, price: 654 } ] ]; function clearSortImage(exceptionTHId) { $('th:not(th:nth-child(' + +(exceptionTHId+1) + '))') .removeClass('asc') .removeClass('desc') .find('.indicator-image').hide(); } function drawTabs() { for (var i = 0; i < orders.length; i++) { $('<div>', { text: 'Заказ ' + +(i+1), class: 'button order' + +(i+1), data: { id: i } }).appendTo($('header')); } } function drawTHs() { for (var i = 0; i < headers.length; i++) { var $thead = $('section #orderstable thead'); var $th = $('<th>', { text: headers[i], data: { id: i } }); var $indicatorImage = $('<img>', { alt: 'индикатор сортировки', class: 'indicator-image' }); $th.prepend($indicatorImage); $thead.append($th); } } function sortTable(clickedHeader) { var $th = $('section #orderstable th'); var headerIndex = $th.index($(clickedHeader)); var fieldName = fieldsNames[headerIndex]; var $divSelected = $('div.selected'); var orderIdx = $divSelected.data('id'); var order = orders[orderIdx]; if($(clickedHeader).hasClass('asc')) { if (typeof order[0][fieldName] == "number") { order.sort(function (a, b) { return b[fieldName] - a[fieldName]; }); } else { order.sort(function (a, b) { if (a[fieldName] > b[fieldName]) { return -1; } if (a[fieldName] < b[fieldName]) { return 1; } return 0; }); } $(clickedHeader).addClass('desc').removeClass('asc') .find('.indicator-image').attr('src', 'img/desc.png'); }else{ if(typeof order[0][fieldName] == "number"){ order.sort(function(a, b) { return a[fieldName]-b[fieldName]; }); }else{ order.sort(function(a, b) { if (a[fieldName] < b[fieldName]) { return -1; } if (a[fieldName] > b[fieldName]) { return 1; } return 0; }); } $(clickedHeader).addClass('asc').removeClass('desc').find('.indicator-image').attr('src', 'img/asc.png'); } $(clickedHeader).find('.indicator-image').show(); $divSelected.click(); } function drawTable(clickedButton) { var $tbody = $('#orderstable tbody') $tbody.empty(); var orderIdx = $(clickedButton).data('id'); var order = orders[orderIdx]; for (var i = 0; i < order.length; i++) { var item = order[i]; var $tr = $('<tr>'); for (var column in item){ var $td = $('<td>', { text: item[column] }); $tr.append($td); } $tbody.append($tr); } } $(document).ready(function() { drawTabs(); drawTHs(); $('.button').on('click', function() { var $tbody = $('#orderstable tbody'); if(!$(this).hasClass('selected')) { $('th').removeClass('asc') .removeClass('desc') .find('.indicator-image').hide(); } $('.button').removeClass('selected'); $(this).addClass('selected'); drawTable(this); }); $('th').on('click', function() { // var exceptionTHId = $(this).index(); clearSortImage(/*exceptionTHId*/); sortTable(this); }); $('section header .order2').click(); $('#orderstable th.name').click(); }); Да мне просто ответ на вопрос нужен: как получить доступ к полю объекта? Вот, допустим, кликнул я по "Название". Как мне понять, что сортировать нужно по полю: name в объекте? order.sort(function(a, b) { return a[fieldName]-b[fieldName]; }); Вот этот кусок я написал, но как получить этот самый fieldName? Вот во второй строке у меня то, чего быть не должно var fieldsNames = ['id', 'name', 'count', 'price']; Это костыль. |
Цитата:
function drawTHs() { var $thead = $("section #orderstable thead"); headers.forEach(function(text, i) { var fieldsName = fieldsNames[i]; var $th = $("<th>", { click: function() { superSort(fieldsName) }, text: text, data: { id: i } }); var $indicatorImage = $("<img>", { alt: "индикатор сортировки", "class": "indicator-image" }); $th.prepend($indicatorImage); $thead.append($th) }) }; |
А если без массива fieldsName? Ведь это дублирующиеся данные. Эти ключи у меня уже есть в объекте.
|
Neo54213,
:-? superSort(i) |
рони,
итак, i это индекс th(начиная с нуля, первый th - i=0). Дальше мне в функции superSort(вот она кстати ниже) нужно отсортировать массив по какому-либо столбцу. Этот столбец, допустим, третий. Как теперь по индексу получить доступ к полю? Ну т.е. что нам это дает, что мы знаем номер столбца? Как я с помощью цифры, например, 1, которую мы передали в функцию superSort() при клике на th с текстом "Название", получу доступ к полю name в объекте? var $th = $('section #orderstable th'); var fieldName = // что сюда записать? массив fieldsNames отсутствует var $divSelected = $('div.selected'); var orderIdx = $divSelected.data('id'); var order = orders[orderIdx]; if($(clickedHeader).hasClass('asc')) { if (typeof order[0][fieldName] == "number") { order.sort(function (a, b) { return b[fieldName] - a[fieldName]; }); } else { order.sort(function (a, b) { if (a[fieldName] > b[fieldName]) { return -1; } if (a[fieldName] < b[fieldName]) { return 1; } return 0; }); } $(clickedHeader).addClass('desc').removeClass('asc') .find('.indicator-image').attr('src', 'img/desc.png'); }else{ if(typeof order[0][fieldName] == "number"){ order.sort(function(a, b) { return a[fieldName]-b[fieldName]; }); }else{ order.sort(function(a, b) { if (a[fieldName] < b[fieldName]) { return -1; } if (a[fieldName] > b[fieldName]) { return 1; } return 0; }); } $(clickedHeader).addClass('asc').removeClass('desc').find('.indicator-image').attr('src', 'img/asc.png'); } |
Neo54213,
мне сложно понять ваш код, не могу ничего подсказать ... как хотя бы выглядит ваша таблица? (если несложно html таблицы напишите) |
рони,
![]() Хорошо. Вопрос проще, без кода. Как, зная индекс ключа в объекте получить данные из этого поля? Допустим, объект var obj = {firstName: "Vasya", lastName: "Pupkin", age: 33} Я хочу обратиться ко второму полю(в нашем случае lastName). Но я знаю его порядковый индекс(который равен 1), а названия(собственно, lastName) я не знаю. Могу ли я как-то по индексу 1(т.к. это второй ключ в объекте) получить данные из этого поля? obj[1] не работает. |
Neo54213,
var obj = {firstName: "Vasya", lastName: "Pupkin", age: 33} alert(Object.keys(obj)[1]) |
Manyasha,
достаточно неочевидное решение. Спасибо! |
Цитата:
можно конечно так, но это без гарантии, что key во всех тестах будет "lastName", а не что-нибудь ещё. var obj = {firstName: "Vasya", lastName: "Pupkin", age: 33}; var k = 1; var key = Object.keys(obj)[k]; alert(obj[key]); |
Neo54213,
в-каком-порядке-перебираются-свойства |
может так?
<head> <script type="text/javascript" src="https://code.jquery.com/jquery-1.9.0.min.js"></script> <script> var headers = ['Номер', 'Название', 'Количество', 'Цена']; var fieldsNames = ['id', 'name', 'count', 'price']; var orders = [ { id: 1, name: "Book", count: 3, price: 157 }, { id: 2, name: "Pen", count: 4, price: 85 }, { id: 3, name: "Phone", count: 1, price: 464 }, { id: 4, name: "Pencil", count: 65, price: 314 }, { id: 5, name: "Sharpener", count: 6, price: 96 } ]; </script> </head> <table> <tr> <th class='id'>Номер</th> <th class='name asc'>Название</th> <th class='count'>Количество</th> <th class='price'>Цена</th> </tr> </table> <script> $('th').click(function(){ var key = $(this).attr('class').replace(' asc', '').replace(' desc', ''); orders.sort(function (a, b) { return b[key] - a[key]; }); //console.log(orders) console.log(JSON.stringify(orders)) }) </script> |
создание и сортировка таблицы
Neo54213,
<!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> .up span.indicator{ display: inline-block; width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 16px solid red; } .dn span.indicator{ display: inline-block; width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-top: 16px solid red; } span.indicator{ display: inline-block; width: 16px; height: 16px; } .act{ background-color: #D3D3D3; } .button{ display: inline-block; border: 1px #191970 solid; margin: 4px 2px; cursor: pointer; } th{ cursor: pointer; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $(function() { var headers = ['Номер', 'Название', 'Количество', 'Цена']; var fieldsNames = ['id', 'name', 'count', 'price']; var orders = [ [ { id: 1, name: "Book", count: 3, price: 157 }, { id: 2, name: "Pen", count: 4, price: 85 }, { id: 3, name: "Phone", count: 1, price: 464 }, { id: 4, name: "Pencil", count: 65, price: 314 }, { id: 5, name: "Sharpener", count: 6, price: 96 } ], [ { id: 1, name: "Tape", count: 5, price: 543 }, { id: 2, name: "Textbook", count: 65, price: 314 }, { id: 3, name: "Pencil case", count: 35, price: 346 }, { id: 4, name: "Desk", count: 5, price: 4314 }, { id: 5, name: "Marker", count: 5, price: 145 } ], [ { id: 1, name: "Paper", count: 5, price: 87 }, { id: 2, name: "Chalk", count: 6, price: 435 }, { id: 3, name: "Clock", count: 8, price: 563 }, { id: 4, name: "Ruler", count: 22, price: 457 }, { id: 5, name: "Globe", count: 7, price: 789 } ], [ { id: 1, name: "Chair", count: 2, price: 54 }, { id: 2, name: "Eraser", count: 56, price: 2445 }, { id: 3, name: "Map", count: 11, price: 345 }, { id: 4, name: "Scissors", count: 24, price: 451 }, { id: 5, name: "Notebook", count: 32, price: 654 } ] ]; var section = $("section"); var header = $("<header>").appendTo(section); var table = $("<table>", {"id": "orderstable"}).appendTo(section); var thead = $("<thead>").appendTo(table); var tbody = $("<tbody>").appendTo(table); var tbodyContent = orders.map(function(trs, i) { $("<div>", { text: "Заказ " + +(i + 1), "class": "button order" + +(i + 1), click: function() { tbody.html(tbodyContent[i]); $("th", thead).removeClass("up dn"); $(".button", header).removeClass("act"); $(this).addClass("act") } }).appendTo(header); return trs.map(function(tds) { var tr = $("<tr>"); fieldsNames.forEach(function(key, i) { $("<td>", { text: tds[key] }).appendTo(tr) }); return tr }) }); function fnSort(i) { return function(b, a) { a = $("td", a).eq(i).text(); b = $("td", b).eq(i).text(); b = +b || b; a = +a || a; return b > a ? 1 : b < a ? -1 : 0 } } headers.forEach(function(text, i) { var fn = fnSort(i), k = 0; var th = $("<th>", { click: function() { k ^= 1; var tr = $("tr", tbody).get().sort(fn); k && (tr = tr.reverse()); tbody.append(tr); $("th", thead).removeClass("up dn"); th.addClass(k ? "up" : "dn") }, text: text }); var indicator = $("<span>", { "class": "indicator" }); th.prepend(indicator); thead.append(th); }); $(".button:first").click(); }); </script> </head> <body> <section></section> </body> </html> |
моя реализация сортировки :haha:
<div id="search-menu"> <p>Сортировать по :</p> <a class="btn" data-sort="user_name" href="#">Имя<span></span></a> <a class="btn" data-sort="user_age" href="#">Возраст</a> </div> <!-- result --> <div id="search-results"> <!-- user #1 --> <div class="user"> <img src="photo_0.jpg" alt="#" class="user_photo"> <div class="user_name">Peter</div> <div class="user_age">20 Age</div> <div class="user_about">Bla_bla_bla...description...</div> </div> <!-- user #2 --> <div class="user"> <img src="photo_1.jpg" alt="#" class="user_photo"> <div class="user_name">Alex</div> <div class="user_age">30 Age</div> <div class="user_about">Bla_bla_bla...description...</div> </div> <!-- user #3 --> <div class="user"> <img src="photo_2.jpg" alt="#" class="user_photo"> <div class="user_name">Max</div> <div class="user_age">27 Age</div> <div class="user_about">Bla_bla_bla...description...</div> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> (function($) { var $content = $("#search-results"); var $users = $('.user', $content); $('#search-menu').on('click', 'a', function(e) { e.preventDefault(); sortContent($(this)); }); function sortContent($el) { var type = '.' + $el.data('sort'); var sort = $el.hasClass('sort-up') ? 1 : -1; $users.sort(function(a, b) { return sort * $(type, b).text().toLowerCase().localeCompare($(type, a).text().toLowerCase()); }).appendTo($content); sort > 0 ? $el.removeClass('sort-up').addClass('sort-down') : $el.removeClass('sort-down').addClass('sort-up'); } }(jQuery)); </script> |
Часовой пояс GMT +3, время: 15:05. |