Row Ids not assigned with vue ag-grid - vue.js

I'm trying to have user-defined row-ids to prevent rerendering instead of Application assigned Ids as described in Vue ag-grid docs. However, unique row-ids are not getting assigned to the rows and the callback getRowId is not been called and it's adding the row-ids as 0,1,2,.....
From the documentation, it's not clear at which point in time the callback is called to assign the user-provided row-ids.
I'm using "vue": "^2.6.11" and "#ag-grid-community/vue": "^26.1.0"
Model
<template>
<div>
<template>
<ag-grid-vue
style="height: calc(100vh - 148px)"
class="ag-theme-balham"
:columnDefs="columnDefs"
#grid-ready="onGridReady"
:rowData="rowData"
:getRowId="getRowId"
></ag-grid-vue>
</template>
</div>
</template>
Script
<script>
export default {
name: "My-Component",
data() {
return {
columnDefs: [
{ headerName: "Row ID", valueGetter: "node.id" },
{ field: "id" },
{ field: "make" },
{ field: "model" },
{ field: "price" },
],
gridApi: null,
columnApi: null,
rowData: null,
getRowId: null,
};
},
created() {
this.rowData = [
{ id: "c1", make: "Lima", model: "Celica", price: 35000 },
{ id: "c2", make: "Ford", model: "Mondeo", price: 32000 },
{ id: "c8", make: "Porsche", model: "Boxster", price: 72000 },
{ id: "c4", make: "BMW", model: "M50", price: 60000 },
{ id: "c14", make: "Aston Martin", model: "DBX", price: 190000 },
];
this.getRowId = (params) => {
return params?.data.id;
};
},
};
</script>

I think you didn't read the ag-drid documentation clearly.
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<ag-grid-vue
style="height: calc(100vh - 148px)"
class="ag-theme-balham"
:columnDefs="columnDefs"
#onGridReady="onGridReady"
:rowData="rowData"
:getRowId="getId"
></ag-grid-vue>
</template>
<script>
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
import { AgGridVue } from "ag-grid-vue";
export default {
name: "App",
data() {
return {
columnDefs: [
{ headerName: "Row ID", valueGetter: "node.id" },
{ field: "make" },
{ field: "model" },
{ field: "price" },
],
gridApi: null,
columnApi: null,
rowData: null,
getRowId: null,
getId: (params) => {
return params.data.id;
},
};
},
components: {
AgGridVue,
},
created() {
this.rowData = [
{ id: "c1", make: "Lima", model: "Celica", price: 35000 },
{ id: "c2", make: "Ford", model: "Mondeo", price: 32000 },
{ id: "c8", make: "Porsche", model: "Boxster", price: 72000 },
{ id: "c4", make: "BMW", model: "M50", price: 60000 },
{ id: "c14", make: "Aston Martin", model: "DBX", price: 190000 },
];
},
methods: {
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
},
},
};
</script>
enter image description here

Related

vue doesn't update the child chart component in echart

I have built a vue component to show a PIE chart in echart library as showed below. The PIE chart will be initialized with a default value.
pieChart.vue
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
},
chartData: {
type: Object,
required: true
}
},
watch: {
chartData: function(val){
console.log('chartdata handler',val);
this.setOptions(val.legend, val.data);
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons');
this.setOptions(
['group_a','group_b','group_c'],
[
{ value: 1, name: 'group_a' },
{ value: 2, name: 'group_b' },
{ value: 3, name: 'group_c' },
]
);
},
setOptions( lengend, data ) {
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: lengend
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: '50%',
data: data,
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
});
}
}
}
</script>
then I use this component in a view.
<template>
<pie-chart :chartData="updateData"/>
</template>
<script>
export default {
name: 'Personalinforadm',
components: {
PieChart,
},
data() {
return {
updateData: {
data:[
{ value: 33, name: 'group_a' },
{ value: 17, name: 'group_b' },
{ value: 3, name: 'group_c' },
],
legend:['group_a','group_b','group_c']
}
}
},
created() {
this.updateData = {
data:[
{ value: 3, name: 'group_a' },
{ value: 17, name: 'group_b' },
{ value: 3, name: 'group_c' },
],
legend:['group_a','group_b','group_c']
}
}
}
</script>
however the view doesn't update the PIE chart component with the new values in created methods. why the new values doesn't pass to the PIE component and trigger the watch methods, any ideas what goes wrong with the code?
take a look at https://github.com/ecomfe/vue-echarts or solution below may help you.(if you use version >4.x)
sample.vue
<template>
//...
<v-chart
class="chart mt-7"
:option="botChartData"
:update-options="updateOpts"
/>
//...
</template>
<script>
export default {
data() {
return {
updateOpts: {
notMerge: true,
},
botChartData: {
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)",
},
series: [
{
name: "Active Bots",
type: "pie",
center: ["50%", "50%"],
radius: ["75%", "90%"],
itemStyle: {
borderRadius: 8,
},
data: [],
}
],
},
};
},
methods: {
connect() {
this.bots = [
{
value: 0,
name: "a",
},
{
value: 1,
name: "b",
},
{
value: 2,
name: "c",
},
];
this.botChartData.series[0].data = this.bots;
}
},
};
</script>
I called "connect" in "created" you can call it in mounted or on events!
if you need to set your chart as a child component you can easily pass this.botChartData like below
child.vue
<template>
<v-chart
class="chart mt-7"
:option="botData"
:update-options="updateConf"
/>
</template>
<script>
export default {
props: {
botChartData: {
type: Object
},
updateOpts: {
type: Object
}
},
computed: {
botData() {
return this.botChartData
},
updateConf() {
return this.updateOpts
}
}
};
</script>
in parent.vue
<template>
//...
<sample :botChartData="botChartData" :updateOpts="updateOpts" />
//...
</template>
<script>
//...the same as sample.vue js
</script>
By the way if you have multiple charts in one page dont forget notMerge then your charts will reinitialize after switching between them

Vuejs get dynamic form values

I have select and input component with made by buefy. Everything is ok till I realize how can I get the data.
I'm sort of new on vuejs. So I will be glad if you help me out.
I'm getting dynamic form from backend
So my question is how can get values these inputs and submit to backend again with getOffer() methot.
Here is my codes;
Input.vue
<template>
<b-field :label="fieldLabel">
<b-input
:name="inputName"
:type="inputType"
:maxlength="inputType == 'textarea' ? 200 : null"
></b-input>
</b-field>
</template>
<script>
export default {
name: "Input",
props: {
inputType: {
type: String,
required: true,
default: "text",
},
inputName: {
type: String,
required: true,
},
fieldLabel: {
type: String,
required: true,
}
}
};
</script>
Home.vue
<template>
<div class="container is-max-desktop wrapper">
<div v-for="element in offer" :key="element.id">
<Input
v-model="element.fieldValue"
:value="element.fieldValue"
:fieldLabel="element.fieldLabel"
:inputType="element.fieldType"
:inputName="element.fieldName"
v-if="element.fieldType != 'select'"
class="mb-3"
/>
<Select
v-model="element.fieldValue"
:fieldLabel="element.fieldLabel"
:options="element.infoRequestFormOptions"
:selectName="element.fieldName"
v-if="element.fieldType == 'select'"
class="mb-3"
/>
</div>
<b-button type="is-danger" #click="getOffer()">GET</b-button>
</div>
</template>
<script>
import axios from "axios";
import Select from "../components/Select.vue";
import Input from "../components/Input.vue";
export default {
name: "Home",
data() {
return {
offer: [],
};
},
components: {
Select,
Input,
},
methods: {
getOfferForm() {
axios({
method: "get",
url: `/GETDYNAMICFORM`,
})
.then((response) => {
this.offer = response.data;
})
.catch(() => {
this.$buefy.toast.open({
duration: 3000,
message: "oops",
position: "is-bottom",
type: "is-danger",
});
});
},
getOffer() {
console.log(this.offer);
},
},
created() {
this.getOfferForm();
},
};
</script>
Example Dynamic Form Response like;
[
{
"id": 58,
"fieldLabel": "Name Surname",
"providerLabel": "Name Surname",
"fieldName": "nmsrnm",
"fieldType": "text",
"fieldValue": null,
},
{
"id": 60,
"fieldLabel": "E-mail",
"providerLabel": "E-mail",
"fieldName": "e_mail_60",
"fieldType": "email",
"fieldValue": null,
},
{
"id": 2,
"fieldLabel": "Budget",
"providerLabel": "Budget",
"fieldName": "bdget",
"fieldType": "select",
"fieldValue": "",
"infoRequestFormOptions": [
{
"id": 1,
"orderNum": 0,
"optionValue": 0,
"optionText": "Select",
"minValue": null,
"maxValue": null
},
{
"id": 2,
"orderNum": 1,
"optionValue": 1,
"optionText": "10-30",
"minValue": 10,
"maxValue": 30
}
]
}
]

Error in mounted hook: "TypeError: Cannot read property 'type' of null"

I am using echarts to draw a Heatmap
But giving me error!!
Error in mounted hook: "TypeError: Cannot read property 'type' of null"
mounted() {
this.initChart()
},
I am using the json data from here:
https://www.echartsjs.com/data/asset/data/hangzhou-tracks.json
Just took 1 data from the above link.
<template>
<div
:id="id"
:class="className"
:style="{height:height,width:width}"
/>
</template>
<script>
import echarts from 'echarts'
import resize from '../mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'newCustomerForecastChart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
},
data() {
return {
chart: null,
dataArr: [
{
"coord":
[
120.14322240845,
30.236064370321
],
"elevation": 21
},
{
"coord":
[
120.14280555506,
30.23633761213
],
"elevation": 5
}
]
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
var points = [
{
"coord":
[
120.14322240845,
30.236064370321
],
"elevation": 21
},
{
"coord":
[
120.14280555506,
30.23633761213
],
"elevation": 5
}
]
this.chart = echarts.init(document.getElementById(this.id))
var colors = ['#5793f3', '#d14a61', '#675bba'];
this.chart.setOption({
animation: false,
bmap: {
center: [120.13066322374, 30.240018034923],
zoom: 14,
roam: true
},
visualMap: {
show: false,
top: 'top',
min: 0,
max: 5,
seriesIndex: 0,
calculable: true,
inRange: {
color: ['blue', 'blue', 'green', 'yellow', 'red']
}
},
series: [{
type: 'heatmap',
coordinateSystem: 'bmap',
data: points,
pointSize: 5,
blurSize: 6
}]
});
var bmap = myChart.getModel().getComponent('bmap').getBMap();
bmap.addControl(new BMap.MapTypeControl());
}
}
}
</script>
What is the problem actually?
should use
import * as echarts from 'echarts'
imstead of
import echarts from 'echarts'

vue js ag-grid filter component not working

I am quite new to vue-js and ag-grid, I would like to have a custom filter on my ag-grid so tried using component as filter as shown in vue-js ag-grid example: "https://www.ag-grid.com/javascript-grid-filter-component/" but its not working and giving "componentType is not a constructor" error in console.
Below is my code:
Gird:
<template>
<div class="all-devices" style="width: 100%; height: 425px;">
<ag-grid-vue
style="width: 100%; height: 100%;"
class="ag-theme-balham"
:gridOptions="gridOptions"
#grid-ready="onGridReady"
:columnDefs="columnDefs"
:defaultColDef="defaultColDef"
:rowData="rowData"
:frameworkComponents="frameworkComponents"
></ag-grid-vue>
</div>
</template>
<script>
import { AgGridVue } from "ag-grid-vue";
import PartialMatchFilter from "./PartialMatchFilter";
export default {
name: "AllDevices",
components: {},
data() {
return {
gridOptions: null,
columnDefs: null,
defaultColDef: null,
rowData: null,
frameworkComponents: null
};
},
components: {
AgGridVue
},
beforeMount() {
this.gridOptions = {};
this.columnDefs = [
{
headerName: "Row",
field: "row",
width: 450
},
{
headerName: "Filter Component",
field: "name",
width: 430,
filter: "partialMatchFilter"
}
];
this.rowData = [
{
row: "Row 1",
name: "Michael Phelps"
},
{
row: "Row 2",
name: "Natalie Coughlin"
},
{
row: "Row 3",
name: "Aleksey Nemov"
},
{
row: "Row 4",
name: "Alicia Coutts"
},
{
row: "Row 5",
name: "Missy Franklin"
},
{
row: "Row 6",
name: "Ryan Lochte"
},
{
row: "Row 7",
name: "Allison Schmitt"
},
{
row: "Row 8",
name: "Natalie Coughlin"
},
{
row: "Row 9",
name: "Ian Thorpe"
},
{
row: "Row 10",
name: "Bob Mill"
},
{
row: "Row 11",
name: "Willy Walsh"
},
{
row: "Row 12",
name: "Sarah McCoy"
},
{
row: "Row 13",
name: "Jane Jack"
},
{
row: "Row 14",
name: "Tina Wills"
}
];
this.defaultColDef = { filter: true };
this.frameworkComponents = { partialMatchFilter: PartialMatchFilter };
},
methods: {
onGridReady(params) {
params.api.sizeColumnsToFit();
}
}
};
</script>
<style>
</style>
Filter component:
<template>
<div>
<input style="height: 20px" :ref="'input'" v-model="text" />
</div>
</template>
<script>
export default {
name: "PartialMatchFilter",
data() {
return {
text: "",
valueGetter: null
};
},
methods: {
isFilterActive() {
return this.text !== null && this.text !== undefined && this.text !== "";
},
doesFilterPass(params) {
return (
!this.text ||
this.text
.toLowerCase()
.split(" ")
.every(filterWord => {
return (
this.valueGetter(params.node)
.toString()
.toLowerCase()
.indexOf(filterWord) >= 0
);
})
);
},
getModel() {
return { value: this.text };
},
setModel(model) {
if (model) {
this.text = model.value;
}
},
afterGuiAttached() {
this.$refs.input.focus();
},
componentMethod(message) {
alert(`Alert from PartialMatchFilterComponent ${message}`);
}
},
watch: {
text: function(val, oldVal) {
if (val !== oldVal) {
this.params.filterChangedCallback();
}
}
},
created() {
this.valueGetter = this.params.valueGetter;
}
};
</script>
Am I missing something? Please help! - Thanks
I had the same problem.
First, make this change in your columnDefs and get rid of frameworkComponents. Its just cleaner.
filter: "partialMatchFilter" -> filterFramework: PartialMatchFilter
Then the actual fix.
In your filter component add Vue.extend:
<template>
...
</template>
<script>
import Vue from "vue";
export default Vue.extend({
...
});
The example I followed -> https://github.com/ag-grid/ag-grid-vue-example/tree/master/src/rich-grid-example
Ref for Vue.extend -> https://v2.vuejs.org/v2/api/#Vue-extend

Vuejs2- How to do an inline alignment of a radio button in vue-form-generator?

Iam using "vue-form-generator" plugin for dynamic loading of form fields. Among the fields, I am using "radio-button" for the "gender" field. Options are displayed in one below the other but I want the option should be displayed in the "inline" style
How to align the radio button option in the same row(inline)?
Here is my code: addMember.vue
<template>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
<input type="submit" value="Submit">
</div>
</template>
<script>
import Vue from 'vue'
import VueFormGenerator from "vue-form-generator";
import "vue-form-generator/dist/vfg.css";
Vue.use(VueFormGenerator);
export default {
data: () => ({
model: {
building: "",
unitCategory: "",
unit: "",
fullName: "",
gender: "",
},
schema: {
groups: [{
fields: [{
type: "select",
inputType: "text",
label: "Building",
model: "building",
required: true,
styleClasses:'col-md-6',
values: [
{ id: "", name: 'Select Building' },
{ id: 'A', name: 'Block-A'},
{ id: 'B', name: 'Block-B'},
],
selectOptions: {
hideNoneSelectedText: true,
}
}]
},{
fields: [{
type: "select",
inputType: "text",
label: "Unit Category",
model: "unitCategory",
required: true,
styleClasses:'col-md-3',
values: [
{ id: "", name: 'Select Unit Category' },
],
selectOptions: {
hideNoneSelectedText: true,
}
},{
type: "select",
inputType: "text",
label: "Unit",
model: "unit",
required: true,
styleClasses:'col-md-3',
values: [
{ id: "", name: 'Select Unit' },
],
selectOptions: {
hideNoneSelectedText: true,
}
}]
},{
fields: [{
type: "input",
inputType: "text",
label: "Full Name",
model: "fullName",
placeholder: "Enter Full Name",
required: true,
styleClasses:'col-md-3'
},
{
type: "radios",
label: "Gender",
model: "gender",
values: [
"Male",
"Female",
"Other"
],
styleClasses:'col-md-3'
}]
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}),
}
</script>
You can add custom css to your radio input
{
type: "radios",
label: "Gender",
model: "gender",
values: [
"Male",
"Female",
"Other"
],
styleClasses:'col-md-3 display-inline'
}
and in your css
.display-inline label {
display: inline !important;
}
var vm = new Vue({
el: "#app",
components: {
"vue-form-generator": VueFormGenerator.component
},
data() {
return {
model: {
},
schema: {
fields: [{
type: "radios",
label: "Select your gender",
model: "friend",
values: [
"Male",
"Female",
"Others"
],
styleClasses: "display-inline"
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
};
}
});
.display-inline label {
display: inline !important;
}
<link href="https://cdn.jsdelivr.net/npm/vue-form-generator#2.2.2/dist/vfg.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue-form-generator#2.2.2/dist/vfg.min.js"></script>
<script src="https://unpkg.com/vue#2.2.1/dist/vue.min.js"></script>
<h1 class="text-center">Demo of vue-form-generator</h1>
<div class="container" id="app">
<div class="panel panel-default">
<div class="panel-heading">Form</div>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</div>
</div>
</div>