Related
I made some code that hides a column by clicking on a checkbox and saves the changes to localstorage. The data is coming from a database so I have only 1 row line. My issue is when I refresh the page the header info is hiding itself which is good, but the rest of the lines are coming back. I would like to hide all of the column not just the header.
You can see on the image only the headers are not there after refreshing the page.
mounted() {
// "data-control-column" is a custom data attribute added to the html checkboxes
// when a check box changes loop through all, for any that are unchecked, add that checkbox's "data-control-column" value to our array
$('.opt').change(function(){
var states = [];
$('.opt').each(function(){
if(!$(this).is(':checked')) states.push($(this).data('control-column'));
});
setSates(states);
});
// when we need to set the sate of the UI, loop through the checkboxes checking if their "data-control-column" are in the "states" array
// if so, hide the specified column and uncheck the box
function setSates(states){
if(states){
if(!$.isArray( states )) states = JSON.parse(states); // if sates came from localstorage it will be a string, convert it to an array
$('.opt').each(function(i,e){
var column =$(this).data('control-column');
if($.inArray( column, states ) == -1){
$(this).attr('checked', true);
$('#myTable td:nth-child('+column+'), #myTable th:nth-child('+column+')').show();
}
else{
$(this).attr('checked', false);
$('#myTable td:nth-child('+column+'), #myTable th:nth-child('+column+')').hide();
}
});
localStorage.setItem('states', JSON.stringify(states));
}
}
// this will read and set the initial states when the page loads
setSates( localStorage.getItem('states') );
},
My database:
data() {
return {
hidePreLoader: true,
price: '',
purchase_price: '',
selling_price: '',
products: {},
tableOptions: {
tableName: 'products',
columns: [
{
title: 'lang.item_image',
key: 'image',
type: 'images',
source: '/uploads/products',
imagefield: 'imageURL',
sortable: false,
},
{title: 'lang.attribute_values', key: 'attribute_values', type: 'text', sortable: true},
{title: 'lang.quantity', key: 'test', type: 'text', sortable: true},
{title: 'lang.barcode', key: 'bar_code', type: 'text', sortable: true},
{title: 'lang.sku_2', key: 'sku_2', type: 'text', sortable: true},
{title: 'lang.sku_3', key: 'sku_3', type: 'text', sortable: true},
{title: 'lang.sku_4', key: 'sku_4', type: 'text', sortable: true},
{title: 'lang.selling_price', key: 'selling_price', type: 'text', sortable: true},
{title: 'lang.receiving_price', key: 'purchase_price', type: 'text', sortable: true},
],
formatting : ['selling_price','purchase_price'],
source: '/products/variantDetails/' + this.id,
},
}
},
and the checkbox:
<input type="checkbox" checked="checked" data-control-column="1" class="opt" />{{ trans('lang.item_image') }}
I'm trying to use the checkbox in vue-good-table to select rows, then a button in the selected row action slow to perform a function on the selected rows. How can I access the data?
https://xaksis.github.io/vue-good-table/guide/advanced/checkbox-table.html#selected-row-action-slot
This doesn't work:
<vue-good-table
#on-selected-rows-change="selectAll"
:columns="columns2"
id="shift.id"
:ref="shift.id"
:rows="orderedPlacedUsers(shift)"
:select-options="{
enabled: true,
selectOnCheckboxOnly: true,
}"
>
<div slot="selected-row-actions">
<button class="btn btn__small btn__flat" #click="lockAll(shift)">Lock All <i class="ml-2 fas fa-lock-alt"></i></button>
</div>
</div>
</vue-good-table>
Then
data() {
return {
columns2: [
{
label: '',
field: 'extras',
tdClass: 'text-center',
sortable: false,
},
{
label: 'Name',
field: 'fullName',
},
{
label: 'Signed Up',
field: 'created',
sortable: false,
},
{
label: 'Job',
field: 'requestedJob.title',
tdClass: 'text-center',
},
{
label: '',
field: 'notes',
sortable: false,
tdClass: 'text-center',
},
{
label: '',
field: 'reservations',
tdClass: 'text-center',
tdClass: 'text-center',
sortable: false,
},
{
label: '',
field: 'delete',
tdClass: 'text-center',
sortable: false,
},
]
}
}
methods: {
lockAll(shift) {
console.log(shift.id)
console.log(this.$refs[shift.id].selectedRows)
},
orderedPlacedUsers (shift) {
function compare(a, b) {
if (a.firstName < b.firstName)
return -1;
if (a.firstName > b.firstName)
return 1;
return 0;
}
return this.filteredPlacedUsers.sort(compare).filter(user => {
return user.shift == shift.id && user.day == shift.day
});
},
}
The shift is "shift in eventShifts"... here's what that looks like:
{"day":"2021-08-27","endTime":null,"payrollComplete":true,"startTime":"14:00","event":"Los Bukis","id":"dvaBm5wQXMXvVCGBSK8e","exportedCont":{"seconds":1631208172,"nanoseconds":886000000},"collapse":false,"position":{"title":null},"selectedStaff":null,"eventId":"CGHMVzcKPnNLsmRxoeVj","exportedEmp":{"seconds":1631208185,"nanoseconds":622000000},"name":"Line Cook","staff":"50"}
Thank you!
To access the vue-good-table via this.$refs you need to add :ref property into vue-good-table.
<vue-good-table
:id="shift.id"
:ref="shift.id"
>
</vue-good-table>
But there is another thing to be considered, it says here that
When used on elements/components with v-for, the registered reference
will be an Array containing DOM nodes or component instances.
In your case, probably vue-good-table is used on an element/component with v-for. So, you can access it via this.$refs[shift.id][0]. Finally, you can print the selectedRows using console.log(this.$refs[shift.id][0].selectedRows)
I have a table displaying search results with server side Pagination but when I click the columns, there is no sorting taking place and the server displays the results again for any of the column arrow clicks. Is there any way I can limit the pagination to take place only for the page arrows in the footer and then sorting to take place for the displayed results when i click the columns?
<q-table
dense
:title="Patient result"
:data="searchResultList"
:columns="columns"
:pagination="serverPagination"
row-key="name"
:no-data-label="noDataMessage"
:loading="loading"
#request="request"
>
data() {
return {
filter: '',
columns: [
{
name: 'patientId',
required: true,
label: 'patientId',
align: 'left',
field: row => row.patientId,
format: val => `${val}`,
sortable: true,
}
{
name: 'lastname', align: 'center', label: 'lastname', field: 'lastname', sortable: true,
},
{
name: 'firstname', align: 'center', label: 'firstname', field: 'firstname', sortable: true,
},
{
name: 'dob', align: 'center', label: 'dob', field: 'dob', sortable: true,
},
],
page: 1,
rowsInPage: 25,
};
computed: {
serverPagination() {
return {
sortBy: this.paginationObject.sortBy,
descending: this.paginationObject.descending,
page: this.paginationObject.page,
rowsNumber: this.patientSearchResults.count,
rowsPerPage: this.paginationObject.rowsPerPage,
};
paginationObject: {
sortBy: 'name',
descending: false,
page: 1,
rowsPerPage: 25,
methods: {
request(props) {
this.$store.dispatch('patientSearch/setPaginationObject', props);
},
Use sort-method. You can write a custom function where you can pass the rows(Not all but according to pagination i.e. if the selected page is 1 the rows will be 0-5 from your array. Here I'm guessing the default visible rows will be 5.)
Check out this API reference - https://quasar.dev/vue-components/table
In QTable API, you will find the details about this method.
I've built a Vue.js component. I have a vue-good-table, where it fetches data from the server. I need to format the output data. Now the data comes with numbers. For example: it's show number 1 as a value. Instead of "1" it has to be ITEM1, for 2 - ITEM2 and so on.
<vue-good-table
:columns="columns"
:rows="formattedItems"
:paginate="true"
:lineNumbers="true">
</vue-good-table>
<script type="text/javascript">
import config from '../main.js'
import moment from 'moment'
export default {
components: {
},
data(){
return {
items: [],
columns: [
{
label: 'Number',
field: 'number',
type: 'String',
filterable: true,
placeholder: 'Number'
},
{
label: 'Name',
field: 'name',
type: 'String',
filterable: true,
placeholder: 'Name'
},
{
label: 'Validity Date',
field: 'validitydate',
type: 'String',
filterable: true,
placeholder: 'dd/mm/yyyy'
},
{
label: 'Authority',
field: 'authority',
type: 'String',
filterable: true,
placeholder: 'Authority'
},
{
label: 'Status',
field: 'status',
type: 'String',
filterable: true,
placeholder: 'Status'
},
{
label: 'Structure',
field: 'structure',
type: 'String',
filterable: true,
placeholder: 'Structure'
},
{
label: 'Type',
field: 'type',
type: 'String',
filterable: true,
placeholder: 'Type'
},
{
label: 'National',
field: 'isnational',
type: 'String',
filterable: true,
placeholder: 'National'
},
],
json_meta: [
[{
"key": "charset",
"value": "utf-8"
}]
]
}
},
methods: {
computed: {
formattedItems () {
if (!this.items || this.items.length === 0) return []
return this.items.map(item => {
return {
...item,
validitydate: item.validitydate === null ? null :
moment(item.validitydate).format('DD/MM/YYYY')
}
})
}
}
}
</script>
I need to do it for columns Authority, Status, Structure, Type and National.
For Authority: 1 - ITEM1, 2 - ITEM2, 3 - ITEM3
For Status: 1 - Status1, 2 - Status2, 3 - Status3
And so on.
Update:
I was wondering for using Map as a way to make it. However, I am not very sure how.
vue-good-table supports a column proprty called formatFn where you can format the data before it shows up on the column.
// in your columns
{
label: 'Authority',
field: 'authority',
type: 'String',
filterable: true,
placeholder: 'Authority',
formatFn: this.formatAuthority,
}
// in your methods
methods: {
formatAuthority(value) {
return `ITEM ${value}`;
}
}
you can see the documentation here:
https://xaksis.github.io/vue-good-table/guide/configuration/column-options.html#formatfn
I want to change a text field attribute in a specific row.
I have an editable dGrid with 5 fields, 2 of them are disabled and their values change when a select filed value is changed, now I want when the value of the select is changing to specific value, the two disabled filed are enabled for edit only for this row, and then be disabled again when choosing other values in the select, here's a screenshot of the grid
And here's the creation of the grid
this.productStore = new Memory({idProperty: 'id', data: []});
this.productObjStore = new ObjectStore({objectStore:
this.productStore});
var productColumn = {
field: 'productServiceId',
label: dojoConfig.i18n.productOrService,
className: 'hand',
editor: Select,
autoSave: true,
editorArgs: {
searchAttr: 'name',
labelAttr: "name",
style: 'width: 95%',
store: this.productObjStore,
required: true,
},
renderCell: function(object, data, td, options){
if(data != ''&& data != dojoConfig.i18n.addNewProduct){
td.innerHTML = this.editorArgs.store.get(data).label;
}
}
};
var quantityColumn = {
field: 'quantity',
label: dojoConfig.i18n.quantity,
className: 'hand',
editor: TextBox,
autoSave: true,
editorArgs: {
placeHolder: '#####',
regExp: dojoConfig.regExps.intExp,
trim: true,
style: 'width: 100%',
invalidMessage: dojoConfig.i18n.error_quantityIsZero,
validator: function(){
if( this.value > 0)
return true;
return false;
}
}
};
var me=this
var rateColumn = {
field: 'rate',
label: dojoConfig.i18n.rate,
className: 'hand',
editor: TextBox,
autoSave: true,
editorArgs: {
disabled: true,
placeHolder: '#####.##',
regExp: dojoConfig.regExps.floatExp,
trim: true,
style: 'width: 100%',
}
};
var amountColumn = {
field: 'amount',
label: dojoConfig.i18n.amount,
className: 'hand',
editor: TextBox,
editorArgs: {
disabled: true,
placeHolder: '#####.##',
regExp: dojoConfig.regExps.floatExp,
trim: true,
style: 'width: 100%',
}
};
this.discountStore = new Memory({idProperty: 'id', data: []});
var discountColumn = {
field: 'discount',
label: dojoConfig.i18n.lineDiscount,
className: 'hand',
editor: Select,
autoSave: true,
editorArgs: {
searchAttr: 'name',
labelAttr: "name",
style: 'width: 99%',
store: this.discountStore,
required: false,
value:null
},
renderCell: function(object, data, td, options){
if(data != '')
td.innerHTML = this.editorArgs.store.get(data).label;
}
};
this._grid = new Grid({
autoHeight: true,
showToolbar: true,
//label: dojoConfig.i18n.invoiceLines,
style: 'width: 100%; max-height: 200px; margin-top: 1px;',
columns : [
{field: 'id', label: 'ID', hidden: true, unhidable: true},
productColumn,
{field: 'description' ,label: dojoConfig.i18n.description, dismissOnEnter: false, editor: 'textarea', autoSave: true, renderCell: function(object, data, td, options){
td.innerHTML = data;
}},
quantityColumn,
rateColumn,
// discountColumn,
amountColumn,
{field: 'taxable', style:'width:50%', label: dojoConfig.i18n.taxable, editor: CheckBox, hidden: true, unhidable: true}
],
contextMenuInfo: [
{label: dojoConfig.i18n.new_, iconClass: 'newIcon', onClick: this.addProduct},
{label: dojoConfig.i18n.remove, iconClass: 'deleteIcon', onClick: this.deleteProduct, needSelection: true}
],
contextHandler: this,
selectionMode : 'single', // for Selection; only select a single row at a time
cellNavigation : false,
colspan: 5
});
this._grid.set('store', new Observable(new Memory({idProperty: 'id', data: []})));
Thanks