Best way to update cell in row based on data in another cell?

Best way to update cell in row based on data in another cell?

loukinglouking Posts: 259Questions: 52Answers: 0

I'm trying to loop through the rows, updating all the data in cells in a certain column based on the data in the associated cell in another column. Not sure the best way to do that, and am having trouble figuring out how to do it at all. After a couple of hours of struggling with this feel it's time to ask the forum :)

I'm sure there's a better way to do this. I tried starting at the cell level but didn't see how to select the parent to get to the a column data. Probably best done using raw jQuery, but I'm struggling

See http://codepen.io/louking/pen/adaXLY for my non-working example

table = $('#tbl').DataTable({
  columns: [{ name: 'a' }, 
            { name: 'b' }, 
            { name: 'c' }]
})

var andx = table.column('a:name').index();
var bndx = table.column('b:name').index();

table.rows().every ( function () {
  var adata = this.cells( andx ).data();
  this.cells( bndx ).data('xx' + adata);
} );
<table id=tbl>
  <thead>
    <tr>
      <th>col0</th>
      <th>col1</th>
      <th>col2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a0</td>
      <td>b0</td>
      <td>c0</td>
    </tr>
     <tr>
      <td>a1</td>
      <td>b1</td>
      <td>c1</td>
    </tr>
  </tbody>
</table>

This question has accepted answers - jump to:

Answers

  • glendersonglenderson Posts: 231Questions: 11Answers: 29

    You want to use the rowCallback feature. Just remember that columns are zero [0] based.

    https://datatables.net/reference/option/rowCallback.

  • loukinglouking Posts: 259Questions: 52Answers: 0
    edited February 2016

    corrected url from previous comment https://datatables.net/reference/option/rowCallback

    I think andx and bndx in my example are zero based.

    I see some good information on how to use jQuery within that reference that I will try out, but what is advantage of using rowCallback rather than looping through the rows using the dataTables api?

    I will also have to make this same update when using Editor to create a row -- should I assume the rowCallback function would be invoked at row create time as well?

  • glendersonglenderson Posts: 231Questions: 11Answers: 29
    Answer ✓

    I'm not saying that your method wont' work. There are many ways to do the same thing and if your method works, continue doing it that way. rowCallback is preferred by me because I have many tables, a single API Class that I wrote to handle all my tables so I have only one method of instantiation, and mostly because some of my tables are serverside, some are native. I update tables sometimes upon an edit of the user, and sometimes because the content has changed and triggered a row refresh. rowCallback is defined once, and each time the row is modified it's called automatically.

    In my API instantiation class, I determine if I want a rowCallback on a column by column basis. When I add a column object to the table object, I specify if the column has a rowcallback and let my API determine it's ordinal, I just add the conditional to the column and the API determines the final rowCallback at the table level.

  • allanallan Posts: 63,695Questions: 1Answers: 10,500 Site admin
    Answer ✓

    If I've understood correctly, then I would suggest using columns.render. Updated example.

    See also the renderer's manual page.

    Allan

  • loukinglouking Posts: 259Questions: 52Answers: 0
    edited February 2016

    Thanks for the explanation @glenderson. That makes sense.

    I think the answer @allan gave might work well for me, too, although I might try both solutions.

    In my application I do need to process the whole row each time it is changed, setting row class and doing special rendering of a couple of fields.

    One other small point: it hurts the maintainability of the javascript to hardcode the column index. Is the table api instance available to either the rowCallback or render function, to determine the index from the column name as I did in my original example?

  • glendersonglenderson Posts: 231Questions: 11Answers: 29

    I think that render is best used for changing the data inside the cell, while rowcallback is best for changing data outside the cell (including td class and style). Since I always pass the actual HTML for inside the cell, I don't use render.

    Knowing the ordinal of the cell is a maintenance issue. I overcame that by not writing any javaScript at all and writing an api that determined the actual ordinal of the column at time of insertion. But, I'm sure there are other ways to do it programmatically.

  • loukinglouking Posts: 259Questions: 52Answers: 0
    edited February 2016

    Is there any way to set/update the columns.render function or rowCallback function after initialization? If there is the column index could be obtained from the table api instance.

    Added:
    Maybe use this.api() inside the callback based on https://datatables.net/examples/api/api_in_init.html .

    But when I tried that I get "Uncaught TypeError: this.api is not a function". See http://codepen.io/louking/pen/yeRYzE

    MTA: Seems like this is referring to the window, not the table here.

  • loukinglouking Posts: 259Questions: 52Answers: 0
    edited February 2016

    I was able to answer my own question about the named column.

    Based on docs in https://datatables.net/reference/option/columns.render , api can be obtained from the meta argument, "settings - The DataTables.Settings object for the table in question. This can be used to obtain an API instance if required."

    Relevant code is

    var table = $('#tbl').DataTable({
      columns: [{ name: 'a' }, 
                { name: 'b', render: function ( data, type, row, meta ) {
                  var settings = meta.settings;
                  var api = new $.fn.dataTable.Api( settings );
                  var a_ndx = api.column('a:name').index();
                  return 'xx'+row[a_ndx];
                } }, 
                { name: 'c' }],
    
    });
    

    See http://codepen.io/louking/pen/JGmKNq

  • allanallan Posts: 63,695Questions: 1Answers: 10,500 Site admin

    it hurts the maintainability of the javascript to hardcode the column index

    Use objects instead - much easier :-)

    Allan

  • loukinglouking Posts: 259Questions: 52Answers: 0

    Use objects instead - much easier :-)

    perfect, thanks

    updated codepen: http://codepen.io/louking/pen/GoYNEL

This discussion has been closed.