CellValueChanged event in master detail of ag-grid - javascript

I am developing an ag-grid with master-detail set to true, the first row of master-detail has a editable cell i.e. "contractID", I want to populate other cells of the master-detail depending upon the fetched contractID.
I tried adding cellValueChanged in the columnDef and also tried to set params.api.rowModel.gridApi.cellValueChanged explicitly in onFirstDataRendered method for the detailGrid, but found no luck.
Master detail grid code:
detailCellRendererParams = {
detailGridOptions: {
columnDefs: [
{ headerName: "Contact ID", field: "contractId", editable: true, [cellValueChanged]: "cellValueChanged()" },
{ headerName: "Contact Name", field: "contractName" },
{ headerName: "Category", field: "category" }]
}
}
onFirstDataRendered(params) {
params.api.rowModel.gridApi.cellValueChanged = function (params) {
console.log("cellChanged");
}
}

In case someone still wonders, in detailGridOptions add:
onCellValueChanged: function ($event) {
// your code here
},
This will be triggered every time you change cell value.

Fixed the problem using custom cellRenderer and added an eventListener for change event. I just wanted to have this functionality on the first row of the grid, so added a condition to the rowIndex.
detailCellRendererParams = {
detailGridOptions: {
columnDefs: [{headerName: "Contact ID",field: "contractId",editable: true,
cellRenderer: (params) => {
params.eGridCell.addEventListener('change', (e) => {
this.getDetails(e.target.value);
})
},
{headerName: "Contact Name", field: "contractName"},
{headerName: "Category",field: "category"}]
}
}
getDetails(id): void {
this.apiService.getDetails(id)
.subscribe(result => {
this.gridApi.detailGridInfoMap.detail_0.api.forEachNode(node=> {
if(node.rowIndex == 0){
node.data = result;
node.gridApi.refreshCells();
}}
);
})}

Related

VueGoodTable filter dropdown options vue2

I'm trying to populate possible dropdown options on vue good table. The idea is that I conduct an API call to the server to bring back what values can possibly go into the drop down and I'm trying to assign it to the column filter. However, I can't seem to get it to work.
<vue-good-table
:paginationOptions="paginationOptions"
:sort-options="sortOptions"
:isLoading.sync="isTableLoading"
:rows="rows"
:columns="columns"
:lineNumbers="true"
mode="remote"
:totalRows="totalRecords"
#on-row-click="onRowClick"
#on-page-change="onPageChange"
#on-sort-change="onSortChange"
#on-column-filter="onColumnFilter"
#on-per-page-change="onPerPageChange"
#on-search="onSearch"
:search-options="{
enabled: true
}"
styleClass="vgt-table striped bordered"
ref="table"
>
Fairly standard vgt set up.
columns: [
{
label: 'some column',
field: 'column1'
},
{
label: 'Customer',
field: 'customerName',
filterOptions: {
enabled: true,
placeholder: 'All',
filterDropdownItems: Object.values(this.customers)
}
},
{
label: 'other columns',
field: 'column234'
}
]
and the API call
methods: {
async load () {
await this.getTableOptions()
},
async getTableOptions () {
try {
var response = await axios.get(APICallUrl)
this.customers= []
for (var i = 0; i < response.data.customers.length; i++) {
this.customers.push({ value: response.data.customers[i].customerId, text: response.data.customers[i].customerName})
}
} catch (e) {
console.log('e', e)
}
}
The only thing that I thought of is that the table has finished rendering before the load method is complete. However just creating a static object in my data and assigning it to a filterDropDownItems yielded no better results. The result whenever I try to set it to an object is that the box is a type-in box rather than a dropdown.
You can make the table update after it's rendered by making columns a computed property. The other problem you have is this.customers is an Array but Object.values() expects an Object. You could use the Array.map function instead
this.customers.map(c => c.value)
Although according to the VueGoodTable docs an array of objects like you have should work just fine
computed: {
columns() {
return [
{
label: 'some column',
field: 'column1'
},
{
label: 'Customer',
field: 'customerName',
filterOptions: {
enabled: true,
placeholder: 'All',
filterDropdownItems: this.customers
}
},
{
label: 'other columns',
field: 'column234'
}
];
}
}

AG-Grid Master Detail Can not See Detail Rows

In my code, I am using AG-Grid with the master detail property to display some data. The code doesn't get any errors and the master row has records, but when I expand the detail, not 1 row is present even though in the network, params.data has values. My code is below. What am I doing wrong, and how should I fix it?
constructor(
private _reportService: ReportService,
) {
this._reportService
.getAllSupplierProductList()
.subscribe((response: any) => {
this.rowData = response;
});
}
public detailCellRendererParams: any = {
detailGridOptions: {
columnDefs: [
{ headerName: 'Ürün Kodu', field: 'StockIntegrationCode' },
{ headerName: 'Ürün Adı', field: 'ProductName' },
{ headerName: 'Ürün Kategorisi', field: 'CategoryName' },
],
defaultColDef: {
flex: 1,
filter: 'agTextColumnFilter',
resizable: true,
sortable: true,
floatingFilter: true,
},
},
getDetailRowData: (params) => {
params.successCallback(params.data.StockIntegrationCode && params.data.ProductName && params.data.CategoryName);
},
} as IDetailCellRendererParams;
rowData: Observable<IReportRow[]>;
onFirstDataRendered(params: FirstDataRenderedEvent) {
// arbitrarily expand a row for presentational purposes
setTimeout(function () {
params.api.getDisplayedRowAtIndex(1)!.setExpanded(true);
}, 0);
}
onGridReady(params: GridReadyEvent) {
}
In the getDetailRowData function, you're given params.data, which is the data of the master row. You should obtain details and pass it to the params.successCallback function like this:
getDetailRowData: (params) => {
this._reportService
.getProductList(params.data.SupplierId)
.subscribe(products => {
params.successCallback(products);
});
}

Store calculated data in Column of Kendo Grid

What I'm trying to do is store some data in a specific column that is calculated by using the data from another column.
I currently have a function that returns the number of available licenses for the given Id in JSON
function getAvailableLicenses(id) {
var url = "/Host/Organization/AvailableLicenses/" + id;
$.get(url, function (data) {
return data.AvailableLicenses;
});
}
How do I go about storing this number in a column named "AvailableLicenses"?
Here is my current Grid:
$("#OrganizationGrid").kendoGrid({
dataSource: viewModel.get("orgDataSource"),
filterable: {
extra: false
},
sortable: true,
pageable: true,
columns: [
{ field: "Id", hidden: true },
{ field: "Name", template: "<a href='/Host/Organization/Detail/#:Id#'>#:Name#</a>" },
{ field: "LicenseNumber", title: "Number of Licenses" },
{ field: null, title: "Available Licenses", template: "#= getAvailableLicenses(Id) #" },
{ field: "LicenseExpiration", title: "License Expiration", format: "{0:MM/dd/yyyy}" },
{ field: "State" },
{ field: "Active" }
],
editable: false
});
As you can see, I tried to create a null column with a template that calls the function for the given Id.
By using Fiddler I can see that the function is indeed being called for all of the rows, but the AvailableLicenses column just displays Undefined for every row.
Is there something I'm missing here to get this to work?
I think the better way to do this is on dataSource parse() function
First: you column configuration must change like this:
{ field: "AvalableLicenses", title: "Available Licenses" },
You alaways can use you template .
And second, inside your dataSource() you can add:
schema: {
parse: function(response) {
for (var i = 0; i < response.length; i++) {
response[i].AvalableLicenses= null;
response[i].AvalableLicenses = getAvailableLicenses(response[i].Id)
}
return response;
}
}
EDIT:
If you prefer using you way, I dont see any problem in your configuration, probably your $.get is returning undefined, or something you don't expect.
For conviniance I did an example working.
http://jsfiddle.net/jwocf897/
Hope this help

DGrid Editor - Changing the Displayed Value when Trying to Edit a Text Cell

I'm using a DGrid editor column to edit the contents of a store. Of the fields that I want to be able to edit, one is an object. When I click on the field to edit it, what I want is for the value displayed in the editor to match the value displayed by the grid when not editing. The cell formatting just shows the value of the object, but when I click on the field to edit it, instead of the object's value, I instead the field is populated with '[object Object]'. I can still edit it (though the results of doing so is that the field will display 'undefined' until I refresh the page, but I could just force a refresh after the change), but can't seem to get it to show what I want.
Here's the set up code:
// build the store
this.postStore = Observable(Memory({
data: posts
}));
var formatCategory = function(object, data, cell) {
cell.innerHTML = object.category.value;
};
var formatAuthor = function(object, data, cell) {
cell.innerHTML = object.author.value;
};
var formatDate = function(object, data, cell) {
cell.innerHTML = new Date(object.dateCreated).toISOString();
};
// the columns displayed in the grid
var columns = [
selector({
field: 'checkbox',
label: ' ',
selectorType: 'radio',
width:33
}),
{
label: "Author",
field: "author",
width: 120,
renderCell: formatAuthor
},
editor({
label: "Title",
field: "title",
editor: "text",
editOn: "click",
width: 200
}),
editor({
label: "Text",
field: "text",
editor: "text",
editOn: "click",
width:500
}, Textarea),
editor({
label: "Category",
field: "category",
editor: "text",
editOn: "click",
width: 150,
renderCell: formatCategory
}),
{
label: "Date",
field: "date",
renderCell: formatDate,
width: 120
}
];
if (this.postGrid) {
this.postGrid.set("store", this.postStore);
} else {
var SelectionGrid = new declare([OnDemandGrid, Selection, Keyboard, editor, selector, DijitRegistry, ColumnResizer]);
this.postGrid = new SelectionGrid({
store: this.postStore,
columns: columns,
selectionMode: 'none',
sort: [{attribute: "date", descending: false}]
}, this.postGridDiv);
this.postGrid.startup();
this.postGrid.on("dgrid-select, dgrid-deselect", lang.hitch(this, this._postSelected));
this.postGrid.on("dgrid-datachange", lang.hitch(this, function(evt){
var cell = this.postGrid.cell(evt);
var post = cell.row.data;
if (cell.column.field === "title") {
post.title = evt.value;
} else if (cell.column.field === "text") {
post.text = evt.value;
} else if (cell.column.field === "category") {
post.category.value = evt.value;
}
this._updatePost(post);
}));
Instead of defining a renderCell function, define a get function (which is used to transform the value before it is even sent to renderCell) and a set function (which is used to transform data back before it's sent to a store when saving edits).
Something like:
get: function (object) {
return object.category.value;
},
set: function (object) {
return { value: object.category };
}
See also the documentation.

Kendo Grid keydown event

I have initiated a Kendo Grid using Kendo directives. How do I catch the keydown/keypress event of the grid? My final objective is to populate a grid column based on user input of another column. For example, populate the phone number when the first name is entered. For that I believe I have to use the Kendo Grid edit and the keypress events and do a search on the user input, unless there's a better way to do it. Is this possible?
This is how I initialized the grid:
<section id="dashboard-view" class="mainbar" data-ng-controller="dashboard as vm">
....
<div kendo-grid="vm.testGrid" k-options="vm.testGridOptions" k-rebind="vm.testGridDataSource.data" k-on-edit="vm.onEdit(kendoEvent)"></div>
....
</section>
Options defined in my JavaScript file:
vm.testGridOptions = {
columns: [
{ field: "Id", title: "ID" },
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" },
{ field: "Phone", title: "Phone" },
{ command: ["destroy"] }
],
toolbar: ["create", "save", "cancel"],
dataSource: vm.testGridDataSource,
editable: {
createAt: "bottom"
},
height: 400,
autoBind: false
};
vm.onEdit = function (e) {
//if grid column == Id && keypressed == Tab key
//search
};
The grid is on batch edit mode.
You can find current column/field name based on the index. Then filter the dropdown present in column next to it: (this is just a sample code, please replace DOM ids with your code)
vm.onEdit = function (e) {
var header = vm.thead;//grid header
var index = vm.cellIndex(e.container);//current cell index
var th = $(header).find("th").eq(index);
var colName = $(th).data("field");//fieldname for current cell
var dataItem = e.model;//row model
if(colName=='LastName')
{
var phoneDropDown = e.container.find("#PhoneDropDownId").data("kendoDropDownList");
if (phoneDropDown) {
phoneDropDown.dataSource.filter({ field: "Phone", operator: "eq", value: e.model.LastName });
}
}
};
Since the Kendo Grid doesn't have a native event for this I used the JQuery onBlur event.
vm.onEdit = function (e) {
alert("Edit event fired");
$('input.k-input.k-textbox').blur(function (f) {
alert("Blur event fired");
}
};

Categories

Resources