0

I have an ajax post that turns the JSON that looks like this

{"0":{"Project_ID":"1","Project_Name":"TEST 1"...},
 "1":{"Project_ID":"1","Project_Name":"TEST...etc.`

into an object that can be accessed by using result[0]['Whatever Key'] or result[1]['Whatever Key']. Most of the data is the same considering my query grabs information for just 1 project, but the reason I have multiple results is I have data that fits into more than one location, or cost center category, etc.

I'm unsure how to iterate through the number of results and use that number in a for loop to populate a table with all the values instead of just the ones in index [0].

The script looks like this:

echo "<script type'text/javascript'>
$('#result_year').change(function(event) {
$.post('info.php', { selected_project: $('#selection_project option:selected').val(), selected_year: document.getElementById('result_year').value},
    function(data) {
        var result = JSON.parse(data);
        //maybe an $.each loop here? or
        //for(var i=0; i<result.length; i++) <--(but NOT the length, the number of rows?)
        var location = result['Location'];
        var cccName = result['Cost_Center_Category_Name'];
        var ccName = result['Cost_Center_Name'];
        var Q_1 = result['Q_1'];
        var Q_2 = result['Q_2'];
        var Q_3 = result['Q_3'];
        var Q_4 = result['Q_4'];
        $('.editable').empty();
        document.getElementById('MQ'+location+cccName+ccName+'Q_1').innerHTML=Q_1;
        document.getElementById('MQ'+location+cccName+ccName+'Q_2').innerHTML=Q_2;
        document.getElementById('MQ'+location+cccName+ccName+'Q_3').innerHTML=Q_3;
        document.getElementById('MQ'+location+cccName+ccName+'Q_4').innerHTML=Q_4;
        } 
    );            
}); 
</script>;";

Here's my info.php as well

<?php
require ('system.php');

if (isset($_POST['selected_project']))
    $selected_project = $_POST['selected_project'];

if (isset($_POST['selected_year']))
    $selected_year = $_POST['selected_year'];


    $query = "SELECT Project_Info.Project_ID, Project_Name, Global_Project_Number, Project_Type.Project_Type_Name, Lead_Location, Local_Project_Number_1, Local_Project_Number_2, Local_Project_Number_3, Local_Project_Number_4, Local_Project_Number_5, Development_Location_2, Development_Location_3, Development_Location_4, Development_Location_5, Customer, Duration, Customer_Group, Average_Number_of_Pieces, State, Business_Center.BC_Name, Start_Of_Production, Outlets.Outlet_Name, End_Of_Development, Start_Of_Development, Project_Connection, Project_Manager, Chance_Budget, System_TPL, Chance_Forecast, Product_Family, Technology, LL_SW, Processor_Type, HL_SW, Chassis_Type, Technology_Development, Technical_Description, username, Milestones.Description AS Milestone_Description, Milestone_1, Milestone_2, Milestone_3, Milestone_4, Milestone_5, Milestone_6, Due_Date_1, Due_Date_2, Due_Date_3, Due_Date_4, Due_Date_5, Due_Date_6, Labour_Planning.*, Cost_Center_Category.Cost_Center_Category_Name, Cost_Centers.Cost_Center_Name
        FROM Project_Info 
        LEFT JOIN Project_Type ON Project_Type.Project_Type_ID = Project_Info.Project_Type 
        LEFT JOIN Business_Center ON Business_Center.BC_ID = Project_Info.BU_CC  
        LEFT JOIN Outlets ON Outlets.Outlet_ID = Project_Info.Outlet 
        LEFT JOIN Milestones ON Milestones.Project_ID = Project_Info.Project_ID 
        LEFT JOIN Labour_Planning ON Labour_Planning.Project_ID = Project_Info.Project_ID
        AND Labour_Planning.Year = $selected_year
        LEFT JOIN Cost_Center_Category ON Cost_Center_Category.Cost_Center_Category_ID = Labour_Planning.Cost_Center_Category
        LEFT JOIN Cost_Centers ON Cost_Centers.Cost_Center_Number = Labour_Planning.Cost_Center_Number          
        WHERE Project_Info.Project_ID = '$selected_project';";
    $result = $mysqli->query($query);


    while($row = $result->fetch_assoc()){
    $results[] = $row;
    }
    $results['selected_year'] = $selected_year;
    $results['selected_project'] = $selected_project;
    $response = json_encode($results);

    echo $response;

?>

Any help would be very much appreciated!

Barmar
  • 741,623
  • 53
  • 500
  • 612
Logan Voss
  • 69
  • 1
  • 9
  • [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)*** Learn about [prepared](http://en.wikipedia.org/wiki/Prepared_statement) statements for [MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! [Don't believe it?](http://stackoverflow.com/q/38297105/1011527) – Jay Blanchard Oct 27 '16 at 16:20
  • @JayBlanchard oh no! I'll do that immediately! – Logan Voss Oct 27 '16 at 16:22
  • `$.each(result, function(key, object) ...)` – Barmar Oct 27 '16 at 16:39
  • How are you getting an object in the first place? You should be getting an array. – Barmar Oct 27 '16 at 16:40
  • It should be `[{"Project_ID":"1","Project_Name":"TEST 1"...},{"Project_ID":"1","Project_Name":"TEST...etc.]` – Barmar Oct 27 '16 at 16:41
  • And since it's an array, you can use `result.length` to get the number of results. – Barmar Oct 27 '16 at 16:42
  • I'm actually not sure, I just know if I do something like `alert(data) in my script, it'll output {"0":{"Project_ID":"1","Project_Name"...}"1"{... – Logan Voss Oct 27 '16 at 16:43
  • @Barmar: it's an array while fetching the DB results, then OP stuffs a couple string keys into the array `$results['selected_year'] = `, which forces the entire thing into an object when json encoding. – Marc B Oct 27 '16 at 16:44
  • But that's my question, I want to just go through each result, not each element in the array. Like if I have 4 rows that the query returns, I want to be able to loop `for(var i=0; i<4; i++)` and then have `result[i]['whatever']` – Logan Voss Oct 27 '16 at 16:45
  • Yeah I figured that was the only to implement whichever selection box was selected at the time of the ajax call – Logan Voss Oct 27 '16 at 16:47

2 Answers2

2

You "ruined" your array by adding string keys to it after you complete the database fetch:

$results['selected_year'] =  ...

A Javascript array can have only SEQUENTIAL NUMERIC keys. As soon as there's a gap in the array indexes, or there's a non-numeric key in the array, json_encode() is FORCED to produce a JS object, because anything else would be illegal/invalid javascript/json.

If you want to stuff your results into an array and keep it an array, then don't "share" the data with string keys:

$data = array();
while (...) {
    $data[] = ... fetch from db ...
}

$results = array();
$results['selected_year'] = ...;
$results['data'] = $data;    // put results into its own child array

Then data['data'] in your JS code WILL be an array, and you can .length it.

Marc B
  • 356,200
  • 43
  • 426
  • 500
1

The problem is that you're mixing your database records into the same PHP array as the metadata for the selected year and project. Put the records into a nested array, so you can loop over them.

while($row = $result->fetch_assoc()){
    $data[] = $row;
}
$results['selected_year'] = $selected_year;
$results['selected_project'] = $selected_project;
$results['data'] = $data;
$response = json_encode($results);

echo $response;

Then in the jQuery code you can use result.data.length to get the number of records, and loop over them with $.each(result.data, function(index, row) {... });

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I've got that all in there now, will what I have in the brackets starting with `var location = result[0]['Location']; var cccName ... etc.` still work? or should I put `result[index]` or something? – Logan Voss Oct 27 '16 at 16:58
  • All the rows are moved into `result.data`, so it becomes `result.data[0].Location`. But in the `$.each` loop it's `row.Location`. – Barmar Oct 27 '16 at 17:04