Null check for mData javascript dot notation

Null check for mData javascript dot notation

ddewaeleddewaele Posts: 9Questions: 0Answers: 0
edited April 2014 in DataTables 1.9
Imagine I have a cell that needs to display this :

[code]
"aoColumns": [
{ "mData": "metrics.speed" }
]
[/code]

In my JSON array however some elements have a metrics element while others don't.
Currently, I get either an alert or a JS error when this occurs.

Is there a way to do a null check here ? So when there are no metrics, don't display anything.
If there are metrics, display the speed.

Replies

  • tangerinetangerine Posts: 3,342Questions: 35Answers: 394
    Write a function for mRender:
    http://datatables.net/release-datatables/examples/advanced_init/column_render.html
  • ddewaeleddewaele Posts: 9Questions: 0Answers: 0
    I've got something like this :

    [code]
    { "mData": "metrics.speed","mRender": function(data, type, full) { return (data) ? data + " km" : ""} }
    [/code]

    So there is a null check in the mRender.

    But the error still occurs.

    Uncaught Error: DataTables warning (table id = 'interactions-table'): Requested unknown parameter 'metrics.speed' from the data source for row 0

    I'll try to debug it some more, but I guess it already throws the error during the mData processing.
  • ddewaeleddewaele Posts: 9Questions: 0Answers: 0
    By providing a sDefaultContent value the problem goes away.


    [code]
    { "mData": "metrics.speed","mRender": function(data, type, full) { return data + " km"} , "sDefaultContent":""},
    [/code]
  • allanallan Posts: 61,431Questions: 1Answers: 10,048 Site admin
    edited April 2014
    Yes - sDefaultContent is the answer here. If the data is null or undefined, you need to tell DataTables how to display that (this ain't no Oracle database and `'' !== null` ;-) ). The sDefaultContent option is the way of specifying that - it can be a blank string, HTML content or whatever you want (as long as it is a string).

    Also, you don't need to use mRender as a function for sDefaultContent to operate - just using your original code + sDefaultContent will work just fine:

    [code]
    "aoColumns": [
    { "mData": "metrics.speed", "sDefaultContent": "" }
    ]
    [/code]

    Allan
  • ddewaeleddewaele Posts: 9Questions: 0Answers: 0
    I am appending " km" to the output so the mRender needs to stay I guess.

    If it's a siple pass-through value without manipulation then the mData / sDefaultContent is all you need. I did verify that and it works great.

    Regarding the rendering, is mRender the only place where we can "manipulate" how cell data should be rendered ?

    If cells contain lots of markup it gets kinda messy to do it in pure javascript. Is some templating solution an option ? Or embedded the markup inside the html table directly ?

    In my previous implementation (without the ajax datasource) I simply embedded all html markup inside the tbody of the table. Is such a thing still possible ?

    See this question for more info on this:
    http://datatables.net/forums/discussion/20521/server-side-sorting-and-embedded-content#Item_1
  • allanallan Posts: 61,431Questions: 1Answers: 10,048 Site admin
    > Regarding the rendering, is mRender the only place where we can "manipulate" how cell data should be rendered ?

    No - mData can also be used, although generally mRender is easier to operate since you don't need to deal with the `set` case. You can also use fnCreatedCell , fnCreatedRow or fnRowCallback . However, mData / mRender are the two which DataTables uses to get the data to use - if you alter the data in the HTML dynamically, DataTables won't be able to see it.

    > If cells contain lots of markup it gets kinda messy to do it in pure javascript. Is some templating solution an option ? Or embedded the markup inside the html table directly ?

    You could just call an external tempting function I guess? No reason it needs to be an anonymous function. There isn't a tempting option available at the moment, but I've been toying with some ideas for it.

    > In my previous implementation (without the ajax datasource) I simply embedded all html markup inside the tbody of the table. Is such a thing still possible ?

    Sure - DataTables, when using DOM sourced data, will just read the data from the DOM. Put whatever HTML you want in it :-)

    Allan
  • ddewaeleddewaele Posts: 9Questions: 0Answers: 0
    The way I understand is now is that DOM sourced data and server-side pagination don't go together but perhaps I'm mistaking.

    With server-side sorting you provide an AJAX based data-source meaning you can't just embed your templating into the html table. Or can the 2 be combined ?
  • allanallan Posts: 61,431Questions: 1Answers: 10,048 Site admin
    > DOM sourced data and server-side pagination don't go together

    I don't really understand how the data can be DOM sourced, but the pagination be at the server-side? If the data is being paged at the server, then surely the data as to come from there?

    > With server-side sorting you provide an AJAX based data-source meaning you can't just embed your templating into the html table.

    If you mean tempting in the sense of having (for example) a PHP function that outputs a `TR` row, then no. You would need to use Javascript to render the data.

    Allan
  • ddewaeleddewaele Posts: 9Questions: 0Answers: 0
    With templating I'm referring to some client side template mechanism like this.

    I typically define a table in html in an external template (JST) and then expect "something" to provide me the collection. (In this case that "something" is a backbone view that provides the collection supportedPids).

    [code]



    PID (Hex)
    Description
    Supported



    <% _.each(supportedPids, function(pid) { %>

    <%= pid.pid %>
    <%= pid.descr %>
    checked <% } %> disabled />

    <% }); %>


    [/code]

    When I introduced the server-side sorting/paging like below I retrieve the same model (a collection of pid elements) and rendered the table data via the "aoColumns/mData" mechanism.

    Would there be a way to pull in the template above and simply apply the data returned from the server on that template ?

    I hope I am making more sense now. I feel that the model and the view are too tightly coupled to my taste using the code below. (this is a simple example, but sometimes the cell data is a lot more complex). I could probably externalize each cell in its own template but that would be too fine-grained.


    [code]
    var table = $('#vehicle-table').dataTable( {
    "bSort": false,
    "bFilter": false,
    "bServerSide": true,
    "bLengthChange":false,
    "aoColumns": [
    { "mData": "pid","mRender": function(data, type, full) { return data} },
    { "mData": "descr","mRender":function(data, type, full) { return data} },
    { "mData": "supported","mRender": function(data, type, full) { return ""},
    ],

    "sAjaxSource":"/vehicles/pids/" + vehicle.id,

    "fnServerData": function ( sSource, aoData, fnCallback, oSettings ) {
    oSettings.jqXHR = $.ajax( {
    "dataType": 'json',
    "type": "GET",
    "beforeSend" : function(xhr) {
    xhr.setRequestHeader('Authorization',authUtils.make_base_auth(username, password));
    },
    "url": sSource,
    "data": aoData,
    "success": fnCallback
    }).done(function(data) {
    // $('.img-tooltip').tooltip();
    });
    },
    "aaSorting": [[ 0, "desc" ]]

    });
    [/code]
  • allanallan Posts: 61,431Questions: 1Answers: 10,048 Site admin
    I see - thanks for the explanation. Ultimately yes, I would like to do something like that in DataTables, but currently there isn't any code in DataTables to do that.

    Allan
  • ddewaeleddewaele Posts: 9Questions: 0Answers: 0
    No worries ... DataTables remains a great library and thanks a lot from a very happy user !
This discussion has been closed.