Given this columns array in a parent component:
columns = [
{ field: 'field1', title: 'Title 1', width: '100px' },
{ field: 'field2', title: 'Title 2', width: '200px' },
{ field: 'field3', title: 'Title 3' }
];
I can build a Kendo for Angular grid dynamically in a my-table component:
#Component({
selector: 'my-table',
template: `
<kendo-grid #grid="kendoGrid" [data]="data">
<kendo-grid-column
*ngFor="let column of columns"
field="{{column.field}}"
title="{{column.title}}"
width="{{column.width}}"
</kendo-grid-column>
</kendo-grid>
`
})
export class MyTableComponent {
#Input() data: any[] = [];
#Input() columns: any[] = [];
}
What I need is to programmatically add to the table a column that contains a button, where the button should execute a function in the parent component.
This is an example of the markup that should be rendered by MyTableComponent:
<kendo-grid-column>
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
<button kendoButton (click)="edit(dataItem,rowIndex)" [icon]="'edit'"></button>
</ng-template>
</kendo-grid-column>
MyTableComponent should receive from its parent the information in the columns array, something like this:
columns: [ { isButton: true, buttonLabel: 'Edit', callbackFunc: parentFunc } ];
Can a template be generated programmatically in the table component?
The scenario seems possible. You should add a cell template inside the column and use ngIf to render it only for button columns:
<ng-template *ngIf="column.isButton" kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
<button kendoButton (click)="column.callbackFunc(dataItem,rowIndex)" [icon]="column.icon">{{ column.buttonLabel }}</button>
</ng-template>
https://stackblitz.com/edit/angular-bzuy99?file=app/app.component.ts
Related
I am using this framework called Tabulator.
I add a column called Actions where users can perform viewing, editing and deleting records. Those buttons are shown but onclick events ain't working.
initTabulator() {
this.columns = [
{ title: "Name", field: "name", width: 150 },
{ title: "Status", field: "status", width: 150 },
{
title: "Actions",
formatter: function(value, data, type, params, component){
return `
<span class="border border-slate-300 hover:border-slate-400 bg-red-500" onclick="viewFunc()">View</span>
<button class="border border-slate-300 hover:border-slate-400 bg-blue-500">Edit</button>
<button class="border border-slate-300 hover:border-slate-400 bg-green-500">Delete</button>
`;
},
},
];
},
I am expecting that those buttons would trigger my functions, yet it alerts errors that my functions are not defined while in fact my functions are declared.
I would like to know if it is possible to use datatables (Metronic Laravel Theme) to display a 6*4 grid of user-images instead of displaying the images row-by-row (the standard datatable behavior). Anyone able to help?
ive just started on this so i don't want to waste a lot of time if it's not possible at all, this is what i have so far:
let members_datatable,
members_element = $('...');
members_datatable = members_element.MyCustomDataTable({
columns: [
{
field: 'id',
title: members_element.data('column-id'),
width: 50,
template: function (row) {
return row.id;
}
},
{
field: 'first_name',
title: members_element.data('column-name'),
width: 150,
template: function (row) {
let user_id = ...;
let user_company = ...;
let company_branche = ...;
return `<div class="mt-card-item">
<div class="mt-card-avatar mt-overlay-4">
<img src="storage/public/userImages/${user_id}.jpg">
<div class="mt-overlay">
<h2>${user_company}</h2>
<div class="mt-info font-white">
<div class="mt-card-content">
${company_branche}
</div>
</div>
</div>
</div>
</div>`;
}
},
],
});
I have a vue component which calls a load method returning a multi-part json object. The template of this vue is made up of several sub-vue components where I assign :data="some_object".
This works in all templates except for the one with a v-data-table in that the v-for process (or the building/rendering of the v-data-table) seems to kick-in before the "data" property is loaded.
With an npm dev server if I make a subtle change to the project which triggers a refresh the data-table then loads the data as I expect.
Tried various events to try and assign a local property to the one passed in via "props[]". Interestingly if I do a dummy v-for to iterate through or simply access the data[...] property the subsequent v-data-table loads. But I need to bind in other rules based on columns in the same row and that doesn't work.
Parent/main vue component:
...
<v-flex xs6 class="my-2">
<ShipViaForm :data="freight"></ShipViaForm>
</v-flex>
<OrderHeaderForm :data="orderheader"></OrderHeaderForm>
<v-flex xs12>
<DetailsForm :data="orderdet" :onSubmit="submit"></DetailsForm>
</v-flex>
...
So in the above the :data property is assigned from the result below for each sub component.
...
methods: {
load(id) {
API.getPickingDetails(id).then((result) => {
this.picking = result.picking;
this.freight = this.picking.freight;
this.orderheader = this.picking.orderheader;
this.orderdet = this.picking.orderdet;
});
},
...
DetailsForm.vue
<template lang="html">
<v-card>
<v-card-title>
<!-- the next div is a dummy one to force the 'data' property to load before v-data-table -->
<div v-show="false">
<div class="hide" v-for='header in headers' v-bind:key='header.product_code'>
{{ data[0][header.value] }}
</div>
</div>
<v-data-table
:headers='headers'
:items='data'
disable-initial-sort
hide-actions
>
<template slot='items' slot-scope='props'>
<td v-for='header in headers' v-bind:key='header.product_code'>
<v-text-field v-if="header.input"
label=""
v-bind:type="header.type"
v-bind:max="props.item[header.max]"
v-model="props.item[header.value]">
</v-text-field>
<span v-else>{{ props.item[header.value] }}</span>
</td>
</template>
</v-data-table>
</v-card-title>
</v-card>
</template>
<script>
import API from '#/lib/API';
export default {
props: ['data'],
data() {
return {
valid: false,
order_id: '',
headers: [
{ text: 'Order Qty', value: 'ord_qty', input: false },
{ text: 'B/O Qty', value: 'bo_qty', input: false },
{ text: 'EDP Code', value: 'product_code', input: false },
{ text: 'Description', value: 'product_desc', input: false },
{ text: 'Location', value: 'location', input: false },
{ text: 'Pick Qty', value: 'pick_qty', input: true, type: 'number', max: ['ord_qty'] },
{ text: 'UM', value: 'unit_measure', input: false },
{ text: 'Net Price', value: 'net_price', input: false },
],
};
},
mounted() {
const { id } = this.$route.params;
this.order_id = id;
},
methods: {
submit() {
if (this.valid) {
API.updateOrder(this.order_id, this.data).then((result) => {
console.log(result);
this.$router.push({
name: 'Orders',
});
});
}
},
clear() {
this.$refs.form.reset();
},
},
};
</script>
Hopefully this will help someone else who can't see the forest for the trees...
When I declared the data() { ... } properties in the parent form I initialised orderdet as {} instead of [].
I have a grid where i have Kendo Tabstrip in toolbar so outside this kendo tabstrip I want to add an export button that should work for all tabstrips. I have added a button but its not appearing in the grid. I am not sure what i am doing wrong. Please advise
So far I have tried this:
toolbar: [
{
template: kendo.template('<kendo-tabstrip><ul><li ng-class="{\'k-state-hover k-state-active\': defaultAllTab}">All</li>')
},
{
template: kendo.template('<li ng-class="{\'k-state-hover k-state-active\': defaultPendingTab}">Pending Review</li>')
},
{
template: kendo.template('<li ng-class="{\'k-state-hover k-state-active\': defaultReviewTab}">Reviewed</li></ul><kendo-tabstrip>')
},
{
template: ' <button class="k-grid-excel pull-right btn btn-default btn-sm">Export to Excel</button>'
}
],
excel: {
fileName: 'Subcategory.xlsx',
proxyURL: '/third-party-management/rest/xls/download',
allPages:true,
filterable: true
},
I am working on HTML5 and javascript.
Is it possible to add data and button in the same column in kendo grid.
Need help.
Also in view page, you can use ClientTemplate to achieve this:
#(Html.Kendo().Grid<ViewModel>().Name("grid")
.DataSource(src => src.Ajax().PageSize(10).Read(read => read.Action("Action", "Controller"))
.Columns(col =>
{
col.Bound(e => e.Name).ClientTemplate("<input type='button' value='CLICK' onclick='XYZ();'><label>#= (Name== null) ? ' ' : Name #</label>");
})
.Selectable()
.Scrollable()
)
Yes, it is! Simply use a template for it. Example:
Define the following template:
<script id="template" type="kendoui/template">
<button class="ob-click-me k-button">Click me</button>
<span>#= LastName #</span>
</script>
and the grid as:
var grid = $("#grid").kendoGrid({
dataSource: ds,
...
columns :
[
{ field: "FirstName", width: 90, title: "First Name" },
{
field: "LastName",
width: 200,
title: "Last Name",
template: $("#template").html()
}
]
}).data("kendoGrid");
You can see a running example even defining a handler for the button here: http://jsfiddle.net/OnaBai/qe3tf4tx/