Noob Question(s)

Noob Question(s)

malkneilmalkneil Posts: 2Questions: 1Answers: 0
edited October 2015 in Free community support

Hello DataTables community.

I'm fairly new to jQuery and DataTables but right now I'm simply trying to take the JSON returned from an AJAX request and put it into a table. Data coming back looks like this:

[{"sc":"00","stop_date":"2014-12-04T05:00:00Z","comments":"CROSS AUTO FUNCTION CODE 01 CREATED QSAR","part_sequence":"1","document":"763965661","cia":"0","part_qty":"2","part_number":"43W7633","part_status":"DISBURSED ","machine_serial":" ","machine_type":"1726","entity_type":"qsar","part_fc":"01"},
{"sc":"00","stop_date":"2014-12-19T05:00:00Z","comments":"CROSS AUTO FUNCTION CODE 01 CREATED QSAR","part_sequence":"1","document":"764093109","cia":"0","part_qty":"1","part_number":"39R6518","part_status":"DISBURSED ","machine_serial":" ","machine_type":"1726","entity_type":"qsar","part_fc":"01"}]

Pretty straight-forward. I simply want to create the table and have the column headers be set to the key for each row. On top of that I'm trying to set default values as some rows come back missing a key/value pair.

To accomplish this I'm attempting to go about all of this using columnDefs to define the column headers as well as the default content behavior. I'm guessing I then need to pass in the data itself using some other mechanism?

I've developed in Java for a while but a lot of this is simply not intuitive to me. I'm looking through examples on forums and I see people using a mix of "columnDefs", "aaData", "data", "aoColumns" and "columns" in their DataTable defintion. It's not clear which are prefrerred/required. For the record I'm using the latest version of DataTables (1.10.9).

Sorry for any botched terminology above; I can clarify if need be.

Thanks in advance.

Answers

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75

    I'm guessing I then need to pass in the data itself using some other mechanism?

    All you'd really have to do is use that data as the data source, via either JavaScript Sourced Data or you can do the AJAX Sourced Data

    Just make sure that the columns defined in either columns and/or columnDefs match up with the proper keys in each object within the data source.

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75

    Heres a quick example that took literally 1 minute to setup, I only used 3 of your columns in the JSON content, but hopefully you should be able to figure out the rest..

  • allanallan Posts: 62,316Questions: 1Answers: 10,226 Site admin

    If you are getting a flat array of data back (and you are using DataTables' ajax option you will also need to use ajax.dataSrc and set it to be an empty string so DataTables knows that you are giving it a flat array. See this example for a demo.

    Allan

  • malkneilmalkneil Posts: 2Questions: 1Answers: 0

    Thanks to both for responding. I'm hitting a URL that returns the JSON I pasted in the original post. Just for my clarification, if I'm doing an AJAX request first outside of the DataTable creation and saving the JSON returned to a variable, I need to use the JavaScript Sourced method on that JSON variable, correct? Alternatively, If I use the other method I need to pass the actual URL in as the "url" parameter in the AJAX Sourced DataTable creation?

    Couple other follow-ons:

    (1) I'm also wondering if there's a way to dynamically create the table column names from the JSON data returned instead of having to list them out in "columns"?

    (2) Sometimes the "comments" field in the JSON is not returned and I would like to default that to a empty string (as I'm getting an array index warning when it's missing).

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75

    Just for my clarification, if I'm doing an AJAX request first outside of the DataTable creation and saving the JSON returned to a variable, I need to use the JavaScript Sourced method on that JSON variable, correct?

    Yes, why not just use the variable as the ajax param? It makes things way easier

    Alternatively, If I use the other method I need to pass the actual URL in as the "url" parameter in the AJAX Sourced DataTable creation?

    Yes, this is what i recommend

    I'm also wondering if there's a way to dynamically create the table column names from the JSON data returned instead of having to list them out in "columns"?

    Yes, thats what i did, just create a variable, construct it, and pass it to columns.

    Sometimes the "comments" field in the JSON is not returned and I would like to default that to a empty string (as I'm getting an array index warning when it's missing).

    This one might be tricky then. Need to either always return something, or parse the json before you hand it to DT and add the comments key if it isnt there

  • allanallan Posts: 62,316Questions: 1Answers: 10,226 Site admin

    Sometimes the "comments" field in the JSON is not returned and I would like to default that to a empty string

    Use the columns.defaultContent option to tell DataTables what to do in that situation.

    Allan

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75
    edited October 2015

    Oh, yep, @allan knows best, my bad. lol.

    I'm also wondering if there's a way to dynamically create the table column names from the JSON data returned instead of having to list them out in "columns"?

    I was thinking that maybe the columns could accept a closure to do this, but according to the reference it doesnt look like it. So just construct the array outside of the table.

    What I did, was create the table dynamically via PHP, then just add a bunch of data-* to it, and use jQuery to parse those tags, somewhat like this.

    Also, keep in mind that you can specify a URL with ajax that contains more than just the data you wish to keep in a table, for example, my JSON array returns a ton of data, something like this:

    {
      partition: {
        name: "Some Partition",
        status: "Some Status"
      },
      assets: [
        {
          id: "A",
          name: "Name A"
        },
        {
          id: "B",
          name: "Name B"
        },
      ]
    }
    

    Then I just specify assets via the dataSrc setting, then I can grab the other information that was retrieved via DataTables using ajax.json(), and use that when formatting the rows, or for various other functions

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75
    edited October 2015

    The reason I like ajax over just processing something via $.ajax() then handing it to data, is you can use the ajax namespace, which has a bunch of cool features.

    I wrote some JS that would reload the table via ajax.reload() once it senses some changes were made to the data source (by either more/less records, or if any rows were updated, by looking at the updated values)

    This might be a little over your head (since you said you were a noob), but you might make some use out of it.

    var xhr_start, xhr_stop, last_reload, update_interval;
    
    var $assets_dt = $('#data-table')
        // Set the start timer for the initial XHR request to calculate the update interval
        .one('preXhr.dt', function ( e, settings, data ) {
            // Set first ajax start time
            xhr_start = Date.now();
        } )
        // Whenever DT sends an AJAX request
        .on( 'xhr.dt', function ( e, settings, json, xhr )  {
            // If this was the first xhr request, check how long it took, and set the update
            // interval to that length + 1 second
            if(typeof xhr_stop === 'undefined') {
                xhr_stop = Date.now();
    
                // If the reload is less than 4 seconds, just set 4 seconds (If it ends up being something like
                // 1.5 seconds, we dont want the table reloading every 1.5 seconds..
                var min_interval = 4000;
    
                // Set the interval to a minimum of 4 seconds, if the xhr
                // took longer, then set it to the xhr time + 1 second
                update_interval = xhr_stop - xhr_start < min_interval
                    ? min_interval
                    : xhr_stop - xhr_start + 1000;
            }
    
            // Update the last_reload timestamp, used primarily by monitor_updates()
            last_reload = Math.floor(Date.now() / 1000);
        } )
        .DataTables({
            ajax: 'http://some_url/stuff.json',
            dataSrc: 'assets'
        });
    
    var ajax = false;
    var i = 0;
    
    // Check for updates ever N seconds
    var updates_loop = setInterval(function(){
        i++;
        // If theres no ajax request running, and not paused, then check
        if( ! ajax && ! pause) {
            ajax = true;
            $.ajax( {
                type: "GET",
                dataType: 'json',
                url: $assets_dt.ajax.url(),
                success: function ( response ) {
                    // Get the proper data source
                    var new_json = ($assets_dt.init().ajax.dataSrc
                        ? response[ $assets_dt.init().ajax.dataSrc ]
                        : response);
    
                    // Get the data stored by DataTables to compare
                    var dt_json = ($assets_dt.init().ajax.dataSrc
                        ? $assets_dt.ajax.json()[ $assets_dt.init().ajax.dataSrc ]
                        : $assets_dt.ajax.json());
    
                    // Should reload the table if anything was changed
                    (JSON.stringify(new_json) === JSON.stringify(dt_json)) || $assets_dt.ajax.reload( null, false );
                    
                    /*
                    // Check for updated timestamps (created/modified), or length change (deleted rows)
                    _.find( new_json, function ( asset ) {
                        return ( last_reload  && ( asset.created > last_reload || asset.modified > last_reload ) );
                    } ) || new_json.length !== dt_json.length && $assets_dt.ajax.reload( null, false );
                    */
                },
                error: function ( xhr, ajaxOptions, thrownError ) {
                    clearInterval(updates_loop);
                    throw new Error( 'Error: ' + thrownError );
                }
            } ).done( function () {
                ajax = false;
            } );
        }
    }, update_interval);
    

    EDIT: commented out the part that uses _.find (LowDash JS function) and added something that would just compare the entire arays:

    (JSON.stringify(new_json) === JSON.stringify(dt_json)) || $assets_dt.ajax.reload( null, false );
    
This discussion has been closed.