简体   繁体   中英

How to sort by rows containing words and numbers in javascript

Newbie here how can I sort all of the following table row attach an onclick listener on the header after it is displayed.

ID Name Inventory Volume
1 Rachel Data is not enough
2 Ross 100
3 Monica 1
4 Connor Data is not enough
5 Dustin -5

into this sorting example is in descending, the words should be the last.

ID Name Inventory Volume
2 Ross 100
3 Monica 10
5 Dustin -5
1 Rachel Data is not enough
4 Connor Data is not enough

But I also want the other columns to be sorted as well and the other columns to have the function to sort as well.

Tried this solution but only works for the column. https://jsfiddle.net/7wnke5q2/

function sortData(data, method) {
  let lessData = 'Data Not Enough'
  let lastItems = []
  let sortedList;
  if (method == 'descending') {
    sortedList = data.sort((a, b) => {
      return a - b
    })
  } else if (method == 'ascending') {
    sortedList = data.sort((a, b) => {
      return b - a
    })
  }
  for (let i = 0; i < sortedList.length; i++) {
    if (sortedList[i] == lessData) {
      let item = sortedList[i]
      sortedList.splice(i, 1)
      sortedList.push(item)
    }
  }
  sortedList = sortedList.concat(lastItems)
  return sortedList
}

Could you please help me out. Thanks in advance!

If i understand, you need all "Data Not Enough" at the end. So, it can works:

function sortData(data, method) {
    let lessData = 'Data Not Enough'
    let sortedList;  
    sortedList = data.sort((a, b) => {
        if(a=='Data Not Enough')
            return 1
        if(b=='Data Not Enough')
            return -1
      return method=='ascending'?a-b:b-a
      })
    return sortedList
}

something like that ?
just click on header columns to sort the table

 const myTableHead = document.querySelector('#my-table thead') , myTableHead_TH = document.querySelectorAll('#my-table thead th') , myTableBody = document.querySelector('#my-table tbody') , myTableBody_TR = [...document.querySelectorAll('#my-table tbody tr')] , sortOrder = ['','asc','desc'] , isDNE = str => str.trim() === 'Data is not enough' ; myTableHead.onclick = ({target}) => { if (!target.matches('th')) return let idx = (sortOrder.findIndex(x=>x===target.className) +1) %3 myTableHead_TH.forEach(th=>th.className='') target.className = sortOrder[idx] if ( sortOrder[idx] ) { myTableBody_TR .sort(dynaSort(target.cellIndex, target.dataset.type, sortOrder[idx] )) .forEach(tr=>myTableBody.appendChild(tr) ) } } function dynaSort( colIndex, colType, order='asc' ) { let sortOrder = (order === 'desc') ? -1 : 1 return function(row_a,row_b) { let a = row_a.cells[colIndex].textContent , b = row_b.cells[colIndex].textContent ; if (isDNE(a) && isDNE(b)) return 0 if (isDNE(a)) return +1 if (isDNE(b)) return -1 if (colType==='str') return (a.trim().localeCompare(b.trim())) *sortOrder return (Number(a) - Number(b)) *sortOrder } }
 table { border-collapse : collapse; margin : 2em 1em; font-family: Arial, Helvetica, sans-serif; } td,th { padding : .2em .8em; border : 1px solid darkblue; } th::after { display : block; float : inline-end; content : '\\25B7'; margin : 0 0 0 1em; transition : 180ms; color : transparent; } th.asc::after { transform : rotate(-90deg); color : whitesmoke; } th.desc::after { transform : rotate(+90deg); color : whitesmoke; } thead { background : #437c97; color : whitesmoke; cursor : pointer; }
 <table id="my-table" > <thead> <tr> <th data-type="num">ID</th> <th data-type="str">Name</th> <th data-type="num">Inventory Volume</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Rachel</td> <td>Data is not enough</td> </tr> <tr> <td>2</td> <td>Ross</td> <td> 100 </td> </tr> <tr> <td>3</td> <td>Monica</td> <td> 1 </td> </tr> <tr> <td>4</td> <td>Connor</td> <td>Data is not enough</td> </tr> <tr> <td>5</td> <td>Dustin</td> <td> -5 </td> </tr> </tbody> </table>

  • This should work! Using @YamirL sort alghoritm.
function sort(e, method) {
  //Get table
  while ((e = e.parentElement) && !e.classList.contains("table"));
  //Get rows
  let rows = Array.from(e.getElementsByTagName("tr"));
  //Get each value for each row
  let values = rows.map(row => {
    let tds = Array.from(row.getElementsByTagName("td"));
    return tds.map(td => td.innerHTML);
  });
  /* 
  values is a 2D array which contains each row and column
  values = [
    [Name, Volume],               --> The headers need to be removed
    [Joey, Data Not Enough],
    [Ross,  -5],
    [Monica,    1],
    [Ben,   100],
    [Chandler, Data Not Enough]
  ];
  */
  values.shift(); //remove headers

  // Now we need to sort the array by volume
  values.sort((a, b) => {
    var exception = "Data Not Enough";
    if(a[1] == exception)
      return 1;
    if(b[1] == exception)
      return -1;
    return method == 'ascending' ? a[1] - b[1] : b[1] - a[1];
  });

  /*******     Put sort values on table     *************/

  // Get body
  let body = e.getElementsByTagName("tbody")[0];
  // Erase Body
  body.innerHTML = "";
  // Iterate each row
  values.forEach(row => {
    // Create new row element
    let tr = document.createElement("tr");
    // Iterate each column
    row.forEach(val => {
      // Create new value
      let td = document.createElement("td");
      // Append values
      td.append(val);
      tr.append(td);
    });
    // Append row to body
    body.append(tr);
  });
}

Here it is a snippet to try the complete code , I added a <tbody> to the table.

 function sort(e, method) { while ((e = e.parentElement) && !e.classList.contains("table")); let rows = Array.from(e.getElementsByTagName("tr")); let values = rows.map(row => { let tds = Array.from(row.getElementsByTagName("td")); return tds.map(td => td.innerHTML); }); values.shift(); values.sort((a, b) => { var exception = "Data Not Enough"; if(a[1] == exception) return 1; if(b[1] == exception) return -1; return method == 'ascending' ? a[1] - b[1] : b[1] - a[1]; }); let body = e.getElementsByTagName("tbody")[0]; body.innerHTML = ""; values.forEach(row => { let tr = document.createElement("tr"); row.forEach(val => { let td = document.createElement("td"); td.append(val); tr.append(td); }); body.append(tr); }); }
 .clickable { cursor: pointer; } .clickable:hover { opacity: 0.7; }
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <table class="table"> <thead> <tr> <th scope="col">Name</th> <th scope="col" class="clickable" onclick='sort(this, "descending")'>Volume</th> </tr> </thead> <tbody> <tr> <td>Joey</td> <td>Data Not Enough</td> </tr> <tr> <td>Ross</td> <td>-5</td> </tr> <tr> <td>Monica</td> <td>1</td> </tr> <tr> <td>Ben</td> <td>100</td> </tr> <tr> <td>Chandler</td> <td>Data Not Enough</td> </tr> </tbody> </table>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM