0

I'm writing a PHP script which interacts with a MySQL database and a JavaScript script which uses AJAX calls to retrieve information from the PHP script.


What I'm trying to do, is to create a <select> box where my Subjects are the <optgroup label="Subject"> and the Courses are the <option value="1">Course</option> within the subjects.

What I currently have is a JS script which simply doesn't process, though there's no console error in Firebug.


I've written this SQL statement:

$sql = "SELECT
    s.Title AS Subject,
    s.Subject_ID AS Subject_ID,
    c.Title AS Course,
    c.Course_ID AS Course_ID
    FROM
    subjects s
    LEFT JOIN courses c ON s.Subject_ID = c.Subject_ID
    WHERE s.Faculty_ID = $faculty";

Which, if $faculty == 1, returns this data:

Observation Recording - List of subjects and courses

I'm then using the following code to return a multi-dimensional array where the Subject level contains that subject's Courses:

$res = mysql_query( $sql );
while ( $row = mysql_fetch_assoc( $res ) ) {
    $return[$row["Subject_ID"]][] = array( "Course_ID" => $row["Course_ID"], "Title" => $row["Course"] );
}

print_r( $return );

EDIT: I realise that print_r doesn't work for sending information to my JS script (I've got a return $return set up for that), I was just using it for debugging purposes.


The full PHP function looks like:

switch($_GET["cmd"]) {
    case "populateForm" :
        $return = json_encode( populateForm() );
        break;
    case "populateCourses" :
        $return = json_encode( populateCourses( $_GET["faculty"] ) );
        break;
}

echo $return;

-

function populateCourses( $faculty ) {
    $sql = "SELECT
        s.Title AS Subject,
        s.Subject_ID AS Subject_ID,
        c.Title AS Course,
        c.Course_ID AS Course_ID
        FROM
        subjects s
        LEFT JOIN courses c ON s.Subject_ID = c.Subject_ID
        WHERE s.Faculty_ID = $faculty";
    $res = mysql_query( $sql );
    while ( $row = mysql_fetch_assoc( $res ) ) {
        $return[$row["Subject_ID"]][] = array( "Course_ID" => $row["Course_ID"], "Title" => $row["Course"] );
    }

    return $return;
}

The data from that looks like:

Array
(
    [8] => Array
        (
            [0] => Array
                (
                    [Course_ID] => 59
                    [Title] => Core ICT
                )

            [1] => Array
                (
                    [Course_ID] => 60
                    [Title] => BTEC Business
                )

            [2] => Array
                (
                    [Course_ID] => 61
                    [Title] => BTEC ICT
                )

            [3] => Array
                (
                    [Course_ID] => 62
                    [Title] => GCSE Business
                )

            [4] => Array
                (
                    [Course_ID] => 63
                    [Title] => GCSE ICT
                )

        )

    [9] => Array
        (
            [0] => Array
                (
                    [Course_ID] => 64
                    [Title] => Advance BTEC Business
                )

            [1] => Array
                (
                    [Course_ID] => 65
                    [Title] => Advance BTEC ICT
                )

            [2] => Array
                (
                    [Course_ID] => 66
                    [Title] => AS Applied Business
                )

            [3] => Array
                (
                    [Course_ID] => 67
                    [Title] => AS Applied ICT
                )

            [4] => Array
                (
                    [Course_ID] => 68
                    [Title] => A2 Applied Business
                )

            [5] => Array
                (
                    [Course_ID] => 69
                    [Title] => A2 Applied ICT
                )

            [6] => Array
                (
                    [Course_ID] => 70
                    [Title] => A2 Economics
                )

            [7] => Array
                (
                    [Course_ID] => 71
                    [Title] => A2 Law
                )

            [8] => Array
                (
                    [Course_ID] => 72
                    [Title] => GCSE Maths
                )

            [9] => Array
                (
                    [Course_ID] => 73
                    [Title] => Maths
                )

            [10] => Array
                (
                    [Course_ID] => 74
                    [Title] => AS Further Maths
                )

            [11] => Array
                (
                    [Course_ID] => 75
                    [Title] => AS Maths
                )

            [12] => Array
                (
                    [Course_ID] => 76
                    [Title] => GSE Maths Rs-Sit
                )

            [13] => Array
                (
                    [Course_ID] => 77
                    [Title] => A2 Further Maths
                )

            [14] => Array
                (
                    [Course_ID] => 78
                    [Title] => A2 Maths
                )

        )

)

However, once I get in to my JavaScript, I have no clue how to process this data into the <SELECT> box that I'm after. PLEASE NOTE the data is being received correctly. If I console.log(data) in this function, it shows all of the data that has been sent by my PHP script, as expected.

I'm trying this:

        $('#courses').on("click", "option", function(event) {
            var id = $(this).val();
            UWA.Data.getJson(Input.URL + '?cmd=populateCourses&faculty=' + id, Input.populateCourses);
        })
    }

Input.populateCourses = function(data) {
    $('#courses').empty();
    for (var i = 0; i < data.length; i++) {
        alert(data[i]);
        $('#courses').append('<optgroup label="' + data[i] + '>');
        for (var x = 0; x < data[i].length; x++) {
            $('#courses').append('<option value="' + data[i][x].Course_ID + '">' + data[i][x].Title + '</option>');
        }
        $('#courses').append('</optgroup>');
    }
}

With #courses being <select id="courses"></select>.


I'm presuming that the way I've written these for loops in my JS script means that the data isn't being accessed/found and as such it's failing the script.

What's the best way for me to manipulate the data returned from the SQL statement to produce the <select> box I require? Or, should I improve the SQL statement to make things easier?

Thanks in advance,

turbonerd
  • 1,234
  • 4
  • 27
  • 63

4 Answers4

2

Use echo json_encode( array() ); exit; instead of print_r().

feeela
  • 29,399
  • 7
  • 59
  • 71
  • Please re-read my post, I made the changes *just* before you added your answer. The `print_r` was there purely for debugging purposes. – turbonerd Sep 18 '12 at 12:01
  • @dunc "I realise that print_r doesn't work for sending information to my JS script" states, that your purpose in using `print_r` was to sent data to JS; none of the additional information was visible in the question before I posted this answer… Also the question title "How do I create a multi-dimensional associative array in PHP" has nothing to do with your current question. – feeela Sep 18 '12 at 12:04
  • Apologies, I only noticed that I'd pasted the debugging code a couple of minutes after I'd hit "submit". – turbonerd Sep 18 '12 at 12:05
  • However, I believe my title is still entirely relevant? "How do I create a multi-dimensional associative array in PHP which JavaScript can then process?" – turbonerd Sep 18 '12 at 12:06
1

If you reseve the data correctly there is no need to show us all that php code.

Im pretty sure that the function you have to look at is:

Input.populateCourses = function(data) {
    $('#courses').empty();
    for (var i = 0; i < data.length; i++) {
        alert(data[i]);
        $('#courses').append('<optgroup label="' + data[i] + '>');
        for (var x = 0; x < data[i].length; x++) {
            $('#courses').append('<option value="' + data[i][x].Course_ID + '">' + data[i][x].Title + '</option>');
        }
        $('#courses').append('</optgroup>');
    }
}

Solution one:

Input.populateCourses = function(data) {
    var html = "";
    for (var i = 0; i < data.length; i++) {
        html += <optgroup label="' + data[i] + '>';
        for (var x = 0; x < data[i].length; x++) {
            html += '<option value="' + data[i][x].Course_ID + '">' + data[i][x].Title + '</option>';
        }
        html += '</optgroup>';
    }
    $('#courses').empty().html(html);
}

Solution two:

Input.populateCourses = function(data) {
    var $courses = $('#courses').empty();
    var $optgroup;
    for (var i = 0; i < data.length; i++) {
        $optgroup = $('<optgroup label="' + data[i] + '>').appendTo($courses);
        for (var x = 0; x < data[i].length; x++) {
            $('<option value="' + data[i][x].Course_ID + '">' + data[i][x].Title + '</option>').appendTo($optgroup);
        }
    }
}
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
1

Haven't tried it but i'm guessing the problem is that you're data is not a zero-based array, your indexes aren't 0,1,2,3, etc so your loop doesn't work. You should try something like this:

Input.populateCourses = function(data) {
    $('#courses').empty();
    for (var i in data) {
        alert(data[i]);
        /*...*/
    }
}

data is an associative array in php, which translate to an object with numeric properties in javascript for (var i in data) would iterate through the object's properties.

Ben
  • 20,737
  • 12
  • 71
  • 115
  • That's my thought exactly Ben. However, I've had issues with `for/in` loops in Internet Explorer - basically I find that they tend not to work. Any other alternatives? – turbonerd Sep 18 '12 at 13:12
  • 1
    @dunc `for..in` should work in ie, though it might not appear in the right order. The alternative would be to change your PHP so that it returns a sequential array. The best options would a sequential array like `[{subjectID,courses:[{courseID, Title}]}, {subjectID,courses:[{courseID, Title}]}, /*...*/ ]` – Ben Sep 19 '12 at 02:20
0

You want to json_encode your PHP array. JS would have no idea what to do with that string output.

Then, on the JS-side, you need to JSON.parse the text into a JS object which you can use as normal.

If you also need this to work in IE6/7 then you need to have Douglas Crockford's json2.js on the page. If you aren't supporting GhettoIE, then you don't.

Norguard
  • 26,167
  • 5
  • 41
  • 49