Answer the question
In order to leave comments, you need to log in
How to fix Invalid handler for event: got undefined Vue JS error?
The Laravel application with Vue.JS was inherited.
In the admin panel there is a table with orders with the ability to filter by values.
Initially, everything worked, but after a few commits, everything fell off.
Invalid handler for event "changed": got undefined
found in
---> <Calendar> at resources/assets/js/components/@shared/Calendar.vue
<TableFilterCell>
<Anonymous>
<Anonymous>
<DxTemplatePlaceholder>
<DxTemplateConnector>
<DxTemplatePlaceholder>
<Anonymous>
<TableRow>
<DxTemplatePlaceholder>
<Anonymous>
<RowLayout>
<Anonymous>
<RowsBlockLayout>
<Table>
<Anonymous>
<Anonymous>
<Anonymous>
<Anonymous>
<DxTemplateConnector>
<DxTemplatePlaceholder>... (1 recursive calls)
<Anonymous>
<DxTemplatePlaceholder>
<DxPluginHost>
<App> at resources/assets/js/components/orders/OrdersTable.vue
<Root>
<template>
<div>
<h3 v-if="company">{{company.name}}</h3>
<div class="card orders-table" v-if="!loading">
<dx-grid
:rows="rows"
:columns="columns"
>
<dx-sorting-state
:sorting.sync="sorting"
:columnExtensions="sortingStateColumnExtensions"
/>
<dx-integrated-sorting />
<dx-filtering-state
:filters.sync="filters"
:columnExtensions="filteringStateColumnExtensions"
/>
<dx-integrated-filtering />
<dx-table
:cellComponent="Cells"
:columnExtensions="tableColumnExtensions"
/>
<dx-table-header-row
showSortingControls
/>
<dx-table-filter-row
:cellComponent="FilterCell"
/>
</dx-grid>
</div>
</div>
</template>
<script>
import "@devexpress/dx-vue-grid-bootstrap4/dist/dx-vue-grid-bootstrap4.css";
import {
DxSortingState,
DxIntegratedSorting,
DxFilteringState,
DxIntegratedFiltering,
} from '@devexpress/dx-vue-grid';
import {
DxGrid,
DxTable,
DxTableHeaderRow,
DxTableFilterRow,
} from '@devexpress/dx-vue-grid-bootstrap4';
import moment from 'moment';
import swal from 'sweetalert2';
import { Actions, OrderId } from './comps';
import Calendar from '../@shared/Calendar';
const createComponent = (data, filter = null) => ({
props: ['column', 'row'],
template: `<dx-cell v-bind="$attrs" v-on="$listeners">${data}</dx-cell>`,
components: {
DxCell: filter ? DxTableFilterRow.components.DxCell : DxTable.components.DxCell,
Actions,
OrderId,
Calendar,
},
computed: {
changeStatus() {
return OrdersTable.methods.changeStatus;
},
onChange() {
return this.$parent.$parent.$parent.$parent.$parent.$parent
.$parent.$parent.$parent.$parent.$parent.$parent.$parent
.$parent.$parent.$parent.$parent.$parent.$parent.$parent.onChange; // todo i hope noone will see this crap
},
},
});
const createCells = (cells = {}, filter = null) => ({
inheritAttrs: false,
props: ['column', 'row'],
data() {
return {
componentId: cells[this.column.name] ? cells[this.column.name] : 'dx-cell',
}
},
template: `
<component
:is="componentId"
:column="column"
:row="row"
v-bind="$attrs"
v-on="$listeners"
/>
`,
components: {
DxCell: filter ? DxTableFilterRow.components.DxCell : DxTable.components.DxCell,
[this.componentId]: this.componentId,
}
});
const OrdersTable = {
name: "App",
props: ['companyJson'],
data() {
return {
loading: false,
user: {},
columns: [
{ name: "date", title: "Дата" }, // sortable: true
{ name: "time", title: "Время" },
{ name: "order", title: "№ заказа", getCellValue: row => row.id },
{ name: "price", title: "Сумма", getCellValue: row => row.price },
{ name: "phone", title: "Телефон", getCellValue: row => row.user.phone },
{ name: "email", title: "Email", getCellValue: row => row.user.email },
{ name: "actions", title: "Статус" },
{ name: "updated_at", title: "Изменено" },
],
rows: [],
tableColumnExtensions: [
{ columnName: 'date', width: 180 },
{ columnName: 'time', width: 80 },
{ columnName: 'order', width: 100 },
],
sorting: [],
sortingStateColumnExtensions: [
{ columnName: 'time', sortingEnabled: false },
{ columnName: 'actions', sortingEnabled: false },
],
filters: [],
filteringStateColumnExtensions: [
{ columnName: 'time', filteringEnabled: false },
{ columnName: 'actions', filteringEnabled: false },
{ columnName: 'updated_at', filteringEnabled: false },
],
filterCells: null,
};
},
components: {
DxSortingState,
DxIntegratedSorting,
DxFilteringState,
DxIntegratedFiltering,
DxGrid,
DxTable,
DxTableHeaderRow,
DxTableFilterRow,
},
computed: {
Cells() {
const data = {
price: createComponent(`{{row.price}} лей`),
phone: createComponent(`<a :href="'tel:'+row.user.phone">{{row.user.phone}}</a>`),
email: createComponent(`<a :href="'mailto:'+row.user.email">{{row.user.email}}</a>`),
order: createComponent(`<OrderId :order-id="row.id" />`),
actions: createComponent(`
<Actions
:changeStatus="changeStatus"
:row="row"
/>
`),
};
return createCells(data);
},
FilterCell() {
return createCells({
date: createComponent(`
<Calendar v-on:changed="onChange" />
`, true)
}, true);
},
company() {
return this.companyJson ? JSON.parse(this.companyJson) : null;
},
},
mounted() {
axios.get('/api/users/me').then((response) => {
this.user = response.data.data;
if (this.user.role === 2) {
this.columns.splice(3, 0, { name: "company", title: "Компания" });
this.loading = false;
}
});
const url = this.company ? `/api/users/${this.company.id}/orders` : '/api/orders';
axios.get(url)
.then(
response => this.rows = response.data.data
.map(item => ({
...item,
company: ((item.customer.company)
? item.customer.company.name
: 'NoName'),
date: moment(item.created_at, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD'),
time: moment(item.created_at, 'YYYY-MM-DD HH:mm:ss').format('HH:mm'),
})
)
);
},
methods: {
changeStatus: function (id) {
if (id === 4) {
swal({
title: 'Отменить заказ?',
text: 'Заполните причину отказа',
input: 'text',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
cancelButtonText: 'Отменить',
confirmButtonText: 'Подтвердить'
}).then((result) => {
if (result.value) {
axios.post(`/api/orders/${this.row.id}`, {
status_id: 4,
comment: result.value
}).then(response => {
if (response.data.status === 200) {
this.currentStatus = response.data.data.status;
}
});
}
});
}
else {
axios.post(`/api/orders/${this.row.id}`, {
status_id: id,
}).then(response => {
this.currentStatus = response.data.data.status;
this.row.updated_at = response.data.data.updated_at;
})
}
},
onChange(data) {
let value = null;
this.filters = this.filters.map(filter => filter.columnName !== 'date');
if(data) {
value = moment(data).format('YYYY-MM-DD');
console.log('DATE VALUE', value, this.filters);
this.filters = [...this.filters, { columnName: 'date', value }];
}
},
}
};
export default OrdersTable;
</script>
<style>
.orders-table {
overflow-x: auto;
}
.orders-table .table-responsive,
.orders-table .table,
.orders-table .dx-g-bs4-table-cell {
overflow: unset;
}
</style>
Answer the question
In order to leave comments, you need to log in
Here 's a similar problem:
In short, then:
1. Check the onChange function you're passing in v-on:change . There was just not about the top-level function, but about the function inside the component that called the function. There is at least one call to v-on:change 2 in this code . Check if the onChange
declaration is duplicated inside the component : for example, the onChange method and the computed onChange property are declared.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question