|
1 | 1 | <template> |
2 | | - <div class="q-layout-padding"> |
3 | | - <q-input filled v-model="filter" label="Search" debounce="300"> |
4 | | - <q-icon slot="append" name="search" /> |
5 | | - </q-input> |
6 | | - |
7 | | - <div> |
8 | | - <q-toggle color="primary" v-model="loading" label="Show loading" /> |
9 | | - <q-toggle color="primary" v-model="dense" label="Dense" /> |
10 | | - <q-select filled multiple v-model="visibleColumns" :options="columns" option-value="name" option-disable="required" emit-value /> |
11 | | - <q-select class="q-mt-md" filled v-model="separator" :options="['horizontal', 'vertical', 'cell', 'none']" /> |
| 2 | + <div class="q-pa-md"> |
| 3 | + <div class="row items-center q-gutter-sm q-mb-md"> |
| 4 | + <q-btn label="Toggle data / no data" no-caps color="primary" @click="toggleData" /> |
| 5 | + <q-toggle label="Hide bottom" v-model="hideBottom" /> |
| 6 | + <q-toggle label="Hide sel rows banner" v-model="hideSelectedBanner" /> |
| 7 | + <q-toggle label="Hide no data" v-model="hideNoData" /> |
| 8 | + <q-toggle label="Hide pagination" v-model="hidePagination" /> |
12 | 9 | </div> |
13 | 10 |
|
14 | | - <h2>Fixed header</h2> |
15 | | - <q-table |
16 | | - :dense="dense" |
17 | | - table-style="max-height: 500px" |
18 | | - class="table-sticky" |
19 | | - :separator="separator" |
20 | | - :data="data" |
21 | | - :columns="columns" |
22 | | - :title="title" |
23 | | - :filter="filter" |
24 | | - :loading="loading" |
25 | | - :visible-columns="visibleColumns" |
26 | | - row-key="index" |
27 | | - virtual-scroll |
28 | | - :virtual-scroll-sticky-start="dense ? 24 : 48" |
29 | | - :pagination.sync="pagination" |
30 | | - :rows-per-page-options="[0]" |
31 | | - /> |
32 | | - |
33 | | - <h2>Basic</h2> |
34 | | - <q-table |
35 | | - :dense="dense" |
36 | | - table-style="max-height: 500px" |
37 | | - :separator="separator" |
38 | | - :data="data" |
39 | | - :columns="columns" |
40 | | - :title="title" |
41 | | - :filter="filter" |
42 | | - :loading="loading" |
43 | | - :visible-columns="visibleColumns" |
44 | | - row-key="index" |
45 | | - virtual-scroll |
46 | | - /> |
47 | | - |
48 | | - <h2>With slots</h2> |
49 | 11 | <q-table |
50 | | - ref="virtualScrollTable" |
51 | | - :dense="dense" |
52 | | - table-style="max-height: 500px" |
53 | | - class="table-sticky" |
54 | | - :separator="separator" |
55 | | - :data="data" |
| 12 | + title="Treats" |
| 13 | + :data="rows" |
56 | 14 | :columns="columns" |
57 | | - :title="title" |
58 | | - :filter="filter" |
59 | | - :loading="loading" |
60 | | - :visible-columns="visibleColumns" |
61 | | - row-key="index" |
62 | | - :virtual-scroll="pagination.rowsPerPage === 0" |
63 | | - :virtual-scroll-sticky-start="dense ? 24 : 48" |
64 | | - @virtual-scroll="onVirtualScroll" |
65 | | - :pagination.sync="pagination" |
| 15 | + row-key="name" |
| 16 | + selection="multiple" |
| 17 | + :selected.sync="selected" |
| 18 | + :hide-bottom="hideBottom" |
| 19 | + :hide-selected-banner="hideSelectedBanner" |
| 20 | + :hide-no-data="hideNoData" |
| 21 | + :hide-pagination="hidePagination" |
| 22 | + no-hover |
66 | 23 | > |
67 | | - <template v-slot:header="props"> |
68 | | - <q-tr :props="props"> |
69 | | - <q-th v-for="col in props.cols" :key="col.name" :props="props"> |
70 | | - {{ col.label }} |
71 | | - </q-th> |
72 | | - </q-tr> |
73 | | - </template> |
74 | | - |
75 | 24 | <template v-slot:body="props"> |
76 | 25 | <q-tr :props="props"> |
77 | | - <q-td v-for="col in props.cols" :key="col.name" :props="props"> |
78 | | - {{ col.value }} |
| 26 | + <q-td auto-width> |
| 27 | + <q-toggle dense v-model="props.selected" /> |
| 28 | + </q-td> |
| 29 | + <q-td key="desc" :props="props" no-hover> |
| 30 | + {{ props.rowIndex }} / {{ props.pageIndex }} - |
| 31 | + {{ props.row.name }} |
| 32 | + <q-btn dense round flat :icon="props.expand ? 'arrow_drop_up' : 'arrow_drop_down'" @click="props.expand = !props.expand" /> |
| 33 | + </q-td> |
| 34 | + <q-td key="calories" :props="props">{{ props.row.calories }}</q-td> |
| 35 | + <q-td key="fat" :props="props">{{ props.row.fat }}</q-td> |
| 36 | + <q-td key="carbs" :props="props">{{ props.row.carbs }}</q-td> |
| 37 | + <q-td key="protein" :props="props">{{ props.row.protein }}</q-td> |
| 38 | + <q-td key="sodium" :props="props">{{ props.row.sodium }}</q-td> |
| 39 | + <q-td key="calcium" :props="props">{{ props.row.calcium }}</q-td> |
| 40 | + <q-td key="iron" :props="props"> |
| 41 | + <q-badge color="amber"> |
| 42 | + {{ props.row.iron }} |
| 43 | + </q-badge> |
79 | 44 | </q-td> |
80 | 45 | </q-tr> |
81 | | - </template> |
82 | | - </q-table> |
83 | | - <div class="q-pa-md"> |
84 | | - <q-input |
85 | | - type="number" |
86 | | - :value="listIndex" |
87 | | - :min="0" |
88 | | - :max="pagination.rowsPerPage === 0 ? listSize : pagination.rowsPerPage - 1" |
89 | | - label="Scroll to index" |
90 | | - input-class="text-right" |
91 | | - @input="onIndexChange" |
92 | | - /> |
93 | | - </div> |
94 | | - |
95 | | - <h2>With slots & different sizes</h2> |
96 | | - <q-table |
97 | | - :dense="dense" |
98 | | - table-style="max-height: 500px" |
99 | | - class="table-sticky" |
100 | | - :separator="separator" |
101 | | - :data="data" |
102 | | - :columns="columns" |
103 | | - :title="title" |
104 | | - :filter="filter" |
105 | | - :loading="loading" |
106 | | - :visible-columns="visibleColumns" |
107 | | - row-key="index" |
108 | | - virtual-scroll |
109 | | - :virtual-scroll-sticky-start="dense ? 24 : 48" |
110 | | - :pagination.sync="pagination" |
111 | | - > |
112 | | - <template v-slot:header="props"> |
113 | | - <q-tr :props="props"> |
114 | | - <q-th v-for="col in props.cols" :key="col.name" :props="props"> |
115 | | - {{ col.label }} |
116 | | - </q-th> |
117 | | - </q-tr> |
118 | | - </template> |
119 | | - |
120 | | - <template v-slot:body="props"> |
121 | | - <q-tr :props="props"> |
122 | | - <q-td v-for="col in props.cols" :key="col.name" :props="props"> |
123 | | - {{ col.value }} |
124 | | - <div v-if="pagination.page % 2 === 0" style="height: 50px;" /> |
| 46 | + <q-tr v-show="props.expand" :props="props" no-hover> |
| 47 | + <q-td colspan="100%"> |
| 48 | + <q-table |
| 49 | + :data="rows" |
| 50 | + :columns="columns" |
| 51 | + > |
| 52 | + <q-tr :props="props" /> |
| 53 | + </q-table> |
125 | 54 | </q-td> |
126 | 55 | </q-tr> |
127 | 56 | </template> |
|
130 | 59 | </template> |
131 | 60 |
|
132 | 61 | <script> |
133 | | -const seed = [ |
| 62 | +const rows = [ |
134 | 63 | { |
135 | 64 | name: 'Frozen Yogurt', |
136 | 65 | calories: 159, |
@@ -233,89 +162,42 @@ const seed = [ |
233 | 162 | } |
234 | 163 | ] |
235 | 164 |
|
236 | | -// we generate lots of rows here |
237 | | -let data = [] |
238 | | -const listSize = 1000 |
239 | | -for (let i = 0; i < listSize; i++) { |
240 | | - data = data.concat(seed.slice(0).map(r => ({ ...r }))) |
241 | | -} |
242 | | -data.forEach((row, index) => { |
243 | | - row.index = index |
244 | | -}) |
245 | | -
|
246 | 165 | export default { |
247 | 166 | data () { |
248 | 167 | return { |
249 | | - dense: false, |
250 | | - title: 'QDataTable', |
251 | | - filter: '', |
252 | | - loading: false, |
253 | | - visibleColumns: ['index', 'desc', 'fat', 'carbs', 'protein', 'sodium', 'calcium', 'iron'], |
254 | | - separator: 'horizontal', |
255 | | - pagination: { |
256 | | - rowsPerPage: 0 |
257 | | - }, |
258 | | -
|
259 | | - listSize: listSize * seed.length - 1, |
260 | | - listIndex: 50, |
261 | | -
|
| 168 | + hideBottom: false, |
| 169 | + hideSelectedBanner: false, |
| 170 | + hideNoData: false, |
| 171 | + hidePagination: false, |
| 172 | + selected: [], |
262 | 173 | columns: [ |
263 | | - { |
264 | | - name: 'index', |
265 | | - label: '#', |
266 | | - field: 'index' |
267 | | - }, |
268 | 174 | { |
269 | 175 | name: 'desc', |
270 | 176 | required: true, |
271 | 177 | label: 'Dessert (100g serving)', |
272 | 178 | align: 'left', |
273 | 179 | field: row => row.name, |
274 | | - format: val => `~${val}`, |
| 180 | + format: val => `${val}`, |
275 | 181 | sortable: true |
276 | 182 | }, |
277 | 183 | { name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true }, |
278 | | - { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true }, |
| 184 | + { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true, style: 'width: 10px' }, |
279 | 185 | { name: 'carbs', label: 'Carbs (g)', field: 'carbs' }, |
280 | 186 | { name: 'protein', label: 'Protein (g)', field: 'protein' }, |
281 | 187 | { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' }, |
282 | 188 | { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, |
283 | 189 | { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) } |
284 | | - ] |
| 190 | + ], |
| 191 | + rows |
285 | 192 | } |
286 | 193 | }, |
287 | 194 |
|
288 | 195 | methods: { |
289 | | - onIndexChange (index) { |
290 | | - this.$refs.virtualScrollTable.scrollTo(index) |
291 | | - }, |
292 | | - onVirtualScroll ({ index }) { |
293 | | - this.listIndex = index |
| 196 | + toggleData () { |
| 197 | + this.rows = this.rows.length === 0 |
| 198 | + ? rows |
| 199 | + : [] |
294 | 200 | } |
295 | | - }, |
296 | | -
|
297 | | - created () { |
298 | | - this.data = data |
299 | | - }, |
300 | | -
|
301 | | - mounted () { |
302 | | - this.$refs.virtualScrollTable.scrollTo(this.listIndex) |
303 | 201 | } |
304 | 202 | } |
305 | 203 | </script> |
306 | | - |
307 | | -<style lang="stylus"> |
308 | | -.table-sticky |
309 | | - .q-table__top, |
310 | | - .q-table__bottom, |
311 | | - thead tr:first-child th /* bg color is important for th; just specify one */ |
312 | | - background-color: #c1f4cd |
313 | | -
|
314 | | - thead tr th |
315 | | - position: sticky |
316 | | - z-index: 1 |
317 | | - thead tr:last-child th // this will be the loading indicator |
318 | | - top: 48px // height of all previous header rows |
319 | | - thead tr:first-child th |
320 | | - top: 0 |
321 | | -</style> |
0 commit comments