【问题标题】:sort all rows from a table with pagination使用分页对表中的所有行进行排序
【发布时间】:2020-07-16 12:06:52
【问题描述】:

我正在构建一个具有分页和排序功能的表格,但我在对所有页面中的项目进行排序时遗漏了一些东西。

  1. 我想做的是对第 1 页和第 2 页中的所有项目进行排序,而不仅仅是从我所在的当前页面中排序。你能告诉我应该如何更新我的代码来实现这一点吗?

  2. 我在最后一列遇到了另一个问题。如何使用 propURL 中的 href 创建链接?此时我得到 [object Object]

这里我有一个我的代码的小提琴

https://jsfiddle.net/c2kmruLs/2/

 <div class="book-component">
    <div class="table-wrapper">
    </div>
  </div>

var data =  {
    "headings": [
      {
        "displayName": "Book",
        "columnID": "bookID"
      },
      {
        "displayName": "Author",
        "columnID": "authorID"
      },
      {
        "displayName": "Year",
        "columnID": "yearID"
      },
      {
        "displayName": "",
        "columnID": "urlID"
      }
    ],
    "items": [
      {
        "bookID": "The Great Gatsby",
        "authorID": " F Scott Fitzgerald",
        "yearID": "1925",
        "urlId": {
          "name": "View book",
          "propURL": "https://google.com"
        }
      },
      {
        "bookID": "The Grapes of Wrath",
        "authorID": "John Steinbeck",
        "yearID": "1939",
        "urlId": {
          "name": "View book",
          "propURL": "https://google.com"
        }
      },
      {
        "bookID": "A Wild Sheep Chase",
        "authorID": "Haruki Murakami",
        "yearID": "1982",
        "urlId": {
          "name": "View book",
          "propURL": "https://google.com"
        }
      },
      {
        "bookID": "A Farewell to Arms",
        "authorID": "Ernest Hemingway",
        "yearID": "1929",
       "urlId": {
          "name": "View book",
          "propURL": "https://google.com"
        }
      }
    ]
  }
  
  
var TABLE = document.createElement('table');
TABLE.setAttribute('class', 'pagination');
TABLE.setAttribute('data-pagecount', '2');
const TABLE_WRAPPER = document.querySelector('.book-component .table-wrapper');
  TABLE_WRAPPER.appendChild(TABLE);


for (const field in data) {
      var tr = document.createElement('tr'); 
   if(field == "headings"){

      for (const child in data.headings) {
         var th = document.createElement('th');
           th.setAttribute('class', 'sort-cta');
         tr.appendChild(th);
         th.innerText = data.headings[child].displayName; 
         TABLE.appendChild(tr);
       }
   }
   else if(field == "items"){
      for (const child in data.items) {
         var tr = document.createElement('tr'); 
         let item = data.items[child];
         for (const row in item) {
          var td = document.createElement('td');
          tr.appendChild(td);
          td.innerText = item[row]; 
          TABLE.appendChild(tr);
         }
       }
   }
}

const SORT_LINK = document.querySelectorAll('.sort-cta');
  SORT_LINK.forEach((item) => {
    item.addEventListener('click', () => {
      sortTable(0);
    });
  });

function sortTable(n) {
  var table,
    rows,
    switching,
    i,
    x,
    y,
    shouldSwitch,
    dir,
    switchcount = 0;
  table = document.querySelector('.pagination');
  switching = true;
  dir = 'asc';
  while (switching) {
    switching = false;
    rows = table.rows;
    for (i = 1; i < rows.length - 1; i++) {
      shouldSwitch = false;
      x = rows[i].getElementsByTagName('TD')[n];
      y = rows[i + 1].getElementsByTagName('TD')[n];
      if (dir == 'asc') {
        if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
          shouldSwitch = true;
          break;
        }
      } else if (dir == 'desc') {
        if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
          shouldSwitch = true;
          break;
        }
      }
    }
    if (shouldSwitch) {
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
      switching = true;
      switchcount++;
    } else {
      if (switchcount == 0 && dir == 'asc') {
        dir = 'desc';
        switching = true;
      }
    }
  }
}


var perPage = 20;

function genTables() {
    var tables = document.querySelectorAll(".pagination");
    for (var i = 0; i < tables.length; i++) {
        perPage = parseInt(tables[i].dataset.pagecount);
        createFooters(tables[i]);
        createTableMeta(tables[i]);
        loadTable(tables[i]);
    }
}


function loadTable(table) {
    var startIndex = 0;

    if (table.querySelector('th'))
        startIndex = 1;



    var start = (parseInt(table.dataset.currentpage) * table.dataset.pagecount) + startIndex;
    var end = start + parseInt(table.dataset.pagecount);
    var rows = table.rows;

    for (var x = startIndex; x < rows.length; x++) {
        if (x < start || x >= end)
            rows[x].classList.add("inactive");
        else
            rows[x].classList.remove("inactive");
    }
}

function createTableMeta(table) {
    table.dataset.currentpage = "0";
}

function createFooters(table) {
    var hasHeader = false;
    if (table.querySelector('th'))
        hasHeader = true;

    var rows = table.rows.length;

    if (hasHeader)
        rows = rows - 1;

    var numPages = rows / perPage;
    var pager = document.createElement("div");

    
    if (numPages % 1 > 0)
        numPages = Math.floor(numPages) + 1;

    pager.className = "pager";
    for (var i = 0; i < numPages ; i++) {
        var page = document.createElement("div");
        page.innerHTML = i + 1;
        page.className = "pager-item";
        page.dataset.index = i;

        if (i == 0)
            page.classList.add("selected");

        page.addEventListener('click', function() {
            var parent = this.parentNode;
            var items = parent.querySelectorAll(".pager-item");
            for (var x = 0; x < items.length; x++) {
                items[x].classList.remove("selected");
            }
            this.classList.add('selected');
            table.dataset.currentpage = this.dataset.index;
            loadTable(table);
        });
        pager.appendChild(page);
    }

    
    table.parentNode.insertBefore(pager, table);
}

window.addEventListener('load', function() {
    genTables();
});

【问题讨论】:

    标签: javascript json sorting object


    【解决方案1】:

    对于您的第一个问题:我不确定这是否对用户非常有用,因为如果您对表格的第二页进行排序,您的表格第一页中的值将始终最高。我猜这是你不会做的事情。

    第二个问题:您看到一个 [obejct 对象],因为您想直接显示该对象。您必须再次循环以显示它的值。

    for (const row in item) {
              var td = document.createElement('td');
              
              if (typeof(item[row]) === 'object') {
    
                  for (const obj in item[row]) {
               
                      tr.appendChild(td);
                      td.innerHTML = '<a target="_blank" href="' + item[row][obj] + '">' + item[row][obj] + '</a>'; 
                      TABLE.appendChild(tr);
                      TABLE.appendChild(tr);
                  }
                      
              } else {
                      tr.appendChild(td);
                      td.innerText = item[row]; 
                      TABLE.appendChild(tr);
              }
      }
    

    请看下面的例子:

    var data =  {
        "headings": [
          {
            "displayName": "Book",
            "columnID": "bookID"
          },
          {
            "displayName": "Author",
            "columnID": "authorID"
          },
          {
            "displayName": "Year",
            "columnID": "yearID"
          },
          {
            "displayName": "",
            "columnID": "urlID"
          }
        ],
        "items": [
          {
            "bookID": "The Great Gatsby",
            "authorID": " F Scott Fitzgerald",
            "yearID": "1925",
            "urlId": {
              "name": "View book",
              "propURL": "https://google.com"
            }
          },
          {
            "bookID": "The Grapes of Wrath",
            "authorID": "John Steinbeck",
            "yearID": "1939",
            "urlId": {
              "name": "View book",
              "propURL": "https://google.com"
            }
          },
          {
            "bookID": "A Wild Sheep Chase",
            "authorID": "Haruki Murakami",
            "yearID": "1982",
            "urlId": {
              "name": "View book",
              "propURL": "https://google.com"
            }
          },
          {
            "bookID": "A Farewell to Arms",
            "authorID": "Ernest Hemingway",
            "yearID": "1929",
           "urlId": {
              "name": "View book",
              "propURL": "https://google.com"
            }
          }
        ]
      }
      
      
    var TABLE = document.createElement('table');
    TABLE.setAttribute('class', 'pagination');
    TABLE.setAttribute('data-pagecount', '2');
    const TABLE_WRAPPER = document.querySelector('.book-component .table-wrapper');
      TABLE_WRAPPER.appendChild(TABLE);
    
    
    for (const field in data) {
          var tr = document.createElement('tr'); 
       if(field == "headings"){
    
          for (const child in data.headings) {
             var th = document.createElement('th');
               th.setAttribute('class', 'sort-cta');
             tr.appendChild(th);
             th.innerText = data.headings[child].displayName; 
             TABLE.appendChild(tr);
           }
       }
       else if(field == "items"){
          for (const child in data.items) {
             var tr = document.createElement('tr'); 
             let item = data.items[child];
             for (const row in item) {
              var td = document.createElement('td');
              
              if (typeof(item[row]) === 'object') {
              for (const obj in item[row]) {
               
               tr.appendChild(td);
    
                 td.innerHTML = '<a target="_blank" href="' + item[row][obj] + '">' + item[row][obj] + '</a>'; 
                 TABLE.appendChild(tr);
              }
                      
              } else {
                        tr.appendChild(td);
    
                 td.innerText = item[row]; 
                 TABLE.appendChild(tr);
              }
             }
           }
       }
    }
    
    const SORT_LINK = document.querySelectorAll('.sort-cta');
      SORT_LINK.forEach((item) => {
        item.addEventListener('click', () => {
          sortTable(0);
        });
      });
    
    function sortTable(n) {
      var table,
        rows,
        switching,
        i,
        x,
        y,
        shouldSwitch,
        dir,
        switchcount = 0;
      table = document.querySelector('.pagination');
      switching = true;
      dir = 'asc';
      while (switching) {
        switching = false;
        rows = table.rows;
            
        for (i = 1; i < rows.length - 1; i++) {
          shouldSwitch = false;
          x = rows[i].getElementsByTagName('TD')[n];
          y = rows[i + 1].getElementsByTagName('TD')[n];
          if (dir == 'asc') {
            if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
              shouldSwitch = true;
              break;
            }
          } else if (dir == 'desc') {
            if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
              shouldSwitch = true;
              break;
            }
          }
        }
        if (shouldSwitch) {
          rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
          switching = true;
          switchcount++;
        } else {
          if (switchcount == 0 && dir == 'asc') {
            dir = 'desc';
            switching = true;
          }
        }
      }
    }
    
    
    var perPage = 20;
    
    function genTables() {
        var tables = document.querySelectorAll(".pagination");
        for (var i = 0; i < tables.length; i++) {
            perPage = parseInt(tables[i].dataset.pagecount);
            createFooters(tables[i]);
            createTableMeta(tables[i]);
            loadTable(tables[i]);
        }
    }
    
    // based on current page, only show the elements in that range
    function loadTable(table) {
        var startIndex = 0;
    
        if (table.querySelector('th'))
            startIndex = 1;
    
        var start = (parseInt(table.dataset.currentpage) * table.dataset.pagecount) + startIndex;
        var end = start + parseInt(table.dataset.pagecount);
        var rows = table.rows;
    
        for (var x = startIndex; x < rows.length; x++) {
            if (x < start || x >= end)
                rows[x].classList.add("inactive");
            else
                rows[x].classList.remove("inactive");
        }
    }
    
    function createTableMeta(table) {
        table.dataset.currentpage = "0";
    }
    
    function createFooters(table) {
        var hasHeader = false;
        if (table.querySelector('th'))
            hasHeader = true;
    
        var rows = table.rows.length;
    
        if (hasHeader)
            rows = rows - 1;
    
        var numPages = rows / perPage;
        var pager = document.createElement("div");
    
        // add an extra page, if we're 
        if (numPages % 1 > 0)
            numPages = Math.floor(numPages) + 1;
    
        pager.className = "pager";
        for (var i = 0; i < numPages ; i++) {
            var page = document.createElement("div");
            page.innerHTML = i + 1;
            page.className = "pager-item";
            page.dataset.index = i;
    
            if (i == 0)
                page.classList.add("selected");
    
            page.addEventListener('click', function() {
                var parent = this.parentNode;
                var items = parent.querySelectorAll(".pager-item");
                for (var x = 0; x < items.length; x++) {
                    items[x].classList.remove("selected");
                }
                this.classList.add('selected');
                table.dataset.currentpage = this.dataset.index;
                loadTable(table);
            });
            pager.appendChild(page);
        }
    
        // insert page at the top of the table
        table.parentNode.insertBefore(pager, table);
    }
    
    window.addEventListener('load', function() {
        genTables();
    });
    tr.inactive {
          display: none;
        }
        
        .table-wrapper {
          display: flex;
    flex-direction: column-reverse;
        }
    .pager {
        display: flex;
        justify-content: center;
        padding: 0;
        margin-top: 10px;
        font-weight: 800;
    }    
        
    .pager-item.selected {
      outline: none;
        border-color: #0077cc;
        background: #0077cc;
        color: #fff;
        cursor: default;
    }
    <div class="book-component">
        <div class="table-wrapper">
    
        </div>
    
      </div>

    【讨论】:

    • 完全理解您在第一个问题中所说的话。但是对于第二个,感谢您花时间回答,但我仍然不明白如何使用 href 属性建立一个链接作为 propUrl 的值,并将 btn 附加到该列的 td 内而不是让它像字符串一样。
    • 不客气。如果将innerText 更改为innerHTML 并在其中添加链接标签,则可以添加链接。 td.innerHTML = '' + item[row][obj] + '';
    • 和最后一个问题 :)) 对于排序部分,如果从第二页触发排序以始终返回到第一页并让所有值排序 desc ?并且第一页总是在 asc 和 desc 值之间切换?如果我说的有道理
    • 这是可能的,但不是最佳做法。想象一下,用户在对表格进行排序时总是从一个页面跳到另一个页面。在大多数情况下,用户希望对每页的数据进行排序并且知道这一点。我不知道你想在表中显示多少数据,但延迟加载表和使用数据库查询进行搜索一直运行良好。在显示表格时,还有一些很好的框架可以让您的工作更轻松。 bashooka.com/coding/javascript-data-table-libraries
    • 如果您认为我的回答有用,如果您能将其标记为正确,我会很高兴。 :o)
    猜你喜欢
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    相关资源
    最近更新 更多