Preserve JSON arrays while sorting
You could use JavaScript for doing the sorting on click, and use PHP only for passing the JSON to it.
After you provided the HTML structure you want to display the list in, I updated this answer to use div
elements for the records and p
elements for the fields.
We could replace the select
list, for selecting the sort order, by two buttons.
Here is the PHP code:
<?php$homepage = array(); $homepage[]= '{ "info":{ "collection":[ { "Name":"Charlie", "ID":"13" }, { "Name":"Emma", "ID":"9" } ] }}'; $homepage[] = '{ "info":{ "collection":[ { "Name":"Bob", "ID":"10" } ] }}';$data = array();foreach ($homepage as $homepage2) { $tmp=json_decode($homepage2, false); $data = array_merge($data,$tmp->info->collection);}?><div id="container"></div><button id="sort1">Alphabetical</button><button id="sort2">High to Low</button><script> var collection = <?=json_encode($data)?>; function populate(compareFunc) { collection.sort(compareFunc); var container = document.getElementById('container'); container.innerHTML = ''; collection.forEach(function (key) { var div = document.createElement("div"); div.className = "inventory"; var span = document.createElement("span"); span.textContent = key.ID; div.appendChild(span); span = document.createElement("span"); span.textContent = key.Name; div.appendChild(span); container.appendChild(div); }); } var populateById = populate.bind(null, function (a, b) { return a.ID - b.ID; }); var populateByName = populate.bind(null, function (a, b) { return a.Name.localeCompare(b.Name); }); document.getElementById("sort1").addEventListener('click', populateByName); document.getElementById("sort2").addEventListener('click', populateById); document.addEventListener('DOMContentLoaded', populateById);</script>
For the sample data this will result in the following JavaScript/HTML, which you can test here:
Note that I gave the three items different ID values than in your question, since otherwise the sort order would be the same for both ID and Name.
Using tables: alternative
There are nice JavaScript libraries which give much more features to represent data sets. Here is an example using jQuery with DataTables:
var collection = [{"Name":"Charlie","ID":"13"},{"Name":"Emma","ID":"9"},{"Name":"Bob","ID":"5"}];function populate() { var tbody = $('#collection>tbody'); collection.forEach(function (key) { var row = $('<tr>'); row.append($('<td>').text(key.ID)); row.append($('<td>').text(key.Name)); tbody.append(row); });}$(document).ready(function(){ populate(); $('#collection').DataTable();});
<script src="http://code.jquery.com/jquery-1.12.3.js"></script><link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css"><script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script><table id="collection"> <thead> <tr><th>ID</th><th>Name</th></tr> </thead> <tbody/></table>
The actual code is even smaller (not counting the included library) than a pure JavaScript solution would be with a basic table. But this has sorting up and down, filtering, pagination, nice styles, ...
There are several alternatives for this answer, so I will present a simple one:
Send the data already sorted, a default one, if the user made no choices. Then, set a function that sorts the data as needed, and redraws tables/divs/whatever you are using to present them.
As an quick example:
function sortAlpha(){ for each (stuff in data){ document.getElementById("aTable").textContent=data.StringRepresentation; }}
Then a function for sortSize, sortEtc, etc... in each function, you clear a div content, and populate it again. This way, you do not need to request new content from servers
There are multiple solutions in which you can achieve the desired results.
If you want it pure PHP way what you can do is save the data in PHP Sessions and retrive them as need.
Here is the trick comes, You create function to get the result data in which you pass single parameter whether you want to get the data from external URL or from your saved data.
Now, in your application whenever you want to refresh the saved data call the same function with parameter denoting to refresh the saved data in SESSIONS to get replaced with data from external source.
Using this method you can reuse the data you've already fetched from external source without re-fetching it every-time you reload the function.
You can make another function which will return true for all cases in which application has to re-fetch the resultset from external source.
I've written pseudo code for you to understand what I'm trying to convey,
Function check whether we've to re-fetch the result from external source:
function hasToRefreshResult() { if(/* CERTAIN CONDITIONS */) { return true; } return false; }
Couple of functions to get the data from local/external source according to the parameter passed:
function getResultArray($getdatafromlocal) { if(!hasToRefreshResult() && $getdatafromlocal && array_key_exists("filertereddata",$_SESSION) && isset($_SESSION["filertereddata"])) { $data=$_SESSION["filertereddata"]; } else { $data=getDataFromExternalURL(); } if(!empty($_GET['sort']) && $_GET['sort'] == 'alphabetical') { usort($data, function ($a, $b) { return strcmp($a->Name, $b->Name); }); } else { usort($data, function ($a, $b) { return $b->ID - $a->ID; }); } return $data; } function getDataFromExternalURL() { /***** YOUR LOGIC TO GET DATA FROM EXTERNAL URL; *****/ $data = array(); foreach ($homepage as $homepage2) { $tmp=json_decode($homepage2, false); $data = array_merge($data,$tmp->info->collection); } $_SESSION["filertereddata"]=$data; return $data; }
I hope this will solve your issue strictly using PHP.
Also don't forget the write session_start();
at the top of the PHP file you will be using this functions.