DataTables presenting with a card view
DataTables presenting with a card view
I have seen lots of discussion on trying to get datatables to present in a "card" or "panel" type view. I see there are lots of workarounds utilizing the various callbacks and events. I believe i have found the simplest method yet.
My method relies solely on CSS. Heres a few screen shots and a link to a sample page.
azguys.com/datatables/index.html
I have tested it out on Chrome and IE, they both seem agreeable to the CSS, no funny quirks. Give it a try and let me know what you think, and if it may have problems of other browsers.
Replies
Genius! Absolutely brilliant in fact. Thanks for sharing this with us - I'm really impressed and that works very well.
Two areas that could possibly be improved:
This is absolutely something I will explore in more detail.
Thank you
Allan
Thanks. Pseudo classes work only for adding text to the DOM. So if you wanted a label, so that you can adjust its appearance, you have to use the render or some additional js for that. Also I personally try to keep design intent within one location. That's why i like the column definitions in a separate object, that way I can swap column configurations for different cases
Good point - if you wanted an image in the header there would be no way to do that with a ::before/::after. Possibly one for a plug-in that can dynamically inject the header text in that case.
Regardless, I really like this - thanks again.
Allan
Wow!!!
Allan is right- you are really a genius
You saved us days of work!!!!
Thank you very much
Marcus
Excellent!
hello jmwhiter, how are you?
I would like to ask you for a copy of the code that converts the datatable plugin to a card view.
Hi...i was also looking for code to present datatable as a card. please help!
Looks like the page is unfortunately gone, but here's the latest version the Way Back Machine has:
http://web.archive.org/web/20170605170544/http://azguys.com/datatables/index.html
You'll need to pick through the page source code to separate out the Way Back Machine stuff.
However, I think this would make a great plugin.
Ok, I've used the code from the Way Back Machine make some other adjustments in an attempt to improve this exceptional effort by @jmwither:
My results can be seen here: http://ghsfha.org/datatables_cards.html
I have:
- Updated to Datatables 1.10.16 and Select 1.2.4
- Updated JQuery to 3.2.1
- Updated to Bootstrap 4 beta 3
- Included Font Awesome 4.7.0
- Streamlined some of the css and add a js
'deselect'
to appropriately remove the row data from the alert on the bottomOf note to anyone interested, the only css that is absolutely necessary to get this effect is:
Everything else is simply for aesthetics.
@allan, instead of the render functions being this way:
render: function (data, type, full, meta) { return '<label>Extn:</label>' + data; }
is there a way to automatically grab the column header using the
meta.col
parameter?I tried:
render: function (data, type, full, meta) { return '<label>'+ table.column(meta.col).title() +':</label>' + data; }
But I get
TypeError: table is undefined
. I suppose the error is because table is in the process of still being defined.Any thoughts?
Also, the "cards" are not quite responsive, so when the screen is resized they don't dynamically adjust. They will refresh correctly, but not while the screen size is being changed.
Any ideas on that?
Finally -- any way to capture the button toggle as part of saveState?
Not quite compatible with the Scroller extension:
http://ghsfha.org/datatables_cards_scroller.html
-- Ignore the formatting of the odd rows. That part is a known issue: https://datatables.net/forums/discussion/44685
The real issue is that when swapping to Cards view, 1) the table that holds the Scroller header is still present and 2) when a filter or a sort is being executed, the left-to-right format of the cards "breaks" into a single column.
I suspect these issues are related to how @allan has programmed the Scroller, but maybe some minor adjustments to Scroller or a full-fledged cards extension could make it work.
Anyway, here's another option (plus an updated look) that shows all the rows (or cards) at once:
http://ghsfha.org/datatables_cards_all.html
It's basically achieved with a dom of 'fit' and a pageLen of -1.
You could also update the verbiage (or icons) from "Display as table" to "Display as cards" or whatever.
This would also be a great place to use the Buttons extension to better integrate the toggle with the DataTable code.
Another item that could be integrated is the Editor, with inline editing being particularly nice. As a matter of fact, you could largely sidestep the standalone editor as a whole depending on how the data might be displayed . . .
Thanks for the link and updated code. Looks good.
column().title()
is not a Datatable method. Maybe something like this will work for what you want?Instead of using
table
you can just get an instance of the API.Kevin
@kthorngren
Thanks Kevin, it doesn't quite work.
I don't get an error, so something is there, but nothing is returned now.
Using this same approach I've also tried text() (got nothing again) and innerHTML (got an error).
Maybe because the table isn't drawn yet?
Seems so. This example works with the table being built before the JS executes:
http://live.datatables.net/fobicoge/1/edit
Of course I didn't replicate the card view code, etc. Just the render function.
Kevin
Ok, upon troubleshooting further, maybe it's because I didn't have any
<th>
s in my tableSince I've added them it works perfect.
However, now I'm curious as to how DataTables knew to use the Title fields . . .
Another quick note -- the search picks up the labels since they are technically in the
<td>
along with the data.For example, typing "x" in the search box doesn't remove any entries since "Extn" is one of the labels.
This is true even when the data is viewed as a traditional table and the labels are hidden.
You can render the label for display only using orthogonal data. Try something like this in your render functions:
return type === 'display' ? '<label>'+ $(title).html() +':</label>' + data : data;
The
display
data will have the label. Sorting and searching will use the original data without the label.Kevin
Thanks, Kevin. That did the job!
Also, I've added an actual button to the table using the DataTables Button extension along with a little animate.css to make it stand out:
http://ghsfha.org/datatables_cards_button.html
So to put the cards into a table you pretty much just add the CSS along with the button.
BTW, do you know a simple way to change the text property on the button every time it's pressed?
I'd like use a card icon when the data is viewed as a table and a table icon when the data is viewed as cards, but it seems like I'd have to check each time as to what is currently displayed.
There are actually several drawbacks to this approach, one of which is that when the cards are not evenly sized the format is thrown off.
However I've made an update so that the height of all the cards (actually
<tr>
s) is changed to the height of the maximum card (<tr>
) so that the spacing works out:http://ghsfha.org/datatables_cards_button.html
This is still not quite as good as something like Bootstrap's card-deck class where it will size all the cards by the row, but it's a step in the right direction.
The power of this approach continues to be it's ease of implementation and the retention of all the DataTables functionality like filtering and ordering.
I wouldn't necessarily recommend it for all use cases, but there's definitely potential to cover many with fairly minimal effort.
Revisited this again, to get rid of the
<label>
inside of each cell and add adata-label
attribute that is shown through CSS when in card view. This is actually mentioned in @allan's initial feedback to the OP.I think it worked out really well: http://ghsfha.org/datatables_cards_labels.html
I used this article: https://florianziegler.com/css-tutorial-style-table-rows-to-look-like-cards/ plus there are a couple of other similar examples out there as well.
The key changes were to the button that toggles the view between the traditional table and cards.
Basically when the table goes into card view, the headers are used to populate the
data-label
attribute for each cell:Then some CSS places it properly:
Finally, although I suppose this might not be necessary, when the table goes back into the traditional view I remove the
data-label
attribute:A possible future improvement would be to allow a different label for the card than what the table has for a header. For example, originally the header for the first column in the table was "Photo", but I removed it altogether because I don't want that on the cards.
That is really impressive! Thanks for your updates on this - I'll be linking to this thread in future I'm certain!
Allan
Congratulation guys this is great job !
Many thanks,
Mike
Hi,
I'm wondering if this is possible to print PDF the result in card view
or do we need to change Make PDF code or CSS to make it display the same in PDF?
You'd need to change the document structure that the Buttons library uses to create the table. To be honest, I would just create a custom button that would build the pdfmake document you want rather than attempting to modify the built in one.
Allan
This is really beautiful indeed. I hope to use a modified version of this. I don't actually want the cards shown in a row like that. I'd like them to me responsively displayed vertically inside the content above the table.
I posted an article about this interesting approach at jQuery DataTables: Card view. I cleaned up the source code a little bit to make it more generalized. I am planning to improve the script based on feedback.
This update to the card view is excellent
However, when card view is enabled, it seems to break the clipboard export when using the following code to show only visible cells:
exportOptions: { columns: [':visible'], rows: [':visible']
Note that the clipboard copy works when out of card view again. Is there a way to make this work on card view as well?
sample:
https://jsfiddle.net/gL1o9f0h/
Maybe this is what you are looking for:
https://jsfiddle.net/h7usbfn0/
It uses
exportOptions: { rows: [':visible'] }
to export the rows on the page.Kevin
Almost,
While
exportOptions: { rows: [':visible']}
does indeed export all visible rows on the page to clipboard, it also exports hidden columns.The previous code
exportOptions { columns: [':visible'], rows: [':visible']}
exports only what is visible when outside of card view as expected, but does not copy anything at all with card view enabled.Any solution to this problem?
sample:
https://jsfiddle.net/ea3fbLk8/1/
@hm123 Using the following CSS rule for table head instead of
display: none
seems to solve the issue. Just need to figure out how to prevent hiddenthead
from occupying the space.See updated example for code and demonstration.