0

I was trying to sort data from a JavaScript object dynamically based on what option is selected by user. If the user selects ID, the data should be sorted by ID as also for Name and back and forth if you switch the Select element. Stuck as created a function and attached a onchange method on Select but it obviously doesn't work. Can someone please help? Also, the main issue I am facing is how do I customize the options element.

//sorting based on selection which is the issue

function sorting() {
var my_options = $("#sort option");
var selected = $("#sort").val();

my_options.sort(function(a, b) {
  if (a.text > b.text) return 1;
  if (a.text < b.text) return -1;
  return 0
  })
$("#sort").empty().append(my_options);
$("#sort").val(selected);
}

Fiddle

2
  • The code you've shown is trying to sort the option elements in the select box, but you're supposed to be sorting the data displayed in the div elements. Commented Mar 27, 2017 at 3:38
  • yeah correct. I want to sort the data in li elements based on my selection. But can't get my head wrapped around it. Commented Mar 27, 2017 at 3:41

2 Answers 2

3

There are (at least) two ways to approach this:

  1. Sort the original data and then rebuild the HTML from the result - this would probably result in neater JavaScript.
  2. Sort the DOM elements - this might be faster.

The following implements option 1.

  • The first thing I do is use .map() with Object.keys() to convert the original object to an array of employees. That way the .sort() method can be used.
  • I've made some minor changes to the code that creates the HTML so that it works with the new array of employee objects, and put that in a function so that it can be called from the sort change handler.
  • The actual sorting will work on any of the employee properties, where ID uses a numeric sort, otherwise it does a text-based sort (the text-based sort even works on the dates because of the YYYY-MM-DD format).

var employeesById = {
  "8110923": { "Name": "John Glanton", "Position": "Chief Executive", "Hire Date": "2008-01-15" },
  "7734981": { "Name": "Samuel Chamberlain", "Position": "Sales", "Hire Date": "2012-05-01" },
  "3400981": { "Name": "Louis Toadvine", "Position": "Customer Support", "Hire Date": "2011-08-24" },
  "5517823": { "Name": "Ben Tobin", "Position": "Developer", "Hire Date": "2013-03-19" },
  "4587234": { "Name": "David Brown", "Position": "Director of HR", "Hire Date": "2012-01-10" }
};

var employeesArray = Object.keys(employeesById).map(function(v) {
  return $.extend({ ID: v }, employeesById[v]);
});

displayData(employeesArray); // initial display of data

function displayData(employees) {
  var wrapper = $('#employees').empty();
  employees.forEach(function(employee) {
    var empDiv = $('<div class="employee"></div>');
    wrapper.append(empDiv);
    empDiv.append('<span class="name">' + employee.Name + ' ' + '</span>');
    empDiv.append('<span class="position">' + employee.Position + ' ' + '</span>');
    empDiv.append('<span class="hireDate">' + employee['Hire Date'] + ' ' + '</span>');
    empDiv.append('<span class="id">' + employee.ID + ' ' + '</span>');
  });
}

$("#sort").on("change", function() {
  var field = this.value;
  if (field === "ID")
    employeesArray.sort(function(a,b) {
      return a[field] - b[field];
    });
  else
    employeesArray.sort(function(a,b) {
      return a[field].localeCompare(b[field]);
    });
  displayData(employeesArray);
});
.control { padding-bottom: 4px; }
.employees { width: 300px; margin-left: 12px; }
.employee { border: 1px solid black; padding: 4px 4px 4px 4px; margin-bottom: 8px; }
.employee .name { font-size: 14pt; }
.employee .position { display: block; }
.employee .hireDate { display: block; font-size: 10pt; }
.employee .id { color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="controls">
  <div class="control">Search:
    <input type="text" name="search" id="search" />
  </div>
  <div class="control">Sort:
    <select name="sort" id="sort">
      <option value="Name">Name</option>
      <option value="Hire Date">Hire Date</option>
      <option value="Position">Position</option>
      <option value="ID">ID</option>
    </select>
  </div>
</div>
<div id="employees"></div>

Note that your option elements should have a value attribute, not name.

Sign up to request clarification or add additional context in comments.

Comments

0

Here is another answer for Live Searching and Sorting

var employeesById = {
  "8110923": {"Name": "John Glanton","Position": "Chief Executive","Hire Date": "2008-01-15"},
  "7734981": {"Name": "Samuel Chamberlain","Position": "Sales","Hire Date": "2012-05-01"},
  "3400981": {"Name": "Louis Toadvine","Position": "Customer Support","Hire Date": "2011-08-24"},
  "5517823": {"Name": "Ben Tobin","Position": "Developer","Hire Date": "2013-03-19"},
  "4587234": {"Name": "David Brown","Position": "Director of HR","Hire Date": "2012-01-10"}
};

var EmployeeArray = Object.keys(employeesById).map(function(v) {
  return $.extend({ ID: v }, employeesById[v]);
});

display(EmployeeArray);  /*Display All EmployeeArray data */

function sorting(EmpData,SearchString='',SortBy='ID'){
  switch(SortBy){

    case 'ID'   : 
      EmpData.sort(function(a,b) {
        return a.ID > b.ID;  /*Sort By ID*/
      });
    break;

    case 'Name' :
      EmpData.sort(function(a,b) {
        return a.Name.localeCompare(b.Name);  /*Sort By Name*/
      });
    break;

    case 'Position' :
      EmpData.sort(function(a,b) {
        return a.Position.localeCompare(b.Position);  /*Sort By Position*/
      });
    break;

    case 'Hire Date' :
      EmpData.sort(function(a,b) {
        return a["Hire Date"].localeCompare(b["Hire Date"]);  /*Sort By Hire Date*/
      });
    break;

    default     :
      /*Silent is golden*/
    break; 
  }

  return EmpData;
}

function searching(){
  var SearchString  = $('#search').val().toUpperCase();  /*Uppercase for Case Insentive*/
  var SortBy        = $('#sort').val();
  var Data          = sorting(EmployeeArray,SearchString,SortBy);
  var SearchData    = [];
  var index         = 0;
  var Name          = '';
  for(i=0; i<Data.length; i++){
    Name      = Data[i].Name.toUpperCase();  /*Uppercase for Case Insentive*/
    if (Name.indexOf(SearchString)>=0){  /*Search By Name*/
      SearchData[index++] = Data[i];
    }
  }
  display(SearchData);  /*Display Sorting Data*/
}

function display(Data){
  var html = '';
  for(var i=0; i<Data.length;i++){
    html+='<div class="employee">';
      html+='<p class="id">'+Data[i].ID+'</p>';
      html+='<p class="name">'+Data[i].Name+'</p>';
      html+='<p class="position">'+Data[i].Position+'</p>';
      html+='<p class="hireDate">'+Data[i]['Hire Date']+'</p>';
    html+='</div>';
  };
  $('#employees').html(html);
}

$('#search').keyup(function(){  /*Live Search, When Pressing any Keys*/
  searching();
});

$('#sort').change(function(){  /*Live Search, When Sort by*/
  searching();
});
body{
  margin: 0px;
  padding: 0px;
}
.employee {
  width: 96%;
  border: 1px solid black;
  padding: 5px;
  margin: 5px auto;
}
.employee p{
  padding: 0px;
  margin: 0px;
}
.employee .id {
  color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="controls">
  <div class="control">Search:
    <input type="text" placeholder="Search by Name" id="search" />
  </div>
  <div class="control">Sort:
    <select id="sort">
      <option value="ID">ID</option>
      <option value="Name">Name</option>
      <option value="Position">Position</option>
      <option value="Hire Date">Hire Date</option>
    </select>
  </div>
</div>
<div id="employees"></div>

Here is the function reference for indexOf() , localeCompare() , sort() , toUpperCase() , $.extend()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.