Как построить сортировку строк (горизонтальная сортировка) для HTML-таблицы? - PullRequest
0 голосов
/ 11 июня 2019

Мне нужно реализовать функциональность в jquery, где пользователь нажимает на самую первую строку и сортирует оставшиеся элементы в строке, по которой щелкнули.Я подготовил здесь кодовую ручку https://codepen.io/shaikh709/pen/orNLaY?editors=0010

Вот js, который я имею для сортировки таблицы

function sortRow(rowIndex) {

    let table               = $('.report')
    let tr                  = table.find('tr');
    let selectedRow         = $(tr[rowIndex]);
    let selectedRowTd       = selectedRow.find('td');
    let selectedRowSorting  = [];

    // find and get clicked tr and it formats it in index and value of the cells
    selectedRowTd.each(function(tdIndex){
        let td = $(selectedRowTd[tdIndex]);
        selectedRowSorting.push({
            tdIndex: tdIndex,
            value: parseInt(Math.ceil(td.text().trim()))
        })
    })


    // it will compare values and sort
    selectedRowSorting = selectedRowSorting.sort(function(a, b){

        if (a.value == 0) {
            return -1;
        }

        if (b.value == 0) {
            return -1;
        }

        return b.value - a.value
    });

    console.log(selectedRowSorting)

    // it will only return indexs of sorted list of cells
    var sortedIndexs = selectedRowSorting.map(function(rowSorting){
        return rowSorting.tdIndex
    })

    console.log(sortedIndexs)

    table.find('tr').each(function(){
        let tr = $(this);
        let modifiedTr = [];

        tr.children().each(function(tdIndex, td){

          if (tdIndex == 0) {
            console.log(td)           
            modifiedTr[0] = td;

          } else {
            for (let i =0; i < sortedIndexs.length;i++) {
              console.log(sortedIndexs[i])
              // it gives me index of sorted column.
              if (tdIndex == i) {
                let sortedIndex = sortedIndexs[i];

                if ( sortedIndex == undefined) {
                  console.log('i', i, sortedIndex)
                  sortedIndex = sortedIndexs.length+1
                }

                modifiedTr[sortedIndex] = td;
              }
            }
          }

        })

        tr.append(modifiedTr)
    })
}

Я создал демо здесь https://codepen.io/shaikh709/pen/orNLaY?editors=0010

Когда пользователь нажимает на первую (очень левую) ячейку подряд.Я хочу, чтобы оставшаяся часть строки переключилась с наибольшего значения на наименьшее.

Застрял здесь на пару дней.Любая помощь приветствуется.Благодарю.:)

1 Ответ

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

Я бы оставил это простым и просто построил небольшой массив значений, а затем использовал бы .sort() для массива.

Рабочий пример: https://jsfiddle.net/Twisty/ondf3ram/

JavaScript

$(function() {
  function sortDesc(a, b) {
    return a - b;
  }

  function sortAsc(a, b) {
    return b - a;
  }

  function sortRow(rObj, desc) {
    var curArr = [];
    $("td", rObj).each(function(i, el) {
      curArr.push(parseInt($(el).text().trim()));
    });
    if (desc == undefined || desc == true) {
      curArr.sort(sortDesc);
    } else {
      curArr.sort(sortAsc);
    }
    $("td", rObj).each(function(i, el) {
      $(el).html(curArr[i]);
    });
  }

  $(".sortable tbody th").on("click", function(e) {
    var r = $(this).parent();
    if ($(this).data("sort") == undefined) {
      $(this).data("sort", true);
    }
    sortRow(r, $(this).data("sort"));
    $(this).data("sort", $(this).data("sort") ? false : true);
  });
});

Использование правильных селекторов вам очень поможет! Я не был уверен, хотите ли вы изменить направление сортировки Descending to Ascending. Итак, вот цели, к которым я стремился:

  • Нажмите <th> (первую) ячейку в <tbody>, чтобы выполнить сортировку родительского элемента <tr>
  • Первоначально сортировка с сортировкой по убыванию
  • Дополнительные щелчки переключают сортировку с Desc. в Asc.

Для этого у нас есть функция sortRow(), которая ожидает jQuery <tr> Object . При желании он может принимать сортировку Direction в качестве логического значения (по умолчанию: true, true = Desc. / false = Asc). Он выполняет сортировку и ничего не возвращает.

Я создал массив и заполнил его, используя функцию .each(), чтобы выполнить итерацию для каждого <td> в целевом <tr>. Поскольку я получаю .text() или текстовый узел ячейки, я использую .trim(), чтобы убрать все пробелы, а затем parseInt(), чтобы заполнить массив целыми числами.

Затем мы сортируем массив на основе функции сравнения:

Функция, которая определяет альтернативный порядок сортировки. Функция должна возвращать отрицательное, нулевое или положительное значение в зависимости от аргументов.

Затем мы повторяем те же ячейки и заменяем содержимое массива. Все сделано!

Я добавил функцию переключения, ища .data() в каждой строке. Если это первый щелчок, данных не будет, поэтому мы принимаем Desc. Сортировать. В следующий раз, когда мы нажмем на этот заголовок строки, он будет иметь значение и переключится на Asc. сортировать.

Update

База оставляйте ваши комментарии, похоже, вы хотите отсортировать Martix. Это обсуждается здесь: Как отсортировать 2-мерный массив по значению столбца?

Рабочий пример: https://jsfiddle.net/Twisty/ondf3ram/70/

JavaScript

$(function() {

  var selInd;

  function sortMatrixDesc(a, b) {
    if (a[selInd] === b[selInd]) {
      return 0;
    } else {
      return (a[selInd] < b[selInd]) ? -1 : 1;
    }
  }

  function sortMatrixAsc(a, b) {
    if (a[selInd] === b[selInd]) {
      return 0;
    } else {
      return (a[selInd] > b[selInd]) ? -1 : 1;
    }
  }

  function getTblCont(tb) {
    var cols = [];
    $("tr:first td", tb).each(function(i, el) {
      cols[i] = [];
    });
    for (var c = 0; c < cols.length; c++) {
      $("tr", tb).each(function(i, el) {
        cols[c].push(parseInt($("td", el).eq(c).text().trim()));
      });
    }
    return cols;
  }

  function sortRow(rObj, desc) {
    var tblObj = getTblCont(rObj.parent());
    var rowInd = rObj.index();
    if (desc == undefined || desc == true) {
      tblObj.sort(sortMatrixDesc);
    } else {
      tblObj.sort(sortMatrixAsc);
    }
    rObj.parent().find("tr").each(function(r, tr) {
      $("td", tr).each(function(i, el) {
        $(el).html(tblObj[i][r]);
      });
    });
  }

  $(".sortable tbody th").on("click", function(e) {
    var r = $(this).parent();
    selInd = r.index();
    if ($(this).data("sort") == undefined) {
      $(this).data("sort", true);
    }
    sortRow(r, $(this).data("sort"));
    $(this).data("sort", $(this).data("sort") ? false : true);
  });
});

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...