Updating cell value/HTML in a hidden column
Updating cell value/HTML in a hidden column
Im using the DataTable Buttons extension to manage the visibility of the columns in a table.
When someone updates an "asset" (Meaning the data in a row), via the jQuery x-editable plugin, I use the success handler to get the username that just edited the value, as well as the timestamp, from the AJAX request result, then update the modified and modifier column values.
My question is, when someone has the column hidden, I cant update the value in the DOM, is there a way to update the cell value when its not visible?
The code im using below (I know it isnt DataTables, just my jQuery, but it might help)
$(document).ready(function(){
wp.hooks.addAction( 'assets.xeditable.success', function(data) {
var modified = data.response.asset.modified;
var modifier = data.response.asset.modifier;
var modifier_username = data.response.asset.modifier_username;
// Get the correct row in DataTables
var $asset_row = $( '#data-table' ).find('tbody' ).find('tr[data-row-id="' + data.asset_id + '"]' );
// Update the Modified and Modifier columns in DataTables
$asset_row.find( 'td.modified' ).html(modified);
$asset_row.find( 'td.modifier' ).html('<a href="/account/details/' + modifier + '">' + modifier_username + '</a>');
} );
});
Again, im not asking for help with the jQuery x-editable plugin, just need to know how to update the value of a cell in a hidden column within DataTables
This question has an accepted answers - jump to answer
Answers
I feel like I'm ALMOST there..
Function: assets.list()
Function: assets.editable()
Error: jquery.dataTables.js:8669 Uncaught TypeError: Cannot read property 'row' of undefined
P.S. The above code seems to work ok as long as the column isnt hidden...
I guess this might be the answer?
Found it from here
It seems to be for Legacy DT though
Also tried to just reset it in the DOM and invalidate the cells, no success
Bump anyone?
I think I would use the .data method for this
@glenderson, did you see my 2nd post? The code snippet in the bottom?... Here it is again
Error: Uncaught TypeError: Cannot read property 'row' of undefined on jquery.dataTables.js:8669
@glenderson When I try your code:
The error alert: DataTables warning: table id=data-table - Requested unknown parameter '[object Object]' for row 0. For more information about this error, please see http://datatables.net/tn/4
And in the console: Uncaught TypeError: Cannot assign to read only property 'display' of Sep 18, 2015, 7:06:22 MST
I'm not sure what your modifier and modified are supposed to be sorry, but they should be the new contents of cell (2) and cell (3). Please note [2] and [3] can only be used if you don't name your columns. If you name, then then d["columnName"] must be used.
Here's a simple fiddle using parts of your code.
http://jsfiddle.net/glenderson/om30e27x/
It's takes the table and updates the "name" column in row #1 to be "A New User". There is first an alert just to show the contents of the row prior to change.
Hope this helps.
The issue that im referring to though, (the thread topic), is that I cant update the content of the cell, if the column is hidden...
Here's an update that better shows how to hide the column, display the column, and apply an update to the column.
Please note, the jQuery selector is ONLY picking up the first row <TR>. To accurately select a row, I would suggest including an id on each row.
http://jsfiddle.net/glenderson/om30e27x/3/
The "myColumn" class is applied to the "name" column as part of the table initialization.
myColumn is initially hidden.
You can toggle the display of the "name" column via the button.
Enter a new value for Row #1 (always row #1 in this example).
Hit the button to apply the change.
Whether the row is displayed or not, it gets updated.
Thanks so far @glenderson
Good news! I got the Modifier and Modified columns to update, even when the column is hidden..
Bad news Since Im updating the entire row, it breaks the (x-editable)[https://vitalets.github.io/x-editable/] in the cell thats being updated.. Code below:
So I think if I redraw the cell, (not the whole row) it should work...
But when I comment out the last row with the
draw()
, and add...I get the error posted above, which is jquery.dataTables.js:8669 - Uncaught TypeError: Cannot read property 'row' of undefined
I believe it breaks the x-editable because when the whole row is redrawn, it takes it from the DOM again (as thats the source), and xeditable changes the contents of the cell when its completed, so those are conflicting actions
And heres the DOM elements of the table, you can see the row > td has the modifier and modified
data-field
attribute valueshttp://d.pr/i/1fK6E
@glenderson I really appreciate you trying to help me out with this btw, its really holding me back
I've just thrown together this test case and is seems to work just fine for me.
Try simplifying your selector and use:
Failing that, please link to a test case showing the issue.
Allan
Uhm... that will always just update the very first row though... every row in that column has
data-field="modified"
Here, I tried to replicate it as much as I could on live.datatables.net, I had to use the more complicated selector in the cell so it would update just the necessary row...
http://live.datatables.net/duluravi/1/edit?html,js,output
it will update the value if its visible, but if its not, it wont
Whats more, the error when viewing the JS console (Not the console in the editor, no idea where that gets its data..) the error is exactly what I see.. :-D Yay, now I can replicate it.
With colVis, the columns are not just being hidden, they are literally being removed from the DOM. If you inspect the element, you will see they are totally removed from the DOM, not just set to display:hidden. As such, jQuery selectors cannot locate the data-modified attribute because the td does not exist in the jQuery space. It only exists in the dataTable data array. if you alert on your value, it will be NaN.
If you use the table.row(row).draw(d) method, it works for a named column. But if your modified column can be any column, and it can be hidden, then you'll need a completely different manner of specifying which column is being updated per row. You cannot rely on the DOM because the column might be removed, and thus jQuery cannot find it.
If you hide the columns with a class instead of colVis, then your code should work.
In looking into the button.colVis extension, I could not figure out how to easily access that stored array. In theory, you should be able to access the stored invisible column to determine if there's the attribute of data-field. But, it was tasking me too long to figure it out. Sorry.
So I then starting thinking about putting the modified column name into a row attribute instead.
Then you can read what column by the data-modified value was modified, and it can be different for each row. Since you know the row, read the column data-modified value, then update the data[] value, and cell().draw(d) just that cell. Only thing I could think of quickly to overcome your issue.
I had assumed that the editable library you are using was adding the modified attribute.
What glenderson says is absolutely correct (although I would suggest avoiding hiding DataTables elements with a class and use DataTables methods instead).
To get the cell - just use the
cell()
method :-). Here is your example updated: http://live.datatables.net/duluravi/7/editAllan
@allan, that example works for you? The cell gets updated when the col is hidden? It doesnt for me. @glenderson, how about you? Give it a shot
I tried some new stuff, like redrawing just the cell, but it didnt seem to work (unless im doing it wrong)
The very last try however,
$assets_dt.cell( $asset_row.find('td[data-field="modified"]') ).data({ modified: modified }).draw();
, seems to update the modified column, with an object?@glenderson
The Rows each have a
data-row-id
attribute that I use to find the rows, the row ID is the asset ID, and each cell has adata-field='field-name'
which is also the name of the DataTable column, when DataTable is actually initialized, the jQuery goes through and gets these attributes (since they're also in the header, the same way), heres the relevant code for the initializationHeres the DOM
http://d.pr/i/1cHa6
Does that help at all?
For now, I kinda just decided to show the columns using
column().visible()
before the value gets updated... I guess thats not a terrible idea, it will have the viewer realize the values were updated. I might have the color change and fade out (since the value that was updated in the row does the same)That works for now I suppose :-\ Im showing the columns using the numerical value of the column, such as
table.column( 2 ).visible( true, false );
, is there a way to use the name of the column? Such as whats defined when the table is initiated? (liketable.column( 'modified' ).visible( true, false );
, which I tried, and failed)One more question since I'm here, related to this.
As you can see [here|http://d.pr/i/1cHa6], the modified column/cells have a
data-filter
attribute, with the actual Unix timestamp, is it possible to update that value as well?Thanks for the support thus far @allan @glenderson!
Oops - I hid the wrong column while testing it...
Yes.
I'll come back to this when I'm able, I'm sure there is a better way.
Allan
@allan
I would think so too, the DT API is very powerful, I was thinking that there was an easy solution that I just wasn't seeing and couldn't find.
Thanks!
@allan
Ok. I got it to work in the same function I initialized the table in, but if I go to a different function, where I re-initialize the DT to have access to it, it doesnt work, and if I pass the column names when I re-initialize the table, it still doesnt work, it alerts:
Test Case, but if you dont have time to look at this, thats fine, the col visibility one is more important, lol (Plus it would void the need for this)
Your example doesn't use the
columns.name
property which is required to name a column if you want to use that name in a column selector. This is referenced in the column selector documentation I linked to above.Allan
Oh wow, weird, when I used
columns.data
, it would work when referencing them by the name (of the data) in the same scope, so I thought that was fine. weird.Thanks!