javascriptjqueryasp-classicadodbjqxgrid

Cannot bind json data to jqxgrid data adapter


I need the help of an expert on this site. I am attempting to bind some JSON data that is return from an AJAX call to my asp page through the method below. The server successfully returns the following data:

{"Records": [ {"LastName":"Harold","FirstName":"Kelly","Floor":"","Office":""}, {"LastName":"Kelly","FirstName":"Jason","Floor":"12","Office":"D01"} ]}

It appears however, that the data does not get binded to the grid and hence the JQXGrid is empty

I don't understand what I am doing wrong. Theoretically everything should working. Maybe I am missing something here.

compile_data.asp:

<%
'Function to convert an ADO recordset into a JSON object
'
'Written by Tracy Dryden, Commonwealth Technology Group, Inc.
'
'Released to the public domain.

function RStoJSON(rs)
    dim sFld
    dim sFlds
    dim sRec
    dim sRecs
    dim sRecordSet
    dim lRecCnt

    sRecordSet = ""
    sRecs = ""
    lRecCnt = 0
    if rs.EOF or rs.BOF then
        RStoJSON = "null"
    else
        do while not rs.EOF and not rs.BOF
            lRecCnt = lRecCnt + 1
            sFlds = ""
            for each fld in rs.Fields
                sFld = """" & fld.Name & """:""" & toUnicode(fld.Value&"") & """"
                sFlds = sFlds & iif(sFlds <> "", ",", "") & sFld
            next 'fld
            sRec = "{" & sFlds & "}"
            sRecs = sRecs & iif(sRecs <> "", "," & vbCrLf, "") & sRec
            rs.MoveNext
        loop
        sRecordSet = "{""Records"": [" & vbCrLf & sRecs & vbCrLf & "]}"
        RStoJSON = sRecordSet
    end if
end function

function toUnicode(str)
    dim x
    dim uStr
    dim uChr
    dim uChrCode
    uStr = ""
    for x = 1 to len(str)
        uChr = mid(str,x,1)
        uChrCode = asc(uChr)
        if uChrCode = 8 then ' backspace
            uChr = "\b" 
        elseif uChrCode = 9 then ' tab
            uChr = "\t" 
        elseif uChrCode = 10 then ' line feed
            uChr = "\n" 
        elseif uChrCode = 12 then ' formfeed
            uChr = "\f" 
        elseif uChrCode = 13 then ' carriage return
            uChr = "\r" 
        elseif uChrCode = 34 then ' quote 
            uChr = "\""" 
        elseif uChrCode = 39 then ' apostrophe
            uChr = "\'" 
        elseif uChrCode = 92 then ' backslash
            uChr = "\\" 
        elseif uChrCode < 32 or uChrCode > 127 then ' non-ascii characters
            uChr = "\u" & right("0000" & CStr(uChrCode),4)
        end if
        uStr = uStr & uChr
    next
    toUnicode = uStr
end function

function iif(cond,tv,fv)
    if cond then
        iif = tv
    else
        iif = fv
    end if
end function
%>



<%

Dim cn
Dim rs
Dim sSQL

    set cn = Server.CreateObject("ADODB.Connection")

    cn.Open "Provider=sqloledb;Data Source=sql8002.site4now.net;Initial Catalog=db_a8d1d3_accmgr; User Id=db_a8d1d3_accmgr_admin;Password=accmgr01;"

    sSQL = "SELECT * FROM tbl_offices"

    set rs = cn.Execute(sSQL)

    response.write(RStoJSON(rs))

    'response.write(Request.QueryString("first"))

    response.flush

    rs.Close
    set rs = nothing

    cn.close
    set cn = nothing

%>

Code in question:

<script type="text/javascript">
var data = ""

        $(document).ready(function () {

    $.ajax({
        type: 'GET',
        url: "compile_data.asp",
        success:function(response){

            data = response
            alert(data)
            
                }
        });


    var source = {
                datatype: "json",
                datafields: [
            { name: 'LastName', type: 'string' },
            { name: 'FirstName', type: 'string' },
            { name: 'Floor', type: 'string' },
            { name: 'Office', type: 'string' }
        ],
        localdata: data
        };
            
    var dataAdapter = new $.jqx.dataAdapter(source);


    $("#grid").jqxGrid({
                width: getWidth('Grid'),
                source: dataAdapter,
                columnsresize: true,
                columns: [
                    { text: 'LastName', datafield: 'LastName', width: 250 },
                    { text: 'FirstName', datafield: 'FirstName', width: 150 },
                    { text: 'Floor', datafield: 'Floor', width: 180 },
                    { text: 'Office', datafield: 'Office', width: 120 }
                ]
            });
        });


</script>

HTML:

<div id='jqxWidget'>
    <div id="grid"></div>
</div>

Solution

  • The issue here is how the $.ajax() method is being used. AJAX is designed to be asynchronous which means that it executes but delegates handling of the response to a delegate function.

    In the current code, both the dataAdapter and the jqxGrid() will execute directly after AJAX which may still be awaiting a response.

    There are two ways to approach this

    1. Relocate the setup of the dataAdapter in the success: delegate of the $.ajax() method, this guarantees the data variable is not bound to the dataAdapter before a response is received.

    2. In the $.ajax() options pass async: false which will make the AJAX call behave synchronously blocking until it receives a response. Be cautious however as this approach will lead to a poor user experience.

    Personally, I prefer option 1 with a few adjustments to your code we can load the jqxGrid without hindering the user by blocking#.

    var data = ""
    
    $(document).ready(function () {  
      $.ajax({
        type: 'GET',
        url: "compile_data.asp",
        success:function(response){
            data = response
            alert(data)
            // Grid will reload with returned data.
            loadJqxGrid();
        }
      });
      
      // Initial Grid load will be empty.
      loadJqxGrid();
    });
    
    function loadJqxGrid() {
      var source = {
        datatype: "json",
        datafields: [
            { name: 'LastName', type: 'string' },
            { name: 'FirstName', type: 'string' },
            { name: 'Floor', type: 'string' },
            { name: 'Office', type: 'string' }
        ],
        localdata: data
      };
              
      var dataAdapter = new $.jqx.dataAdapter(source);
      
      $("#grid").jqxGrid({
        width: getWidth('Grid'),
        source: dataAdapter,
        columnsresize: true,
        columns: [
            { text: 'LastName', datafield: 'LastName', width: 250 },
            { text: 'FirstName', datafield: 'FirstName', width: 150 },
            { text: 'Floor', datafield: 'Floor', width: 180 },
            { text: 'Office', datafield: 'Office', width: 120 }
        ]
      });
    }
    

    # Provided untested