Reset a const variable to its default value in vue - vue.js

How can I reset the value of my constant variable in vue? Here is what I meant:
data(){
const _hdrList = [
{
label: 'start_time',
value: 'start_time'
},
{
label: 'name',
value: 'name'
},
{
label: 'another',
value: 'another'
},
];
const _cboList = [
{start_time:''},
{name:''},
{another:''},
];
return{
hdrList:_hdrList,
headercbo:_cboList,
columns:[],
}
}
After that, I access it using the following:
<tr>
<th v-for="(col, index) in columns" :key="index.id">
<ui-select
:options="hdrList"
v-model="headercbo[index][hdrList[index]['label']]"
></ui-select>
</th>
</tr>
The output of this one is like this:
And when I click the clear button, this combo lists are not reverting back to default which it displays an empty or no selected value. Here's how I do it.
clearFields(){
this.columns = [];
this.headercbo = [];
}
But this one does not clear the fields, they still have the previous selected value with them. How can I totally clear them up and set backs to default.

Move the constant out of data.
During reset, you've reassign the default headercbo value with the constant value.
const _hdrList = [
{
label: 'start_time',
value: 'start_time'
},
{
label: 'name',
value: 'name'
},
{
label: 'another',
value: 'another'
},
];
const _cboList = [
{start_time:''},
{name:''},
{another:''},
];
export default {
data(){
return{
hdrList:_hdrList,
headercbo:_cboList,
columns:[],
}
},
clearFields() {
this.columns = [];
this.headercbo = _cboList;
}
}

Put what you have in your data function into a method named initialData, then use that function in your data function and in your clearFields method.
data() {
return this.initialData();
},
methods: {
initialData() {
const _hdrList = [{
label: 'start_time',
value: 'start_time'
},
{
label: 'name',
value: 'name'
},
{
label: 'another',
value: 'another'
},
];
const _cboList = [{
start_time: ''
},
{
name: ''
},
{
another: ''
},
];
return {
hdrList: _hdrList,
headercbo: _cboList,
columns: [1,2],
}
},
clearFields() {
this.columns = [];
this.headercbo = this.initialData().headercbo;
}
}

Related

Display Selected values in v-select multiple

I am new in vue js. Using vue2, I have a v-select implemented on my site now, I want to select multiple values and save and show them while editing. But I can't show multiple values properly using :reduce
Here is my code:
<v-select name="allowed_extensions"
:reduce="allowed_extensions => allowed_extensions.value"
multiple
:closeOnSelect="false"
v-model="form.allowed_extensions"
:options="file_options"
v-validate="'required'" > </v-select>
In js:
data () {
return {
isDisabled: false, //Submit Button
form: {
maximum_file_size: '',
allowed_extensions: ''
},
be_errors: {},
// Options
file_options: [
{ label: 'doc', value: 'doc' },
{ label: 'docx', value: 'docx' },
{ label: 'pdf', value: 'pdf' },
{ label: 'txt', value: 'txt' },
{ label: 'gif', value: 'gif' },
{ label: 'png', value: 'png' },
{ label: 'jpg', value: 'jpg' },
{ label: 'jpeg', value: 'jpeg' }
]
}
}
IN Mysql DB, sample data saved as : ["doc","txt"]
But when I want to display them in edit, it showing wrongly in a single tag.
How can I solve this

Vuex: getters return always initial value

I try to get the value of the vuex getters but I always get the initial value.
My Code:
export default {
state:{
transuser:{
Name: '1',
Email: '2',
Role: '3',
Email_Verified: '4',
Created:'5',
Updated:'6',
Edit_User:'7',
Delete_User:'8'
}
},
mutations:{
transusers(state,data) {
state.transuser.Name = data.Name ;
state.transuser.Email = data.Email ;
state.transuser.Role = data.Role ;
state.transuser.Email_Verified = data.Email_Verified;
state.transuser.Created = data.Created ;
state.transuser.Updated = data.Updated ;
state.transuser.Edit_User = data.Edit_User ;
state.transuser.Delete_User = data.Delete_User ;
return state.transuser;
}
},
getters:{
getTranslationUser(state){
return state.transuser
}
},
actions:{
loadTranslationUser(context){
axios.get("/t/gettransuser")
.then((response)=>{
context.commit("transusers",response.data);
})
.catch((error)=>{
console.log(error)
})
}
}
}
In my Component
mounted(){
this.$store.dispatch("loadTranslationUser");
},
I have a method
T(t)
{
return this.$store.getters.getTranslationUser[t];
}
Then I use it in my component:
columns: [
{
label: 'ID',
name: 'id',
orderable: true,
},
{
label: this.T('Name'),
name: 'name',
orderable: true,
},
etc....
But I get always the initial value 1,2,3,4,5 etc....
But if I do console.log(this.$store.getters.getTranslationUser) in my method T I see
{…}
Created: "Toegevoegd Op"
Delete_User: "Gebruiker Verwijderen"
Edit_User: "Gebruiker Aanpassen"
Email: "E-mail"
Email_Verified: "E-mail Geverifieerd"
Name: "Naam"
Role: "Rol"
Updated: "Aangepast Op"
So the correct values are there but I can't use them.
So what Am I doing wrong?
I believe you have columns in data field:
data() {
return {
columns: [...]
}
}
Move it to computed and it will pick up changes:
computed: {
columns() {
return [...]
}
}

Add extra field on items of <v-data-table>

I have medications object as follow:
medications: [
{
'name': 'abc',
'id': naks23kn,
'resident': //this is resident id, resident is another object
.........
},
{.......},.....
]
I wanted to add another field residentName on this object list or is there any way so that I can display 'residentName' in the v-data-table ?:
medications: [
{
'name': 'abc',
'id': naks23kn,
'resident': //this is resident id, resident is another object
'residentName': 'ad' //set this new field
.........
},
{.......},.....
]
I am using `v-data-table> as :
<v-data-table
:headers="headers"
:items="medications"
:items-per-page="20"
:search="search"
class="elevation-23"
>
Now I want to add an residentName field based on the resident field. For this I did the following:
export default {
data() {
return {
medications: [],
}
},
computed: {
...mapGetters([
'allMedications', //this is used to get all medication from medication store
'getResidentsById',
]),
},
created() {
this.get_resident_list(),
this.get_registered_medication_list();
},
methods: {
...mapActions([
'get_registered_medication_list', //this is used to call API and set state for medication
'get_resident_list', //this is used to callAPI and set state for resident
]),
getResidentName(id) {
const resident = this.getResidentsById(id)
return resident && resident.fullName
},
},
watch: {
allMedications: {
handler: function () {
const medicationArray = this.allMedications;
console.log("Created this");
this.medications = medicationArray.map(medication => ({
...medication,
residentName: this.getResidentName(medication.resident)
})
);
},
immediate: true
},
}
}
In header
headers: [
{ text: 'Medication Name', value: 'name' },
{ text: 'Resident', value: 'residentName' },
]
This is in resident.js getter module
getResidentsById: (state) => (id) => {
return state.residents.find(resident => resident.id === id)
}
Edit: This is working, i.e I am getting residentName when the page is created but if I refresh the page then I get residentName=undefined
You can use map to add new prop to your each item in array
let medications = [{
name: 'abc',
id: 'naks23kn',
resident: 1
}]
medications.map(item => item.residentName = "Your Resident Name")
console.log(medications)
This should work
watch: {
allMedications: {
handler: function() {
const medicationArray = this.allMedications;
console.log("Created this");
this.medications = medicationArray.map(medication => medication.residentName = this.getResidentName(medication.resident)));
},
immediate: true
},
}

How to combine Filtering, Grouping, and Sorting in Kendo UI Vue Grid (native)

I'm trying to enable some operations on my grid such as grouping, filtering and sorting, individually they works as shown in the docs but there is no an example of those functionality working together.
By myself I was able to combine sorting and filtering but grouping does not work when i'm adding it as it shown in the docs. look at at my code
<template>
<div>
<Grid :style="{height: '100%'}"
ref="grid"
:data-items="getData"
:resizable="true"
:reorderable="true"
#columnreorder="columnReorder"
:filterable="true"
:filter="filter"
#filterchange="filterChange"
:sortable="true"
:sort= "sort"
#sortchange="sortChangeHandler"
:groupable="true"
:group= "group"
#dataStateChange="dataStateChange"
:columns="columns">
</Grid>
</div>
</template>
<script>
export default {
data() {
return {
items: [],
editID: null,
columns: [
{ field: 'AbsenceEmployeID', filterable:false, editable: false, title: '#'},
{ field: 'Employe', title: 'Employer', cell: DropDownEmployes},
{ field: 'Remarque', title: 'Remarque'},
{ field: 'Type', title: 'Type', cell: DropDownTypes},
{ field: 'CreatedDate', filter:'date', editable: false, editor: 'date', title: 'créé le', format: '{0:d}'},
{ title: 'Actions', filterable:false, cell: CommandCell}
],
filter: {
logic: "and",
filters: []
},
sort: [
{ field: 'CreatedDate', dir: 'desc' }
],
group: [],
gridData: []
}
}
mounted() {
this.loadItems()
},
computed: {
absencesList() {
return this.items.map((item) => Object.assign({ inEdit: item.AbsenceEmployeID === this.editID}, item));
},
getData() {
return orderBy(filterBy(this.absencesList, this.filter), this.sort);
},
...mapState({
absences: state => state.absences.absences
})
}
methods: {
loadItems () {
this.$store.dispatch('absences/getAbsences')
.then(resp => {
this.items = this.absences.map(item => item)
})
},
filterChange: function(ev) {
this.filter = ev.filter;
},
columnReorder: function(options) {
this.columns = options.columns;
},
sortChangeHandler: function(e) {
this.sort = e.sort;
},
// the following is for grouping but not yet used, read more
groupedData: function () {
this.gridData = process(this.getData, {group: this.group});
},
createAppState: function(dataState) {
this.group = dataState.group;
this.groupedData();
},
dataStateChange: function (event) {
this.createAppState(event.data);
},
}
}
</script>
The last three methods are not used yet, so filtering and sorting is working perfectly as of now. then in other to enable grouping I want to replace :data-items="getData" by :data-items="gridData" and run this.groupedData() method after the items are loaded but grouping doesn't work.
I think everything should be handle by the dataStateChange event and process() function but I also tried but without success
If you define the filterchange and sortchange events they are being triggered for filter and sort and you will have to updated data in their handlers. If you rather want to use datastatechage event for all the changes you have to remove the filterchange and sortchange events and the datastatechage event will be triggered instead of them. In this case you will have to update the data in its handler.
You can use the process method of #progress/kendo-data-query by passing the respective parameter each data change that is needed as in the example below:
const result = process(data, {
skip: 10,
take: 20,
group: [{
field: 'category.categoryName',
aggregates: [
{ aggregate: "sum", field: "unitPrice" },
{ aggregate: "sum", field: "unitsInStock" }
]
}],
sort: [{ field: 'productName', dir: 'desc' }],
filter: {
logic: "or",
filters: [
{ field: "discontinued", operator: "eq", value: true },
{ field: "unitPrice", operator: "lt", value: 22 }
]
}
});
Hers is a sample stackblitz example where such example is working correctly - https://stackblitz.com/edit/3ssy1k?file=index.html
You need to implement the groupchange method to handle Grouping
I prefer to use process from #progress/kendo-data-query
The following is a complete example of this
<template>
<Grid :style="{height: height}"
:data-items="gridData"
:skip="skip"
:take="take"
:total="total"
:pageable="pageable"
:page-size="pageSize"
:filterable="true"
:filter="filter"
:groupable="true"
:group="group"
:sortable="true"
:sort="sort"
:columns="columns"
#sortchange="sortChangeHandler"
#pagechange="pageChangeHandler"
#filterchange="filterChangeHandler"
#groupchange="groupChangeHandler"
/>
</template>
<script>
import '#progress/kendo-theme-default/dist/all.css';
import { Grid } from '#progress/kendo-vue-grid';
import { process } from '#progress/kendo-data-query';
const sampleProducts = [
{
'ProductID': 1,
'ProductName': 'Chai',
'UnitPrice': 18,
'Discontinued': false,
},
{
'ProductID': 2,
'ProductName': 'Chang',
'UnitPrice': 19,
'Discontinued': false,
},
{
'ProductID': 3,
'ProductName': 'Aniseed Syrup',
'UnitPrice': 10,
'Discontinued': false,
},
{
'ProductID': 4,
'ProductName': "Chef Anton's Cajun Seasoning",
'UnitPrice': 22,
'Discontinued': false,
},
];
export default {
components: {
Grid,
},
data () {
return {
gridData: sampleProducts,
filter: {
logic: 'and',
filters: [],
},
skip: 0,
take: 10,
pageSize: 5,
pageable: {
buttonCount: 5,
info: true,
type: 'numeric',
pageSizes: true,
previousNext: true,
},
sort: [],
group: [],
columns: [
{ field: 'ProductID', filterable: false, title: 'Product ID', width: '130px' },
{ field: 'ProductName', title: 'Product Name' },
{ field: 'UnitPrice', filter: 'numeric', title: 'Unit Price' },
{ field: 'Discontinued', filter: 'boolean', title: 'Discontinued' },
],
};
},
computed: {
total () {
return this.gridData ? this.gridData.length : 0;
},
},
mounted () {
this.getData();
},
methods: {
getData: function () {
this.gridData = process(sampleProducts,
{
skip: this.skip,
take: this.take,
group: this.group,
sort: this.sort,
filter: this.filter,
});
},
// ------------------Sorting------------------
sortChangeHandler: function (event) {
this.sort = event.sort;
this.getData();
},
// ------------------Paging------------------
pageChangeHandler: function (event) {
this.skip = event.page.skip;
this.take = event.page.take;
this.getData();
},
// ------------------Filter------------------
filterChangeHandler: function (event) {
this.filter = event.filter;
this.getData();
},
// ------------------Grouping------------------
groupChangeHandler: function (event) {
this.group = event.group;
this.getData();
},
},
};
</script>

Datatables get value of searchable on a column

I have created a datatable with following code:
userTable = $('#userTable').DataTable({
serverSide: true,
processing: true,
ajax: {
url: "{!! route('listOfUsersAjax') !!}",
type: "GET",
dataSrc: function ( json ) {
//console.log(json);;
for ( var i=0, ien=json.data.length ; i<ien ; i++ ) {
if (json.data[i].is_manager == 1){
json.data[i].is_manager = 'Yes';
}
else {
json.data[i].is_manager = 'No';
}
}
return json.data;
}
},
columns: [
{
className: 'details-control',
orderable: false,
searchable: false,
data: null,
defaultContent: ''
},
{ name: 'id', data: 'id' },
{ name: 'name', data: 'name' },
{ name: 'email', data: 'email' },
{ name: 'is_manager', data: 'is_manager'},
{ name: 'region', data: 'region' },
{ name: 'country', data: 'country' },
{ name: 'domain', data: 'domain' },
{ name: 'management_code', data: 'management_code' },
{ name: 'job_role', data: 'job_role' },
{ name: 'employee_type', data: 'employee_type' },
{
name: 'actions',
data: null,
sortable: false,
searchable: false,
render: function (data) {
var actions = '';
actions += '<div class="btn-group btn-group-xs">';
actions += '<button data-toggle="tooltip" title="view" id="'+data.id+'" class="buttonView btn btn-success"><span class="glyphicon glyphicon-eye-open"></span></button>';
actions += '<button data-toggle="tooltip" title="edit" id="'+data.id+'" class="buttonUpdate btn btn-primary"><span class="glyphicon glyphicon-pencil"></span></button>';
actions += '<button data-toggle="tooltip" title="delete" id="'+data.id+'" class="buttonDelete btn btn-danger"><span class="glyphicon glyphicon-trash"></span></button>';
actions += '</div>';
return actions;
}
}
],
columnDefs: [
{
"targets": [1,3,4], "visible": false, "searchable": false
}
],
order: [[2, 'asc']],
initComplete: function () {
this.api().columns().every(function () {
var column = this;
//console.log(userTable);
// Now we need to skip the first column as it is used for the drawer...
if(column[0][0] == '0' || column[0][0] == '11'){return true;};
var input = document.createElement("input");
$(input).appendTo($(column.footer()).empty())
.on('keyup change', function () {
column.search($(this).val(), false, false, true).draw();
});
});
}
} );
At the end, you can see that I have put a initComplete to have search columns to be at the bottom of each column.
I don't need to have a search when the column is not searchable, for example, first column and last one because it is not searchable. I am using the number of the column and returning true so that it doesn't create it but I would like something more dynamic and have an if column searchable is false then return true that way I don't need to specify the number of the column.
Thanks for your help.
You do have the columns definition available through this.api().init().columns. So all you have to do is to evaluate if a columns searchable explicit is set to false (not defining searchable or not defining the column at all means true, since this is the default) :
initComplete: function() {
var columns = this.api().init().columns;
this.api().columns().every(function(index) {
if (!columns[index] || columns[index].searchable) {
// column is searchable
} else {
// column is not searchable
}
})
}