Код сортировки таблиц JQuery не работает (нет плагина)

Я показываю на своем веб-сайте таблицу с AJAX. Я написал код JQuery для сортировки моей таблицы, когда она отправляется через AJAX и нажимается тег <th>. (Я не хочу использовать плагин. Нет, правда, я не хочу использовать плагин!)

Это мой код:

PHP (index.php):

<form action = "query.php" method = "get">
    <input type = "search" name = "query" autofocus = "true" autocomplete = "off" list = "products">
    <datalist id = "products">
        <?php
            $sql = "SELECT * FROM products;";

            $result = mysqli_query($con, $sql);

            while ($product = mysqli_fetch_array($result)) {
                echo "<option value=\"" . $product["productname"] . "\">" . $product["price"] . " $</option>";
            }
        ?>
    </datalist>
    <button type = "submit">Search</button>
</form>
<div class = "result" align = "center"></div>

PHP (query.php):

<?php
    include_once "connection.php";

    $query = trim($_GET["query"]);
    $query = mysqli_real_escape_string($con, $query);
    $sql = "SELECT * FROM products WHERE productname LIKE '%$query%' ORDER BY productname;";

    $result = mysqli_query($con, $sql);
    $result_no = mysqli_num_rows($result);

    if ($result_no > 0) {
        echo "<table>";
        echo "<thead>";
        echo "<tr>";
        echo "<th>Product</th>";
        echo "<th>Price</th>";
        echo "<th>Quantity</th>";
        echo "</tr>";
        echo "</thead>";
        echo "<tbody>";

        while ($product = mysqli_fetch_array($result)) {
            echo "<tr class=\"table\"><td align=\"left\">" . $product["productname"] . "</td><td align=\"right\">" . $product["price"] . " $</td><td align=\"right\">" . $product["quantity"] . "</td></tr>";
        }

        echo "</tbody>";
        echo "<tfoot>";

        if ($result_no == 1) {
            echo "<tr><td colspan=\"3\" align=\"center\">" . $result_no . " product found." . "</td></tr>";
        } else {
            echo "<tr><td colspan=\"3\" align=\"center\">" . $result_no . " product found." . "</td></tr>";
        }

        echo "</tfoot>";
        echo "</table>";

    } elseif ($result_no <= 0) {
        echo "<p>No products found.</p>";
    }

    mysqli_close($con);
?>

JQuery:

$(document).ready(function() {  
    $("form").on("submit", function(event) {
        event.preventDefault();

        var form = $(this);

        $.ajax({
            type: this.method,
            url: this.action,
            data: form.serialize(),
            cache: false,
            success: function(data) {
                $("div.result").html(data);

                $("th").on("click", function() {
                    var column = $(this).index();
                    var tbody = $("tbody");
                    var rows = tbody.find("tr");
                    var dir = $(this).data("dir") || -1;
                    dir *= -1;

                    rows.sort(function(a, b) {
                        var aVal = $($(a).find("td")[column]).text().toLowerCase();
                        var bVal = $($(b).find("td")[column]).text().toLowerCase();
                        return aVal > bVal ? 1 * dir : aVal < bVal ? -1 * dir : 0;
                    });

                    $(this).data("dir", dir);

                    tbody.empty();
                    $(rows).appendTo(tbody);
                });
            }
        });
    });
});

Connection.php предназначен для подключения к моей базе данных. Я использую MySQL и PHPMyAdmin. Мои таблицы - это «пользователи» для данных входа и «продукты» для продуктов в магазине.

Моя проблема: первая строка таблицы всегда отсортирована не в том месте.

Что такое данные? Если вы не используете плагин tableorter, удалите этот тег.

Daniel Manta 17.04.2018 20:04

Что не работает? Каков ваш ожидаемый результат? У нас нет простого способа сравнить это с фактическими данными, поэтому невозможно сказать, что в нем не работает.

Kal_Torak 17.04.2018 20:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
86
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Используйте встроенную функцию Javascript Сортировать.

  1. Я извлек соответствующий код сортировки из вашего примера
  2. Я взял образец таблицы из w3cschools
  3. Я модифицировал js, чтобы сохранить отсортированное направление в ячейке заголовка.
  4. Я реализовал функцию compare (см. Связанную документацию по сортировке).
  5. Я заменил tbody, когда сортировка была завершена.

Обновлено: изменен HTML, добавлены функции для включения числовой сортировки, а не только по алфавиту. Обратите внимание на класс number и новый if в функции сортировки.

$("th").on("click", function() {
  var column = $(this).index();
  var numeric = $(this).hasClass("number"); //this class has been sprinkled to identify numeric sort.
  var bdy = $(this).closest("table").find("tbody");
  var rows = bdy.find("tr");
  var dir = $(this).data("dir") || -1; //default direction is desc
  dir *= -1; //reverse the stored direction
  rows.sort(function(a, b) {
    var aVal = $($(a).find("td")[column]).text().toLowerCase(); //get the text from one row
    var bVal = $($(b).find("td")[column]).text().toLowerCase(); //get the text from row 2
    if (numeric) {  //added to handle numeric columns
      aVal = parseFloat(aVal);
      bVal = parseFloat(bVal);
    }
    return aVal > bVal ? 1 * dir : aVal < bVal ? -1 * dir : 0; // note the dir value to change direction
  }); //sort the rows by the column content
  bdy.empty(); //empty the body
  $(rows).appendTo(bdy); //put the rows back
  $(this).data("dir", dir); //log the direction
});
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class = "table">
  <thead>
    <tr class = "table">
      <th class = "table">Product</th>
      <th class = "table number">Price</th>
      <th class = "table number">Quantity</th>
    </tr>
  </thead>
  <tbody>
    <tr class = "table">
      <td align = "left" class = "table">Chainsaw</td>
      <td align = "right" class = "table">60.00 $</td>
      <td align = "right" class = "table">1</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Hammer</td>
      <td align = "right" class = "table">24.99 $</td>
      <td align = "right" class = "table">2</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Nails (25 per Box)</td>
      <td align = "right" class = "table">9.99 $</td>
      <td align = "right" class = "table">21</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Screwdriver</td>
      <td align = "right" class = "table">29.99 $</td>
      <td align = "right" class = "table">2</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Screws (25 per Box)</td>
      <td align = "right" class = "table">15.00 $</td>
      <td align = "right" class = "table">26</td>
    </tr>
  </tbody>
  <tfoot>
    <tr class = "table">
      <td colspan = "3" align = "center" class = "table">5 products found.</td>
    </tr>
  </tfoot>
</table>

Спасибо, но похоже, что это не работает. Если я запустил этот код, первая строка будет неправильной. Может это из-за знаков доллара в моей таблице?

Felix Rewer 18.04.2018 21:25

Феликс, если вы предоставили какой-либо HTML-код, мы могли бы помочь вам с этой проблемой. Это просто сравнивает ячейки по алфавиту.

Steve0 19.04.2018 18:14

Я добавил свой код. PS: Я изменил ваш код не для того, чтобы сделать его более полезным, а просто для того, чтобы он мне нравился.

Felix Rewer 19.04.2018 20:49

@FelixRewer, пожалуйста, включите образец отрисованной таблицы, ваш вопрос был обновлен с учетом вашего PHP. Я считаю, что ваша проблема заключается не в PHP, а в HTML, который выходит с другой стороны.

Steve0 20.04.2018 23:11

@FelixRewer, please include a sample rendered table, your question was updated with your PHP. I believe that the PHP is not your problem but the HTML that comes out the other end.

Да, может ты и прав. Итак, вот фрагмент кода с выводом query.php и JQuery tablesorter (я также добавил свои стили, не думаю, что это актуально, но если да, то вот оно.):

$("th").on("click", function() {
  var column = $(this).index();
  var table = $("table");
  var tbody = table.find("tbody");
  var rows = tbody.find("tr");
  var dir = $(this).data("dir") || -1;
  dir *= -1;

  rows.sort(function(a, b) {
    var aVal = $($(a).find("td")[column]).text().toLowerCase().trim();
    var bVal = $($(b).find("td")[column]).text().toLowerCase().trim();
    return aVal > bVal ? 1 * dir : aVal < bVal ? -1 * dir : 0;
  });

  $(this).data("dir", dir);

  tbody.empty();
  $(rows).appendTo(table);
});
.table {
  margin: 3vmax;
  border: 1px solid #000000;
  border-collapse: collapse;
  color: #000000;
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class = "table">
  <thead>
    <tr class = "table">
      <th class = "table">Product</th>
      <th class = "table">Price</th>
      <th class = "table">Quantity</th>
    </tr>
  </thead>
  <tbody>
    <tr class = "table">
      <td align = "left" class = "table">Chainsaw</td>
      <td align = "right" class = "table">60.00 $</td>
      <td align = "right" class = "table">1</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Hammer</td>
      <td align = "right" class = "table">24.99 $</td>
      <td align = "right" class = "table">2</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Nails (25 per Box)</td>
      <td align = "right" class = "table">9.99 $</td>
      <td align = "right" class = "table">21</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Screwdriver</td>
      <td align = "right" class = "table">29.99 $</td>
      <td align = "right" class = "table">2</td>
    </tr>
    <tr class = "table">
      <td align = "left" class = "table">Screws (25 per Box)</td>
      <td align = "right" class = "table">15.00 $</td>
      <td align = "right" class = "table">26</td>
    </tr>
  </tbody>
  <tfoot>
    <tr class = "table">
      <td colspan = "3" align = "center" class = "table">5 products found.</td>
    </tr>
  </tfoot>
</table>

И да, у меня здесь та же проблема. Я много тестировал свой код и думаю, что, возможно, первая строка отсортирована не в том месте из-за <tfoot>, но это всего лишь предположение.

Я обновил свой ответ, включив в него возможность сортировки по номерам, а не только по алфавиту.

Steve0 23.04.2018 16:50
Ответ принят как подходящий

Эта тема закрыта. Вот код, который я искал:

  1. JavaScript: https://jsfiddle.net/tf4e97w6/#&to Generaljs=TGIj8qdzUO
  2. jQuery: https://jsfiddle.net/15ke8Lqv/#&to Generaljs=DACQV5mE9F
  3. Фрагмент кода:

$(document).ready(function() {
  $("th").on("click", function() {
    var column = $(this).index();
    var table = $("table");
    var tbody = table.find("tbody");
    var rows = tbody.find("tr");
    var dir = $(this).data("dir") || -1;
    dir *= -1;
    $(this).siblings().data("dir", -1);

    rows.sort(function(a, b) {
      var aVal = $($(a).find("td")[column]).html().toLowerCase().trim();
      var bVal = $($(b).find("td")[column]).html().toLowerCase().trim();

      if ($.isNumeric(aVal.charAt()) && $.isNumeric(bVal.charAt())) {
        aVal = parseFloat(aVal);
        bVal = parseFloat(bVal);
      }

      return aVal > bVal ? 1 * dir : aVal < bVal ? -1 * dir : 0;
    });

    $(this).data("dir", dir);

    tbody.empty();
    $(rows).appendTo(table);
  });
});
h1 {
  color: #cc1100;
}

table {
  width: 100%;
}

table,
tr,
td {
  border: 1px solid #000000;
  border-collapse: collapse;
}

tfoot,
thead {
  text-align: center;
  background-color: #cccccc;
}

th:hover {
  cursor: pointer;
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <caption>
    <h1>Tablesorter</h1>
  </caption>
  <thead>
    <tr>
      <th>Month</th>
      <th>Savings</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>January</td>
      <td>$150</td>
    </tr>
    <tr>
      <td>February</td>
      <td>$160</td>
    </tr>
    <tr>
      <td>March</td>
      <td>$240</td>
    </tr>
    <tr>
      <td>April</td>
      <td>$160</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan = "2">Sum: $710</td>
    </tr>
  </tfoot>
</table>

С наилучшими пожеланиями, Феликс Реуэр.

Другие вопросы по теме