0

Here is my JSON string.... which I can't modify because it comes from a database query from ColdFusion:

    {
    "Modules": {
        "COLUMNS": [
            "MODULECODE",
            "MODULETITLE"
        ],
        "DATA": [
            [
                "A001",
                "The Middle Ages"
            ],
            [
                "M001",
                "Civil Liberties"
            ],
            [
                "H001",
                "Project Preparation"
            ]
        ]
    },
    "Courses": {
        "COLUMNS": [
            "COURSETITLE",
            "COURSECODE"
        ],
        "DATA": [
            [
                "Marketing",
                "00007001"
            ],
            [
                "Fashion and Textile Buying Management",
                "00006002"
            ]
        ]
    }
}

Here is my JQuery code to try to extract out the data in order to populate SELECT form element:

$(document).ready(function() {
    $('#UserCode').blur(function() {
        $.ajax({
            type: 'get',
            url: 'mydata.cfc',
            data: {method:'getData', UserCode:$(this).val()},
            dataType: 'json',
            success: function(result){
                $.each(result, function(index, valueA){
                    $.each(valueA, function(index, valueB){
                        // Trying to append to the #Courses <select> element
                        $('#Courses').append('<option value="'+valueB[1]+'">'+valueB[2]+' ('+valueB[1]+')</option>');
                    });
                });                                 
            }
        });
    });
});

Basically I don't have a clue how to get the "Courses" data into the #Courses select element for now. Later I will also need to create a #Modules select element and do the same thing with the "Modules" data.

There are arrays within arrays and I don't understand how to ask JQuery to just select "valueB.Courses" for example. I have got about 5 Jquery books but their example JSON strings do not have arrays of arrays like mine so I can't figure what to do :(

5
  • 4
    I guess the question is "how to loop a JavaScript array". Actual JSON parsing is done automatically by jQuery and it doesn't depend on the JSON structure. Commented Nov 19, 2013 at 11:57
  • valueB.Courses.DATA[1][0] == "Fashion and Textile Buying Management" Commented Nov 19, 2013 at 11:57
  • 2
    You do not need to return the entire query as JSON. You can loop over each query and create a structure of data for each row and append it to an array. This will make it easier to access the data on the client side as you can reference the 'column names' rather than array positions. Commented Nov 19, 2013 at 13:51
  • @ScottStroz could you provide an example as an answer? It would really help me out. Just to give me an idea what I'm supposed to do. At the moment the database query is being returned from a function with returntype="struct" and format="JSON" Commented Nov 19, 2013 at 16:03
  • 1
    I would suggest that you format your data in your own way. Don't rely on how CF builds the json struct for you. What if CF changes how the json struct from a query is built? Future proofing is always a good idea. Commented Nov 19, 2013 at 16:57

3 Answers 3

2

I have found it is easier to deal with simpler data structures than the JSON that results from simply returning a query serialized as JSON.

Here is some pseudo code to get you pointed in the right direction - in cfscript format:

<cffunction name="GetStuff" >
    <cfset var ret = {} />
    <!--- code for queries here --->
    <cfset var qry1Data = [] />
    <cfloop query="query1">
        <cfset var item = {"modulecode" = query1.modulecode, "moduletitle" = query1.moduleTitle} />
        <cfset arrayAppend( qry1Data, item ) />
    </cfloop>
    <cfset ret["modules"] = qry1Data/>
    <cfset var qry2Data = [] />
    <cfloop query="query2">
    <cfset var item = {"coursecode" = query1.coursecode, "coursetitle" = query1.courseTitle} />
        <cfset arrayAppend( qry2Data, item ) />
    </cfloop>
    <cfset ret["courses"] = qry2Data />
    <cfreturn ret />
</cffunction>

You need not specify returnformat as you can do that with your AJAX call by passing it as aprt of the 'data'. Here is what your callback might look like

$(document).ready(function() {
$('#UserCode').blur(function() {
    $.ajax({
        type: 'get',
        url: 'mydata.cfc',
        data: {method:'getData', UserCode:$(this).val(), returnFormat : 'JSON'},
        dataType: 'json',
        success: function(result){
            $.each(result.modules, function( index, val ) ){
                $("#Modules").append('<option value="' + val.modulecode + '">' + val.moduletitle + ' (' + val.modulecode + ')</option>');
                $("#Courses").append('<option value="' + val.coursecode + '">' + val.coursetitle + ' (' + val.coursecode + ')</option>');
            }                                
        }
    });
});

});

You may need to tweak the jQuery to populate the select boxes a little, but that should give you the idea.

I might consider splitting out the calls to get modules and courses into different AJAX calls and handling each individually, but that is more of a personal preference than anything else.

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

3 Comments

Thanks Scott! I completely understand why you have done this and I have given it a go which has worked well.... but... how is one supposed to do this when a query could contain up to 50 columns?
You can loop over the column list to create the structure dynamically.
Brilliant thanks so much. I would have voted it the answer but given the original question I had to vote the other one. But as an overall solution yours is really fantastic.
1

As you identified that its an arrays within arrays hence you can iterate them like this:

...
success: function(result){
    for(var i=0;i<result.Courses.Data.length;i++)
        $('#Courses').append('<option value="'+result.Courses.Data[i][1]+'">'+result.Courses.Data[i][2]+'('+result.Courses.Data[i][1]+')</option>');

    for(var i=0;i<result.Modules.Data.length;i++)
        $('#Modules').append('<option value="'+result.Modules.Data[i][1]+'">'+result.Modules.Data[i][2]+'('+result.Modules.Data[i][1]+')</option>');
});

Comments

0

Though this post is old just wanted to correct syntax error in the solution suggested by Scott . $each syntax should be like

$.each(result.modules, function( index, val ){

});

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.