Tablesorter сортирует обычным образом проанализированные номера только в порядке убывания, порядок возрастания неверный - PullRequest
0 голосов
/ 04 июня 2019

Использование Mottie's fork tableorter . Необходимо отсортировать даты в формате «16 января». С августа по июль.

Написал пользовательский парсер.

let monthsFirstDayIndexes = {
    'Aug': 0,
    'Sep': 31,
    'Oct': 61,
    'Nov': 92,
    'Dec': 122,
    'Jan': 153,
    'Feb': 184,
    'Mar': 213,
    'Apr': 244,
    'May': 274,
    'Jun': 305,
    'Jul': 335,
  }

$.tablesorter.addParser({
  id: 'date',
  is: function() {
    return false;
  },

  format: function(s) {
    dateSplitted = s.split(' ')
    return monthsFirstDayIndexes[dateSplitted[0]] + Number(dateSplitted[1])
 },

     type: 'numeric'
  });

Я использую парсер это шаблон Django

{% extends 'base.html' %}
{% load static %}
{% load tags %}

{% block title %}
  {{ player.name }} - Game Log - NHL stats tracker
{% endblock title %}

{% block styles %}
  <link rel="stylesheet" href="{% static 'players/tablesorter.css' %}">
{% endblock styles %}

{% block content %}
      <img class="rounded-circle account-img" src="{{ player.image.url }}">
             <h5>{{ player.name }} Game Log</h5>
             <a href="{% url 'player_detail' player.slug player.nhl_id %}">Return to the full profile</a><br>
            <!-- GOALIES       -->
              {% if player.position_abbr == 'G' %}
              <!-- GAMELOG       -->
              <table id="tab1" class="tablesorter">
                <thead>
                  <tr>
                    <th>Date</th>
                    <th>Opp</th>
                    <th>Res</th>
                    <th>Min</th>
                    <th>GA</th>
                    <th>SV %</th>
                    <th>SV</th>
                    <th>SA</th>
                    <th>SHO</th>
                  </tr>
                </thead>
                <!-- PAGER -->
                <tfoot>
                  <tr class="tablesorter-ignoreRow">
                    <th colspan="28" class="pager"></th>
                  </tr>
                  <tr class="tablesorter-ignoreRow">
                    <th colspan="28" class="pager-g form-horizontal pager">
                      <button type="button" class="btn first"><i class="small material-icons">first_page</i></button>
                      <button type="button" class="btn prev"><i class="small material-icons">navigate_before</i></button>
                      <span class="pagedisplay"></span>
                      <button type="button" class="btn next"><i class="small material-icons white">navigate_next</i></button>
                      <button type="button" class="btn last"><i class="small material-icons">last_page</i></button>
                      <select class="pagesize browser-default" title="Select page size">
                        <option selected="selected" value="25">25</option>
                        <option value="50">50</option>
                        <option value="100">100</option>
                        <option value="200">200</option>
                        <option value="all">All</option>
                      </select>
                    </th>
                  </tr>
                </tfoot>
                <tbody>
                {% for game in player.gamelog_stats %}
                  <tr>
                    <td>{{ game.date }}</td>
                    <td>{{ game.opponent.id }}</td>
                    <td>{{ game.stat.decision }}</td>
                    <td>{{ game.stat.timeOnIce }}</td>
                    <td>{{ game.stat.goalsAgainst }}</td>
                    <td>{{ game.stat.savePercentage|floatformat:3 }}</td>
                    <td>{{ game.stat.saves }}</td>
                    <td>{{ game.stat.shotsAgainst }}</td>
                    <td>{{ game.stat.shutouts }}</td>
                  </tr>
                {% endfor %}
                </tbody>
              </table>

              {% else %}
              <!-- SKATERS       -->
              <table id="tab2" class="sortable">
                <thead>
                  <tr>
                    <th class="sorter-date">Date</th>
                    <th>Opp</th>
                    <th>G</th>
                    <th>A</th>
                    <th>Pts</th>
                    <th>+/-</th>
                    <th>PIM</th>
                    <th>SOG</th>
                    <th>Hits</th>
                    <th>Blk</th>
                    <th>FW</th>
                    <th>PPP</th>
                    <th>SHP</th>
                    <th class="sorter-countdown">TOI</th>
                    <th class="sorter-countdown">TOI PP</th>
                    <th class="sorter-countdown">TOI SH</th>
                  </tr>
                </thead>
                <!-- PAGER -->
                <tfoot>
                  <tr class="tablesorter-ignoreRow">
                    <th colspan="28" class="pager"></th>
                  </tr>
                  <tr class="tablesorter-ignoreRow">
                    <th colspan="28" class="pager-s form-horizontal pager">
                      <button type="button" class="btn first"><i class="small material-icons">first_page</i></button>
                      <button type="button" class="btn prev"><i class="small material-icons">navigate_before</i></button>
                      <span class="pagedisplay"></span>
                      <button type="button" class="btn next"><i class="small material-icons white">navigate_next</i></button>
                      <button type="button" class="btn last"><i class="small material-icons">last_page</i></button>
                      <select class="pagesize browser-default" title="Select page size">
                        <option selected="selected" value="25">25</option>
                        <option value="50">50</option>
                        <option value="100">100</option>
                        <option value="200">200</option>
                        <option value="all">All</option>
                      </select>
                    </th>
                  </tr>
                </tfoot>
                <tbody>
                {% for game in player.gamelog_stats %}
                  <tr>
                    <td>{{ game.date }}</td>
                    <td>{{ game.opponent.id }}</td>
                    <td>{{ game.stat.goals }}</td>
                    <td>{{ game.stat.assists }}</td>
                    <td>{{ game.stat.points }}</td>
                    <td>{{ game.stat.plusMinus }}</td>
                    <td>{{ game.stat.pim }}</td>
                    <td>{{ game.stat.shots }}</td>
                    <td>{{ game.stat.hits }}</td>
                    <td>{{ game.stat.blocked }}</td>
                    <td>{{ game.stat.faceOffWins }}</td>
                    <td>{{ game.stat.powerPlayPoints }}</td>
                    <td>{{ game.stat.shortHandedPoints }}</td>
                    <td>{{ game.stat.timeOnIce }}</td>
                    <td>{{ game.stat.powerPlayTimeOnIce }}</td>
                    <td>{{ game.stat.shortHandedTimeOnIce }}</td>
                  </tr>
                {% endfor %}
                </tbody>
              </table>
              {% endif %}
{% endblock content %}

{% block scripts %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.1/js/jquery.tablesorter.js"></script>
<!-- Widgets -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.1/js/jquery.tablesorter.widgets.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.1/js/extras/jquery.tablesorter.pager.min.js"></script>

<script src="{% static 'players/parser-duration.js' %}"></script>
<script src="{% static 'players/parser-date.js' %}"></script>
<script src="{% static 'players/sorting_player_gamelog.js' %}"></script>
{% endblock scripts %}

Результат сортировки по порядку asc. Проблема в том, что даты с днями <10 отсортированы в неправильном порядке. </p> * +1012 *enter image description here

Порядок desc в порядке.

enter image description here

Также пытался использовать parseInt(dateSplitted[1]) вместо Number(dateSplitted[1]). Это дает еще более странные результаты.

Проверен тот же метод анализа в простой JS с пользовательской сортировкой. Это работает.

let monthsFirstDayIndexes = {
    'Aug': 0,
    'Sep': 31,
    'Oct': 61,
    'Nov': 92,
    'Dec': 122,
    'Jan': 153,
    'Feb': 184,
    'Mar': 213,
    'Apr': 244,
    'May': 274,
    'Jun': 305,
    'Jul': 335,
  }

let dates = [
  'Mar 3',
  'Nov 24',
  'Nov 25',
  'Sep 14',
  'Mar 5',
  'Mar 7',
  'Jan 25',
  'Sep 8',
  'Mar 16',
  'Jan 12',
  'Mar 8',
]

dateSplitted = dates.map(item => item.split(' '));

function sortFunc(a, b) {
  return (monthsFirstDayIndexes[a[0]] + Number(a[1])) - (monthsFirstDayIndexes[b[0]] + Number(b[1]));
}

console.log(dateSplitted.sort(sortFunc).map(item => item.join(' ')));

Есть какие-нибудь мысли о том, как заставить это работать для TableSorter? Дело в том, что я действительно не знаю, как отлаживать мой код в этом случае, как увидеть фактические числа, которые он анализирует, по датам в HTML-коде.

1 Ответ

1 голос
/ 05 июня 2019

Проблема была на самом деле не в JavaScript.Я запутался, потому что на странице все даты показаны без лишних пробелов между символами.Но во всех датах, где день <10, было дополнительное место. Я понял, что проверял исходный код HTML.</p>

enter image description here

Произошла ошибка в скрипте Django, который загружает и конвертирует формат даты из источника API в мою БД.

def date_convert(date):
    datetime_obj = datetime.datetime.strptime(date, '%Y-%m-%d')
    return datetime_obj.strftime('%b %e')

Я изменил формат дня с% d (с добавлением нуля) на% e (без заполнения нулями).Таким образом, это добавляло дополнительное пространство к дням с 1 цифрой вместо ноля.И Number(dateSplitted[1] был равен нулю, а не номеру дня, который я ожидал.Таким образом, все даты с днями, состоящими из 1 цифры, были отсортированы как monthsFirstDayIndexes для данного месяца, без добавления фактических номеров.

Поэтому мне нужно использовать заполнение нулями или убрать лишний пробел.Я решил пойти со вторым вариантом.Использовал regex

import re 

def date_convert(date):
    datetime_obj = datetime.datetime.strptime(date, '%Y-%m-%d')
    date_str = datetime_obj.strftime('%b %e')
    return re.sub(r'\s+', ' ', date_str)

Я также хотел бы добавить, что я мог бы легко найти источник ошибки, если бы знал, что могу просто записывать все, что я хочу, в консоль браузера (например, F12 в Firefox).Рисунок ясно показывает, что в некоторых датах есть дополнительное место, и из-за этого парсер не вывел ожидаемых чисел.Эти знания могут сэкономить вам время.Кстати, имя console.log в данном случае довольно очевидно.

enter image description here.

...