How to use Vue Component on custom formatter in Vue 3 - vue.js

newbie in vuejs.
I'm trying to use tabulator data-table for data and used Custom Formatters. But unable to return Vue component.
How to return Vue component on custom formatter Vue3?
<script>
import BaseLink from "#/components/BaseLink.vue";
export default {
data() {
return {
switch1: false,
columns: [
{
rowHandle: true,
formatter: "handle",
headerSort: false,
frozen: true,
width: 30,
minWidth: 30,
},
{ title: "ID", field: "id", editor: "input" },
{ title: "Name", field: "name" },
{ title: "Email", field: "email" },
{
title: "Status",
field: "status",
formatter: function (cell, formatterParams, onRendered) {
//cell - the cell component
//formatterParams - parameters set for the column
//onRendered - function to call when the formatter has been rendered
return `<v-switch v-model="switch1" />`;
},
},
{
title: "Action",
field: "id",
formatter: function (cell, formatterParams, onRendered) {
//cell - the cell component
//formatterParams - parameters set for the column
//onRendered - function to call when the formatter has been rendered
return `<BaseLink to="/members/${cell.getValue()}/details">Details</BaseLink>`;
},
},
],
};
},
};
</script>
Thank in advance!

Related

Vue2 trying to set chart title

Does not work like this:
<template>
<Bar
:chart-options="chartOptions"
:chart-data="$attrs['chart-data'] || chartData"
:chart-id="chartId"
:dataset-id-key="datasetIdKey"
:plugins="plugins"
:css-classes="cssClasses"
:styles="styles"
:width="width"
:height="height"
/>
</template>
<script>
import { Bar } from 'vue-chartjs/legacy'
import 'chart.js/auto'
export default {
name: 'BarChart',
components: { Bar },
props: {
chartId: {
type: String,
default: 'bar-chart',
},
datasetIdKey: {
type: String,
default: 'label',
},
width: {
type: Number,
default: 400,
},
height: {
type: Number,
default: 400,
},
cssClasses: {
default: '',
type: String,
},
styles: {
type: Object,
default: () => {},
},
plugins: {
type: Object,
default: () => {},
},
},
data() {
return {
chartData: {},
chartOptions: {
responsive: true,
title: {
display: true,
text: 'Custom Chart Title',
},
},
}
},
}
</script>
tried editing even with this: https://codesandbox.io/s/exciting-ully-2wst65?file=/src/components/Bar.vue
but nothing works.
All info gathered from: https://vue-chartjs.org/api/
Registration of components are not needed if you import auto.
maybe some ideas?
You are using v2 syntax in v3, the internal plugins like the tooltip, title, legend and decimation have been moved from the options namespace to the options.plugins namespace.
So you need to nest the title options in a plugins object within the options object. Then it will work
For those like me, who are looking for a solution using vue-chartjs V4.
To show the Title you need to pass the plugin object, for example:
plugins: {
type: Array,
default: () => [Title]
}
and then pass into the chartOptions props the title configuration, for example:
chartOptions: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: "Chart Title",
},
},
}
sandBox full example:

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

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>

how to dynamically load a vue-form-generator schema?

I need to dynamically load (part of) a form schema asynchronously.
For example, I want to create the schema after a REST call.
I started using vue-form-generator,
I tried to manipulate the schema creating a component that:
creates a text input with a label Name-TEST-failed
asynchronously call a function that changes the label in Name-TEST-success
Code:
<template>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</div>
</template>
<script>
import Vue from 'vue';
import VueFormGenerator from "vue-form-generator";
Vue.use(VueFormGenerator);
export default {
created(){
setTimeout(() => {
console.log("start!");
Vue.set(this.$data.schema.fields,
[{
type: "input",
inputType: "text",
label: "Name-TEST-success",
model: "name",
placeholder: "Your name",
featured: true,
required: true
}]
)
console.log("end!");
}, 1000);
},
data() {
return {
model: {
name: "John Doe"
},
schema: {
fields: [{
type: "input",
inputType: "text",
label: "Name-TEST-failed",
model: "name",
placeholder: "Your name",
featured: true,
required: true
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}
}
}
</script>
both the messages start! and end! appear in the console, but the label of the input test does not change.
How can I change the schema (and the model) dynamically?
Just put the schema in a computed property and make it dependant on a data property. So the schema will change everytime you change a property on which it depends.
export default {
created(){
setTimeout(() => {
console.log("start!");
this.labelName = "Name-TEST-success"
}, 1000);
},
data() {
return {
model: {
name: "John Doe"
},
// Add a new property that you can change as you wish
labelName: 'Name-TEST-failed",
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}
},
computed: {
schema () {
var result = {
fields: [{
type: "input",
inputType: "text",
label: this.labelName,
model: "name",
placeholder: "Your name",
featured: true,
required: true
}]
}
return result
}
}
}
UPDATE:
You don't need computed properties, they can lead to problems with validity check. Just manipulate the properties direclty.
PS: The $set method needs an index to work correct on arrays.
export default {
created(){
setTimeout(() => {
console.log("start!");
this.fieldObject.label = "Name-TEST-success"
}, 1000);
},
data() {
var fieldObject = {
type: "input",
inputType: "text",
label: this.labelName,
model: "name",
placeholder: "Your name",
featured: true,
required: true
}
return {
fieldObject, // now you can change label with "fieldObject.label = ..."
model: {
name: "John Doe"
},
schema: {
fields: [fieldObject]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}
}
}

Bind KendoUI grid with Model data in MVC 4

For example, I have a view with model IEnumerable<Correspondence>. I want to bind it to KendoUI grid. What should I do? I've tried
#model IEnumerable<Correspondence>
<div id="Correspondence"></div>
<script>
$(document).ready(function () {
$('#Correspondence').kendoGrid({
dataSource: {
data: #Html.Raw(Json.Encode(Model)),
editable: { destroy: true },
batch: true,
pageSize: 15,
schema: {
model: {
id: "Id",
fields: {
Subject: { type: "string" },
CorrespondenceType: { type: "number" },
SentDate: { type: "date" }
}
}
}
},
navigatable: true,
selectable: "row",
filterable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true
},
columns: [
{
title: "Subject",
field: "Subject"
},
{
title: "Type",
field: "CorrespondenceType"
},
{
title: "Sent Date",
field: "SentDate",
format: "{0:MM/dd/yyyy}"
},
{
command: [{ name: "openCorrespondence", text: "Open", className: "k-grid-openLaboratory", imageClass: "k-icon k-i-maximize", click: Open },
{ name: "deleteCorrespondence", text: "Delete", className: "k-grid-deleteLaboratory", imageClass: "k-icon k-delete", click: Delete },
{ name: "EditCorrespondence", text: "Edit", className: "k-grid-editLaboratory", imageClass: "k-icon k-edit", click: Edit }],
title: "Action"
}
]
});
}); // end ready
</script>
But it doesn't work. The table even doesn't show up. Please help me. Thank you.
Edited!!!
I have solved my own problem. Because I used command column, so I have to add 3 functions: Open, Edit, and Delete. Then, the grid showed successfully.