2

I am trying to use sorting in a table. I am using given below method but there is an error in sorting numbers using bellow Method. This method works properly but issues in numbers ASC and DESC order. I didn't get why happening this. guys, you have any idea about this?

function sortTable(n, selector) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
///table = document.getElementById(selector);
table = $(selector);
switching = true;

//Set the sorting direction to ascending:
dir = "asc";
/*Make a loop that will continue until
no switching has been done:*/
while (switching) {
    //start by saying: no switching is done:
    switching = false;
    rows = $(table).find('tr'); ///table.getElementsByTagName("TR");
    /*Loop through all table rows (except the
    first, which contains table headers):*/
    for (i = 0; i < (rows.length - 1) ; i++) {
        //start by saying there should be no switching:
        shouldSwitch = false;
        /*Get the two elements you want to compare,
        one from current row and one from the next:*/
        x = rows[i].getElementsByTagName("TD")[n];
        y = rows[i + 1].getElementsByTagName("TD")[n];
        /*check if the two rows should switch place,
        based on the direction, asc or desc:*/
        if (x != null && y != null) {
            if (dir == "asc") {
                if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
                    //if so, mark as a switch and break the loop:
                    shouldSwitch = true;
                    break;
                }
            } else if (dir == "desc") {
                if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
                    //if so, mark as a switch and break the loop:
                    shouldSwitch = true;
                    break;
                }
            }
        }
    }
    if (shouldSwitch) {
        /*If a switch has been marked, make the switch
        and mark that a switch has been done:*/
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        switching = true;
        //Each time a switch is done, increase this count by 1:
        switchcount++;
    } else {
        /*If no switching has been done AND the direction is "asc",
        set the direction to "desc" and run the while loop again.*/
        if (switchcount == 0 && dir == "asc") {
            dir = "desc";
            switching = true;
        }
    }
}
}
Kohei TAMURA
  • 4,970
  • 7
  • 25
  • 49
Neeraj Pathak
  • 759
  • 4
  • 13
  • Instead of `$(table).find('tr')` it is very much more efficient to use `table.rows`, and instead of `rows[i].getElementsByTagName("TD")[n]` consider `rows[i].cells[n]`. A lot less to type if nothing else. ;-) This is a bubble sort, which is very inefficient. Consider putting the rows you want to sort into an array, sort using *Array.prototype.sort*, then put the rows into the sorted order. – RobG Jun 17 '17 at 13:58

2 Answers2

2

If you want to sort table rows using any particular column and sort as numbers, you can leverage the built-in Array.prototype.sort method by putting the rows to sort into an array, sort the array, then put the rows into the table in the required order. E.g.:

function sortMe(evt) {
  var table = this;          // Table clicked on
  var cell = evt.target;     // Cell clicked on
  var col = cell.cellIndex;  // Column number
  
  // Put rows into an array
  var rowArray = [].slice.call(table.rows);
  // Or for ECMAScript 2015
  // var rowArray = Array.from(table.rows);

  // Sort rows
  rowArray.sort(function(a, b) {
  
    // Get values of col to sort on
    a = a.cells[col].textContent;
    b = b.cells[col].textContent;

    // If numeric, sort as number
    if (isNumeric(a)) {
      return a - b;
    }
    // Other sort options here, e.g. as dates
    // Otherwise, sort as string
    return a.localeCompare(b);
  });
  
  // Put rows back in table in order
  var tbody = table.tBodies[0];
  rowArray.forEach(function (row) {
    tbody.appendChild(row);
  })

}

// Helper function
// Check if value is numeric, '2' returns true
function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

// Attach listener to table
window.onload = function() {
  document.querySelector('table').addEventListener('click', sortMe, false);
}
table {
  border-collapse: collapse;
}
td {
  border: 1px solid #bbbbbb;
  width: 5em;
}
<table>
  <tr><td>A<td>3
  <tr><td>D<td>0
  <tr><td>B<td>1
  <tr><td>C<td>2
</table>

A click in any column sorts the column. You can add extras like adding a header and footer, toggling between ascending and descending sorts, dealing with blank cells, etc.

You might consider using a class or data attribute in a header cell to control the type of sort to use.

RobG
  • 142,382
  • 31
  • 172
  • 209
0

var filter='';

function myFunction() {
    var input, ul, li, a, i;
    input = document.getElementById("myInput");
    filter = input.value.toUpperCase();
    var product = object.filter(filterByID)
    console.log(product);
}



function filterByID(item) {

    if (item.First_Name.toUpperCase().indexOf(filter) > -1) {
        return true;
    }
    return false;
}

var object = [
  {
    "First_Name": "Adele",
  },
  {
    "First_Name": "Neeraj",
  },
   {
    "First_Name": "Nitin",
  },
]
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 12px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myUL {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

#myUL li a {
  border: 1px solid #ddd;
  margin-top: -1px; /* Prevent double borders */
  background-color: #f6f6f6;
  padding: 12px;
  text-decoration: none;
  font-size: 18px;
  color: black;
  display: block
}

#myUL li a.header {
  background-color: #e2e2e2;
  cursor: default;
}

#myUL li a:hover:not(.header) {
  background-color: #eee;
}
<h2>My Phonebook</h2>

<input type="text" id="myInput" oninput="myFunction()" placeholder="Search for names.." title="Type in a name">
Neeraj Pathak
  • 759
  • 4
  • 13