1

I am getting a bunch of data from the db and want to display all the data in a table, but the data doesn't come sorted. Is there a way I can sort or map the object of arrays so I know what content goes with what so it shows the correct data in each row?

Here is my ajax call to get the data:

        //get the content, display all pages or specified page num
        $.ajax({
            type: 'POST', 
            url: 'qry/getRawText.php',
            async: true,
            data: {FileId: fileId, PageNum: pageNum},
            success: function(response) {
                getRawTextResponse = JSON.parse(response);
                drawTextCodeContent();
           }
        });

Here is where I draw the table with the data:

 function drawTextCodeContent() {
      fileText = "<table id='fileTextTableId'><tbody>";

        //loop through text files
        for(i=0;i<getRawTextResponse.length;i++) {
            //remove null from text
            if(getRawTextResponse["RowData"][i] == null) {
                getRawTextResponse["RowData"][i] == "";
            }
            //draw row
            fileText += "<tr class='rowToEdit " + getRawTextResponse["RowStatus"][i] + "'><td class='hidden'>"+ getRawTextResponse["PageNum"][i] +"</td><td class='rowNumTd'>"+ getRawTextResponse["RowNum"][i] +"</td><td class='rowContentTd'><pre>"+ getRawTextResponse["RowData"][i] +"</pre></td><td class='rowCheckboxTd'><label class='mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect mdl-data-table__select' for='row[" + getRawTextResponse["RowNum"][i] + "]'><input type='checkbox' id='row[" + getRawTextResponse["RowNum"][i] + "]' class='mdl-checkbox__input' /></label></td></tr>";                  
        }
        fileText += "</tbody></table>";
        //display table in div
        $("#textCodeDiv").html(fileText);
 }

Here is a preview of what the data actually looks like:

Object {
     PageNum: Array(66), 
     RowNum: Array(66), 
     RowStatus: Array(66),
     RowData: Array(66), 
     length: 66
 }

PageNum and RowNum are arrays of numbers not in order. Row status and RowData are arrays of strings not in order.

Here is the whole PHP file for getting the data from the db:

$fileId = $_POST["FileId"];
$pageNum = $_POST["PageNum"];

// Populate the query string
$tsql = "Exec TxRrcT1.GetRawText @FileId = ?, @PageNum = ?";

// Attempt to connect to SQL Server
if ( strtoupper(substr(PHP_OS, 0, 3)) == "WIN" ){
    $conn = odbc_connect($connection_string, $user, $pass, SQL_CUR_USE_ODBC);
   if ($conn === false ){ die(); }
 }
else {
    $conn = odbc_connect($connection_string, $user, $pass);
    if ($conn === false ){ die(); } 
}

// Prepare the stored procedure
$sp = odbc_prepare($conn, $tsql);

$params = array(
   $fileId, //@FileId
   $pageNum //@PageNum
);

// Execute procedure
$qryResults = TransformToObjectWithArrays($sp, $params);

// Close the connection
if ($conn !== false){ odbc_close($conn); }

// Return the query results
if (isset($qryResults)){ echo json_encode($qryResults); }

Here's my initial PHP function to take the data and transform it to an object of arrays.. how could I change this to just return the data in array of arrays?

// This function will prepare a tsql procedure and return the ODBC result
// identifier that can be used once the procedure is executed
function GetQryReturn($sp, $params){
    $qryReturn = odbc_execute($sp, CleanInputs($params));
    if ($qryReturn === false){ die(); }
    return $sp;
}

function CleanInputs($InputArray){
    return array_map(function($value){return $value === "" ? NULL : $value;}, $InputArray);
}

// This function takes a prepared stored procedure and any parameters and
// returns the query results as an objects with arrays
// example:
// {key1: [va1,val2], key2: [val1,val2]}
function TransformToObjectWithArrays($sp, $params){
    // Execute query
    $qryReturn = GetQryReturn($sp, $params);

    // Populate array with results
    $qryResults = array();
    if( odbc_num_rows($qryReturn) ){
        for($i=1; $i<=odbc_num_fields($qryReturn); $i++){
        $qryResults[odbc_field_name($qryReturn, $i)] = array();
    }
    $qryResults["length"] = 0;
    while( $row = odbc_fetch_array($qryReturn) ){
        foreach($row as $key => $value){
            array_push($qryResults[$key], $value);
        }
        $qryResults["length"] += 1;
    }
   }
   else{
        $qryResults["length"] = 0;
   }

   return $qryResults;
}
7
  • What if you sort data when you query it from db? Like using params to select the way it must sort it. I consider that if it's a bunch of data and there's no pagination, sorting in js can give to your app a bad performance before rendering. Commented Apr 27, 2017 at 21:54
  • What are you passing to TransformToObjectWithArrays? I.e. your $sp, and $params? Commented Apr 27, 2017 at 22:13
  • @MajidFouladpour I updated the question Commented Apr 27, 2017 at 22:22
  • So... Ignoring the fact that you could have just asked SQL to sort your data, let me make sure I got it straight: You get a response from odbc_fetch_array that is an array of rows, each row being an associative array of columns, a structure perfect for sorting; then you transpose it into an associative array of columns, each column being an array of values; then you send it to clientside? Why not just json_encode the result of odbc_fetch_array as it is and send that? It is much easier to display as a table, easier to sort, easier to... everything. Commented Apr 28, 2017 at 1:25
  • I'm not the db guy and I was told to sort it clientside. If I'm understanding you, I believe I'm already json_encoding the $qryResults.. it's on the first php example I gave Commented Apr 28, 2017 at 4:05

4 Answers 4

2

I would transform the object of four arrays into an array of objects, each having the four fields corresponding to the different arrays. That is:

[
    {
        PageNum: 0,
        RowNum: 0,
        RowStatus: 'status',
        RowData: 'data'
    }
]

You can then easily sort the whole array

Edited:

To sort the array, you have the sort method:

var arr = [...]
arr.sort(function(a, b) {
    // a and b are two element of your array (e.g. arr[i] and arr[j])
    if(a.RowNum === b.RowNum) return 0;
    if(a.RowNum < b.RowNum) return -1;
    if(a.RowNum > b.RowNum) return 1;
})
Sign up to request clarification or add additional context in comments.

4 Comments

How do I go about changing the object into an array?
@Teton-Coder to change the object into an array of objects try data.PageNum.map((x,i) => ({ pagerow:x, rownum: data.RowNum[i], rowdata: data.RowData[i] })) , hope you get the idea
@maioman Okay I was able to get it into an array of arrays, but I'm having difficultly trying to sort by rownum now... would it be something like, data.RowNum.sort();
@lostInTheTetons I included the sorting code in my updated response
0

Generally, I recommend doing sorting server side. Otherwise, you could always use DataTables. It supports client-side sorting. It can be clumsy to use at times, but it's been a real time-saver for me.

10 Comments

Should I use PHP to sort the object of arrays then? I'm still a newb with PHP so I'm not sure how to do it
@Teton-Coder if you're SELECTing the data by a database query, your best option would be using ORDER BY or equivalent to get the data sorted right from the mouth of the database.
I use a stored procedure in PHP to call the data. Where would I use the Order By function? Would this be before the stored procedure, within it, or after it's called?
Teton, Firstly, I would change the format of the data you are returning. You should return an array of objects, not an object of arrays. Secondly, I don't understand why you are including PageNum and RowNum. A proper implementation should not need these. And yes, sorting server-side (in php) would be the most straightforward. In fact, typically PHP would only return one page of data at a time, so sorting there would be necessary. (or yes, sort in your query as Majid suggests--this is best if it's available to you)
I'm using the rowNum and pageNum because the user is editing error data that has been scrapped from a website. So some doesn't come in clean so we record the page and rowNums so the user knows where the error is.
|
0

you can use

arr.sort(compareFunction);

where compare function is something like following:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

for more information on sort check here https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort?v=control

For mapping use something like this

var numbers = [1, 5, 10, 15];
var roots = numbers.map(function(x) {
   return x * 2;
});
Here is the link to complete mapping options.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map?v=example

1 Comment

How can I sort the whole object of arrays at once though? That way all the data is in the correct spot or at least mapped in the correct spots together. That way the table rows will display the correct data
0

If anyone is wondering or for future reference, this is what I came up with. I include it in my ajax success function.

getRawTextResponse = JSON.parse(response);                  
//getNewRawText and map data
gNRT = getRawTextResponse.PageNum.map((x,i) => ({
        index: i,
        PageNum: x, 
        RowNum: getRawTextResponse.RowNum[i], 
        RowData: getRawTextResponse.RowData[i],
        RowStatus: getRawTextResponse.RowStatus[i]
}));
//sort newly mapped array   
gNRT.sort(function(a,b) {return a.RowNum - b.RowNum});

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.