Checkbox selection for DataTable

pull/41/head
cagataycivici 2019-07-09 15:41:15 +03:00
parent b2c695e9fc
commit 15d200848b
4 changed files with 139 additions and 6 deletions

View File

@ -28,6 +28,7 @@
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
<span v-if="col.sortable" :class="getSortableColumnIcon(col)"></span>
<ColumnSlot :column="col" type="filter" v-if="col.$scopedSlots.filter" />
<DTHeaderCheckbox :checked="allRowsSelected" @change="toggleRowsWithCheckbox" :disabled="empty" v-if="col.selectionMode ==='multiple'" />
</th>
</tr>
</thead>
@ -46,7 +47,8 @@
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.bodyStyle" :class="col.bodyClass">
<ColumnSlot :data="rowData" :column="col" type="body" v-if="col.$scopedSlots.body" />
<template v-else-if="col.selectionMode">
<DTRadioButton :value="rowData" :checked="isSelected(rowData)" @change="toggleRowWithRadio" />
<DTRadioButton :value="rowData" :checked="isSelected(rowData)" @change="toggleRowWithRadio" v-if="col.selectionMode === 'single'" />
<DTCheckbox :value="rowData" :checked="isSelected(rowData)" @change="toggleRowWithCheckbox" v-else-if="col.selectionMode ==='multiple'" />
</template>
<template v-else>{{resolveFieldData(rowData, col.field)}}</template>
</td>
@ -81,6 +83,8 @@ import FilterUtils from '../utils/FilterUtils';
import DomHandler from '../utils/DomHandler';
import Paginator from '../paginator/Paginator';
import RowRadioButton from './RowRadioButton';
import RowCheckbox from './RowCheckbox.vue';
import HeaderCheckbox from './HeaderCheckbox.vue';
const ColumnSlot = {
functional: true,
@ -616,6 +620,33 @@ export default {
this.$emit('row-select', {originalEvent: event, data: rowData, type: 'radiobutton'});
}
},
toggleRowWithCheckbox(event) {
const rowData = event.data;
if (this.isSelected(rowData)) {
const selectionIndex = this.findIndexInSelection(rowData);
const _selection = this.selection.filter((val, i) => i != selectionIndex);
this.$emit('update:selection', _selection);
this.$emit('row-unselect', {originalEvent: event, data: rowData, type: 'checkbox'});
}
else {
let _selection = this.selection ? [...this.selection] : [];
_selection = [..._selection, rowData];
this.$emit('update:selection', _selection);
this.$emit('row-select', {originalEvent: event, data: rowData, type: 'checkbox'});
}
},
toggleRowsWithCheckbox(event) {
const processedData = this.processedData;
const checked = this.allRowsSelected;
const _selection = checked ? [] : (processedData ? [...processedData] : [...this.value]);
this.$emit('update:selection', _selection);
if (checked)
this.$emit('row-unselect-all', {originalEvent: event});
else
this.$emit('row-select-all', {originalEvent: event, data: _selection});
},
isSingleSelectionMode() {
return this.selectionMode === 'single';
},
@ -698,10 +729,10 @@ export default {
rangeEnd -= this.first;
}
const filteredValue = this.processedData;
const value = this.processedData;
let _selection = [];
for(let i = rangeStart; i <= rangeEnd; i++) {
let rangeRowData = filteredValue ? filteredValue[i] : this.value[i];
let rangeRowData = value[i];
_selection.push(rangeRowData);
this.$emit('row-select', {originalEvent: event, data: rangeRowData, type: 'row'});
}
@ -760,7 +791,7 @@ export default {
return this.totalRecords;
}
else {
const data = this.hasFilters ? this.processedData : this.value;
const data = this.processedData;
return data ? data.length : 0;
}
},
@ -796,12 +827,18 @@ export default {
},
loadingIconClass() {
return ['p-datatable-loading-icon pi-spin', this.loadingIcon];
},
allRowsSelected() {
const val = this.processedData;
return (this.value && this.value.length > 0 && this.selection && this.selection.length > 0 && this.selection.length === this.value.length);
}
},
components: {
'ColumnSlot': ColumnSlot,
'DTPaginator': Paginator,
'DTRadioButton': RowRadioButton
'DTRadioButton': RowRadioButton,
'DTCheckbox': RowCheckbox,
'DTHeaderCheckbox': HeaderCheckbox
}
}
</script>

View File

@ -0,0 +1,41 @@
<template>
<div class="p-checkbox p-component" @click="onClick">
<div class="p-hidden-accessible">
<input ref="input" type="checkbox" :checked="checked" @focus="onFocus($event)" @blur="onBlur($event)" :disabled="disabled">
</div>
<div ref="box" :class="['p-checkbox-box p-component', {'p-highlight': checked, 'p-disabled': $attrs.disabled, 'p-focus': focused}]">
<span :class="['p-checkbox-icon p-c', {'pi pi-check': checked}]"></span>
</div>
</div>
</template>
<script>
import ObjectUtils from '../utils/ObjectUtils';
export default {
inheritAttrs: false,
props: {
disabled: null,
checked: null
},
data() {
return {
focused: false
};
},
methods: {
onClick(event) {
if (!this.disabled) {
this.$emit('change', event);
this.$refs.input.focus();
}
},
onFocus(event) {
this.focused = true;
},
onBlur(event) {
this.focused = false;
}
}
}
</script>

View File

@ -0,0 +1,46 @@
<template>
<div class="p-checkbox p-component" @click="onClick">
<div class="p-hidden-accessible">
<input ref="input" type="checkbox" :checked="checked" @focus="onFocus($event)" @blur="onBlur($event)" :disabled="disabled">
</div>
<div ref="box" :class="['p-checkbox-box p-component', {'p-highlight': checked, 'p-disabled': $attrs.disabled, 'p-focus': focused}]">
<span :class="['p-checkbox-icon p-c', {'pi pi-check': checked}]"></span>
</div>
</div>
</template>
<script>
import ObjectUtils from '../utils/ObjectUtils';
export default {
inheritAttrs: false,
props: {
value: null,
disabled: null,
checked: null
},
data() {
return {
focused: false
};
},
methods: {
onClick(event) {
if (!this.disabled) {
this.$emit('change', {
originalEvent: event,
data: this.value
});
this.$refs.input.focus();
}
},
onFocus(event) {
this.focused = true;
},
onBlur(event) {
this.focused = false;
}
}
}
</script>

View File

@ -61,7 +61,16 @@
<Column field="brand" header="Brand"></Column>
<Column field="color" header="Color"></Column>
</DataTable>
{{selectedCar3 ? selectedCar3.vin : 'none'}}
<h3>Checkbox</h3>
<p>Multiple selection can also be handled using checkboxes by enabling the selectionMode property of column as "multiple".</p>
<DataTable :value="cars" :selection.sync="selectedCars3" dataKey="vin">
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
<Column field="vin" header="Vin"></Column>
<Column field="year" header="Year"></Column>
<Column field="brand" header="Brand"></Column>
<Column field="color" header="Color"></Column>
</DataTable>
</div>
<DataTableDoc />