Skip to content

Commit 1b4aa3e

Browse files
authored
Merge pull request #33 from HC200ok/enhance/support-nested-header-value
Enhance/support nested header value
2 parents 50754f9 + 62126ab commit 1b4aa3e

File tree

5 files changed

+132
-54
lines changed

5 files changed

+132
-54
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"author": "HC200ok",
44
"description": "A customizable and easy-to-use data table component made with Vue.js 3.x.",
55
"private": false,
6-
"version": "1.2.6",
6+
"version": "1.2.7",
77
"types": "./types/main.d.ts",
88
"license": "MIT",
99
"files": [

src/components/DataTable.vue

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
/>
7979
</template>
8080
<template v-else>
81-
{{ Array.isArray(item[column]) ? item[column].join(',') : item[column] }}
81+
{{ generateColumnContent(column, item) }}
8282
</template>
8383
</td>
8484
</tr>
@@ -453,6 +453,19 @@ const headersForRender = computed((): HeaderForRender[] => {
453453
454454
const headerColumns = computed((): string[] => headersForRender.value.map((header) => header.value));
455455
456+
const generateColumnContent = (column: string, item: Item) => {
457+
let content: any = '';
458+
if (column.includes('.')) {
459+
const propertyArr = column.split('.');
460+
propertyArr.forEach((property, index) => {
461+
content = (index === 0 ? item[property] : content[property]);
462+
});
463+
} else {
464+
content = item[column];
465+
}
466+
return Array.isArray(content) ? content.join(',') : content;
467+
};
468+
456469
// multiple selecting
457470
const selectItemsComputed = computed({
458471
get: () => props.itemsSelected ?? [],
@@ -531,6 +544,11 @@ const multipleSelectStatus = computed((): 'allSelected' | 'noneSelected' | 'part
531544
532545
const currentPaginationNumber = ref(isServerSideMode.value ? props.serverOptions.page : 1);
533546
547+
const { items } = toRefs(props);
548+
watch(items, () => {
549+
currentPaginationNumber.value = 1;
550+
}, { deep: true });
551+
534552
// rows per page
535553
const rowsPerPageReactive = ref(isServerSideMode.value ? props.serverOptions.rowsPerPage : props.rowsPerPage);
536554
watch(rowsPerPageReactive, (value) => {

src/mock.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ export const mockClientItems = (itemsNumber = 100): Item[] => {
3232
return mockItems;
3333
};
3434

35+
export const mockClientNestedItems = (itemsNumber = 100): Item[] => {
36+
const mockItems: Item[] = [];
37+
const sports = ['basketball', 'football', 'running', 'swimming'];
38+
const fruits = ['banana', 'apple', 'orange', 'peach'];
39+
40+
for (let i = 1; i < itemsNumber + 1; i += 1) {
41+
mockItems.push({
42+
name: `name-${i}`,
43+
address: `address-${i}`,
44+
info: {out: { height: i, weight: i }},
45+
age: i,
46+
favouriteSport: sports[i % 4],
47+
favouriteFruits: fruits[i % 4],
48+
});
49+
}
50+
return mockItems;
51+
};
52+
3553
export const mockServerItems = async (
3654
serverOptions: ServerOptions,
3755
serverItemsLength = 500,

src/modes/Client.vue

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
</span>
77
<Slider v-model="ageCriteria" class="slider"/>
88
</div> -->
9+
<button @click="switchToNested300">use nested 300</button>
10+
<button @click="switchToNested">use nested</button>
911
<div class="filter-wrapper">
1012
<span class="field">
1113
filtering by sport:
@@ -48,7 +50,6 @@
4850
buttons-pagination
4951
alternating
5052
:max-height="200"
51-
:filter-options="filterOptions"
5253
sort-by="age"
5354
sort-type="desc"
5455
@click-row="showItem"
@@ -57,7 +58,7 @@
5758

5859
<div class="customize-footer">
5960
<div class="customize-index">
60-
Now displaying: {{currentPageFirstIndex}} ~ {{currentPageLastIndex}} of {{totalItemsLength}}
61+
Now displaying: {{ currentPageFirstIndex }} ~ {{ currentPageLastIndex }} of {{ totalItemsLength }}
6162
</div>
6263
<div class="customize-buttons">
6364
<span
@@ -66,36 +67,61 @@
6667
:class="{'active': paginationNumber === currentPaginationNumber}"
6768
@click="updatePage(paginationNumber)"
6869
>
69-
{{paginationNumber}}
70+
{{ paginationNumber }}
7071
</span>
7172
</div>
7273
<div class="customize-pagination">
73-
<button class="prev-page" @click="prevPage" :disabled="isFirstPage">prev page</button>
74-
<button class="next-page" @click="nextPage" :disabled="isLastPage">next page</button>
74+
<button
75+
class="prev-page"
76+
:disabled="isFirstPage"
77+
@click="prevPage"
78+
>
79+
prev page
80+
</button>
81+
<button
82+
class="next-page"
83+
:disabled="isLastPage"
84+
@click="nextPage"
85+
>
86+
next page
87+
</button>
7588
</div>
7689
</div>
7790
</div>
7891
</template>
7992

8093
<script lang="ts" setup>
8194
// import Slider from '@vueform/slider';
82-
import { computed, ref, reactive, toRefs } from 'vue';
83-
import { Header, Item, FilterOption, clickRowArgument } from "../types/main";
95+
import {
96+
computed, ref, reactive, toRefs,
97+
} from 'vue';
98+
import {
99+
Header, Item, FilterOption, clickRowArgument,
100+
} from '../types/main';
84101
import DataTable from '../components/DataTable.vue';
85-
import { mockClientItems } from "../mock";
102+
import { mockClientNestedItems, mockClientItems } from '../mock';
103+
104+
const searchField = ref('name');
105+
const searchValue = ref('name-1');
106+
107+
const items = ref<Item[]>(mockClientNestedItems(100));
86108
87-
const searchField = ref("name");
88-
const searchValue = ref("name-1");
109+
const switchToNested300 = () => {
110+
items.value = mockClientNestedItems(300);
111+
};
112+
113+
const switchToNested = () => {
114+
items.value = mockClientNestedItems(100);
115+
};
89116
90-
const items = ref<Item[]>(mockClientItems(100));
91117
const headers: Header[] = [
92-
{ text: "Name", value: "name" },
93-
{ text: "Address", value: "address" },
94-
{ text: "Height", value: "height", sortable: true },
95-
{ text: "Weight", value: "weight", sortable: true },
96-
{ text: "Age", value: "age", sortable: true },
97-
{ text: "Favourite sport", value: "favouriteSport" },
98-
{ text: "Favourite fruits", value: "favouriteFruits" },
118+
{ text: 'Name', value: 'name' },
119+
{ text: 'Address', value: 'address' },
120+
{ text: 'Height', value: 'info.out.height', sortable: true },
121+
{ text: 'Weight', value: 'info.out.weight', sortable: true },
122+
{ text: 'Age', value: 'age', sortable: true },
123+
{ text: 'Favourite sport', value: 'favouriteSport' },
124+
{ text: 'Favourite fruits', value: 'favouriteFruits' },
99125
];
100126
101127
const itemsSelected = ref<Item[]>([items.value[14]]);
@@ -108,24 +134,24 @@ const showItem = (item: clickRowArgument) => {
108134
109135
const ageCriteria = ref<[number, number]>([1, 15]);
110136
111-
const favouriteSportCriteria = ref('basketball');
112-
113-
const filterOptions = computed((): FilterOption[] => {
114-
const filterOptionsArray: FilterOption[] = [];
115-
if (favouriteSportCriteria.value !== 'all') {
116-
filterOptionsArray.push({
117-
field: 'favouriteSport',
118-
comparison: '=',
119-
criteria: favouriteSportCriteria.value,
120-
});
121-
}
122-
filterOptionsArray.push({
123-
field: 'age',
124-
comparison: 'between',
125-
criteria: ageCriteria.value,
126-
});
127-
return filterOptionsArray;
128-
});
137+
const favouriteSportCriteria = ref('all');
138+
139+
// const filterOptions = computed((): FilterOption[] => {
140+
// const filterOptionsArray: FilterOption[] = [];
141+
// if (favouriteSportCriteria.value !== 'all') {
142+
// filterOptionsArray.push({
143+
// field: 'favouriteSport',
144+
// comparison: '=',
145+
// criteria: favouriteSportCriteria.value,
146+
// });
147+
// }
148+
// filterOptionsArray.push({
149+
// field: 'age',
150+
// comparison: 'between',
151+
// criteria: ageCriteria.value,
152+
// });
153+
// return filterOptionsArray;
154+
// });
129155
130156
// $ref dataTable
131157
const dataTable = ref();

src/modes/ServerSide.vue

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,16 @@
2020
<a :href="address">{{ address }}</a>
2121
</template>
2222
<template #pagination="{ prevPage, nextPage, isFirstPage, isLastPage }">
23-
<button :disabled="isFirstPage" @click="prevPage">
23+
<button
24+
:disabled="isFirstPage"
25+
@click="prevPage"
26+
>
2427
prev page
2528
</button>
26-
<button :disabled="isLastPage" @click="nextPage">
29+
<button
30+
:disabled="isLastPage"
31+
@click="nextPage"
32+
>
2733
next page
2834
</button>
2935
</template>
@@ -45,10 +51,18 @@
4551
</span>
4652
</div>
4753
<div class="customize-pagination">
48-
<button class="prev-page" @click="prevPage" :disabled="isFirstPage">
54+
<button
55+
class="prev-page"
56+
:disabled="isFirstPage"
57+
@click="prevPage"
58+
>
4959
prev page
5060
</button>
51-
<button class="next-page" @click="nextPage" :disabled="isLastPage">
61+
<button
62+
class="next-page"
63+
:disabled="isLastPage"
64+
@click="nextPage"
65+
>
5266
next page
5367
</button>
5468
</div>
@@ -57,22 +71,24 @@
5771
</template>
5872

5973
<script lang="ts">
60-
import { Header, Item, ServerOptions } from "../types/main";
74+
import {
75+
defineComponent, ref, computed, watch, onMounted, Ref,
76+
} from 'vue';
77+
import { Header, Item, ServerOptions } from '../types/main';
6178
import DataTable from '../components/DataTable.vue';
62-
import { mockClientItems, mockServerItems } from "../mock";
63-
import { defineComponent, ref, computed, watch, onMounted, Ref, } from "vue";
79+
import { mockClientItems, mockServerItems } from '../mock';
6480
6581
export default defineComponent({
66-
components: {DataTable},
82+
components: { DataTable },
6783
setup() {
6884
const headers: Header[] = [
69-
{ text: "Name", value: "name" },
70-
{ text: "Address", value: "address" },
71-
{ text: "Height", value: "height", sortable: true },
72-
{ text: "Weight", value: "weight", sortable: true },
73-
{ text: "Age", value: "age", sortable: true },
74-
{ text: "Favourite sport", value: "favouriteSport" },
75-
{ text: "Favourite fruits", value: "favouriteFruits" },
85+
{ text: 'Name', value: 'name' },
86+
{ text: 'Address', value: 'address' },
87+
{ text: 'Height', value: 'height', sortable: true },
88+
{ text: 'Weight', value: 'weight', sortable: true },
89+
{ text: 'Age', value: 'age', sortable: true },
90+
{ text: 'Favourite sport', value: 'favouriteSport' },
91+
{ text: 'Favourite fruits', value: 'favouriteFruits' },
7692
];
7793
const items = ref<Item[]>([]);
7894
const itemsSelected = ref<Item[]>([items.value[0]]);
@@ -103,7 +119,7 @@ export default defineComponent({
103119
() => {
104120
loadFromServer();
105121
},
106-
{ deep: true }
122+
{ deep: true },
107123
);
108124
// $ref dataTable
109125
const dataTable = ref();

0 commit comments

Comments
 (0)