QTable question: Sort by selected/deselected rows
-
@metalsadman effectively it could be handled by some kind of computed/virtual table column.
-
@qyloxe - do you mean it could be handled in that way not changing Quasar code? If yes, could you elaborate a bit how this could be done? My guess is that somehow you would customize the header slot for that first “checkbox” column, which is Quasar generated, but I would need some sample code to start with.
-
@Mickey58
in:
https://quasar.dev/vue-components/table#Defining-the-columnsthis is actual column definition:
{ // unique id (used by row-key, pagination.sortBy, ...) name: 'desc', // label for header label: 'Dessert (100g serving)', // row Object property to determine value for this column field: 'name', // OR field: row => row.some.nested.prop // (optional) if we use visible-columns, this col will always be visible required: true, // (optional) alignment align: 'left', // (optional) tell QTable you want this column sortable sortable: true, // (optional) compare function if you have // some custom data or want a specific way to compare two rows sort: (a, b, rowA, rowB) => parseInt(a, 10) - parseInt(b, 10), // function return value: // * is less than 0 then sort a to an index lower than b, i.e. a comes first // * is 0 then leave a and b unchanged with respect to each other, but sorted with respect to all different elements // * is greater than 0 then sort b to an index lower than a, i.e. b comes first // (optional) you can format the data with a function format: (val, row) => `${val}%`, style: 'width: 500px', classes: 'my-special-class' },
If you could define “virtual” columns, then you could sort/filter/select them also. In example:
{ // unique id (used by row-key, pagination.sortBy, ...) name: 'desc', // label for header label: 'Dessert (100g serving)', // (optional) alignment align: 'left', // (optional) tell QTable you want this column sortable sortable: true, value: (col, row) => this.selected.includes(row.id) },
the new column attribute “value” could be a “virtual”/“computed” column with parameters:
col - this col definition
row - actual row - based on other row values “value” function returns proper computed valueIt would solve your problem and many others.
-
@qyloxe: Thanks, this looks promising, but I’m still unsure how I would insert this “virtual column” into the first column, especially in the upper left cell of the header of the q-table.
I see various slots in the q-table API for it, q-header, q-header-cell, q-header-cell[-name], q-th - not sure how to use them… Do you have a sample that manipulates the q-table header slots?
Maybe I still misunderstand it, and you mean I should insert a new, second “virtual” column (after the first column that has the Quasar generated checkboxes for row selection) just for sorting of the first column, with that little up/down arrow in the header?
-
@metalsadman and @qyloxe:
I forked a q-table codepen from @metalsadman that happens to customize the q-table header: [https://codepen.io/mickey58/pen/XWWVEEN]
This is what I changed:
- I added a “selection=‘multiple’” to the q-table, which auto-generates checkboxes in the first column.
- I added two so far empty <q-th> </q-th> elements to get proper alignment of the table columns.
I’m unsure how I could get that additional checkbox for selecting/unselecting all rows in the upper left corner cell (which is normally generated by Quasar in case of selection=“multiple”) and how to get to my end goal of getting sorting on it.
Maybe you can have a look at my codepen and have a suggestion?
-
I was able to add the checkbox for selecting/unselecting all rows in the upper left corner cell (which is normally generated by Quasar in case of selection=“multiple”) in the codepen at [https://codepen.io/mickey58/pen/XWWVEEN].
And I looked up the Quasar q-table source code to see how it handles the sorting of columns. The little “up/down” arrow icons that trigger the sorting are generated through very specific CSS, not through regular q-buttons. So it would require complicated CSS on the html table element for the first column/second header row, to get those arrows into the custom header in the codepen. That goes, at the moment, a bit too far in terms of customizing q-table.
What remains to be looked at as an alternative is @qyloxe’ suggestion to implement sorting on the checkbox column (which has v-model=“props.selected”) through an (additional?) virtual column on props.selected. If triggering that sorting directly through an icon in the column header is difficult, it could still be triggered through a button outside of the q-table.
-
Like i said, you can issue a feature request for this, since those controls are internal, maybe just a scope slot for the multi selection th column so that you can customize it, relative props should also be exposed along with the functions that make the deselection/selection of all visible rows. And imo it look like a valid feature that can prove to be useful for others too. maybe @qyloxe can provide you a pen with his idea how to do it. Was trying it earlier, but you’ll have to reinvent how the selection/deselection function works, the sorting is not the problem.
-
@metalsadman @Mickey58
Well, I have a mixed feelings about incorporating virtual columns into q-table. This is obviously the preferred way for presentation of computed (on the client side) values - in this example it is the “is selected” column but it could be anything - the sum of two other columns, the abstract of the long text, the amount with added local tax etc.IMHO the real problem is a concept of “data model”. Of course we could extend the q-table capabilities, BUT very similar capabilities should be possible for other components - list, tree etc. I consider it a bad design if every component would have his own “rules” and separate “data model” to deal with.
I think, that at this moment Quasar is in need of a separate non-visual component for data modelling. There should be column definitions (also virtual/computed), pagination, sorting, filtering, querying, events for data loading, server synchronization etc. This non-visual component (or maybe class?) should be attached by composition to visual components like q-table, q-list, q-tree etc.
So, I am sure, the computed/virtual columns are the way to go, but I’m not so sure, it should be implemented exactly into the q-table.
-
@metalsadman and @qyloxe - thanks for your thoughts. I agree that this stretches the customization of q-table quite far, and I also agree with @qyloxe that putting it into Quasar has also its downsides. The more such extras you put in, the more complex and heavyweight the components and their interfaces get - keeping a clean outside and inside design is important.
Nevertheless, I now managed to put this extra sorting capability on selected/deselected columns in through customization - it is in this codepen derived from another QTable sample from @metalsadman : https://codepen.io/mickey58/pen/XWWVEEN
Could you please have a quick look at the script section? Unfortunately I did not succeed in doing the computation of whether a row is selected into a computed: function. It is in a method currently, because it needs the row as a parameter. And I have “stolen” the sort function for Booleans from some other forum post.
I’d appreciate if you have a quick look and comment whether it could be done better. Thanks.
-
@qyloxe i agree, thats why the composition api is coming to vue 3 for such cases. Like i was saying, this could be exposed by a scope slot as of now imo. @Mickey58 sry cant test this as of now (im at mobile atm, will take a look asap), like i said above the sorting is not the problem, but the deselection/selection, can be done but its reinvention, when its already in there internally just not exposed at current api.