Update cell data by accessing row data with column index

Update cell data by accessing row data with column index

UdiDUdiD Posts: 16Questions: 7Answers: 1

I know that to update a cell data, the draw() function should be called, e.g.:
theGrid.cell($(cellChanged)).data(newValue).draw();

Now, I have a case where calling draw() is undesireable, since the updated cell has a render() function that does some overhead processing - and calling draw() causes render() to be called.

Therefore, what I'd like to achieve is changing the row data by using the index of the column being updated.
In other words, I'm looking for something similiar to the following (which doesn't work, of course):
var currentRowData = theGrid.row($(cellChanged).closest('tr')).data();

var columnIndexChanged = $(cellChanged).index();

currentRowData[columnIndexChanged] = newValue;

Here's a link to a fiddle that has the required code in it.

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    Hi,

    I'm not quite clear on what the issue is with the rendering function being called? In the demo it is listening for a change on a td cell - how do I trigger that to recreate the issue?

    My guess is that calling the rendering function is replacing the select with plain text - is that correct?

    Allan

  • UdiDUdiD Posts: 16Questions: 7Answers: 1

    Hi allan,

    to recreate the calling for the rendering function when a change is happening on the select dropdown - please uncomment the following line in my fiddle:

    theGrid.cell($(cellChanged)).data(cellChanged.children[0].value).draw();

    and then set a value in one of the dropdowns.

    As I said, my actual rendering function (which is not on my fiddle) has some overhead processing to do, and thus I'd like to avoid firing it; And if I'd use draw(), I can't avoid it.

    I'm not sure what you mean by "the rendering function is replacing the select with plain text". For the purpose of this question, the function BuildDropdown() in my fiddle can be treated as the "overhead processing" I mentioned. Not sure if this clarify, please ask for another clarification if needed.

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    How about just:

    theGrid.cell($(cellChanged)).data(cellChanged.children[0].value)
    

    That will update the data value for the row, it just won't draw the updated data (although that is irrelevant in this case since the data to display is what the user has selected).

    Any sorting or filtering would trigger the renderer though. You would want to only return the HTML select list when using the display data type in the renderer.

    Allan

  • UdiDUdiD Posts: 16Questions: 7Answers: 1

    Hmm, that's quite simple, I guess I should have thought it by myself :neutral:

    Thanks!

    BTW, how can I display a code block the way you did in your last message?

  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395
    Answer ✓

    BTW, how can I display a code block the way you did in your last message?

    Use Markdown. Instructions are at the bottom of the forum's "posting" pages.
    https://datatables.net/forums/post/question/

  • UdiDUdiD Posts: 16Questions: 7Answers: 1

    allan,

    Sorry, I rechecked your suggestion, and though no call to draw() is being made, the rendering function still get called. What else can be done?

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    The rendering function will always be called whenever DataTables needs the data for that cell - including getting the data type (which needs to be done when the data is changed). That's why I mentioned the display data type. There is more information about that in the orthogonal data section of the manual. I would suggest adding an if condition into your renderer for the display type.

    Allan

  • UdiDUdiD Posts: 16Questions: 7Answers: 1

    Well, the HTML returned is the result of the heavy processing of my rendering function.
    So no way I can somehow access the row data as if it were an array and access it with the column index (as my example in my question)?

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    I'm not actually entirely clear on what the goal is here, which is why I'm not doing a good job answering I'm afraid.

    Do you want to have the underlying data as such the selected value, but the display of the table should be the select list?

    Allan

  • UdiDUdiD Posts: 16Questions: 7Answers: 1

    Yeah, I think you understand me correctly. To sum it up, here's what should happen:
    1. User pick a new value on select list.
    2. JS function fired, which updates Datatables underlying cell/row data
    --> Important: The JS function should be a "general" one. I.e., it should not access the data by specifying the row's data object's property name (This is why I asked about accessing the row data as an array, using only the column index).
    3. Cell rendering function should not get fired after step 2

    And you can see my commented code in the fiddle I attached.

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    Okay, what I would suggest is that you create the select inside the rendering function when the display type is requested:

    render: function ( data, type, row ) {
      if ( type === 'display' ) {
        var select = '<select>';
        // build options and mark the selected one (which is `data`) as checked
        return select;
      }
    
      return data.
    }
    

    Then it doesn't matter if the rendering function is called or not and the underlying data is the value you need.

    Allan

  • UdiDUdiD Posts: 16Questions: 7Answers: 1

    I guess we still don't have a common understading :(
    Since updating a value is also considered a 'display' type, the select list will be built on each update - this is exactly what I'd like to avoid.

    [Maybe you don't understand my fiddle? I added some alerts: here).

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    Since updating a value is also considered a 'display' type, the select list will be built on each update - this is exactly what I'd like to avoid.

    But if it rebuilds it to show the correctly selected value (which is what my suggestion above would achieve) what is the problem with that?

    The end user would never know that the select has been replaced with another one.

    Allan

This discussion has been closed.