I am looking for a way to see which column the rowClick event has happened.
Because based on which column this happend we want other things to happen.
We already got something like this:
this.chart.listen('rowClick', (event) => {
if (event['period'] && event['period'].itemType === GanttItemType.work) {
setTimeout(() => this.clickedDetail(event), 1);
} else if (event['item'] && event['item'].get('technicianId') && !event['period']) {
// HERE WE WANT TO KNOW IN WHICH COLUMN WE ARE
const technicianId = event['item'].get('technicianId');
setTimeout(() => this.openTechnician(technicianId), 1);
} else {
this.preventDef(event);
}
});
Thanks in advance I cannot seem to find if/where this is possible
Unfortunately, there's no out-of-the-box method to implement such functionality, so it requires some tricks.
The idea is quite simple – if dataGrid columns width is predefined we can compare the click X-coordinate and the column width. For details, check the sample by the link provided in the comment below.
Related
We have an Ag-Grid table with row selection via the built in checkbox functionality. The check boxes are conditionally displaying via the isRowSelectable options:
isRowSelectable: function (rowNode) {
return rowNode.data ? rowNode.data.published === false : true;
}
The published column is being updated as part of a modal called from another column. A redrawRows is being called when the modal is closed:
modal.result.then(() => {
const row = params.api.getDisplayedRowAtIndex(params.rowIndex as number);
//this.gridApi?.redrawRows([row] as any);
this.gridApi?.redrawRows();
});
The display values in the row are being updated when the modal is closed, however, the checkbox is not appearing when the published value is set to false. If I hang a breakpoint in Dev Tools the isRowSelectable code does not appear to be hit.
Any suggestions would be much appreciated.
Cheers,
-John
Can you try this and see if it works?
let itemsToUpdate = [];
let data = rowNode.data;
// modify data fields
// Ex: data.field1 = "new value";
itemsToUpdate.push(data);
this.gridApi.applyTransaction({update: itemsToUpdate});
https://www.ag-grid.com/javascript-data-grid/data-update-transactions/
Use refreshCells
this.gridApi?.refreshCells({force:true});
https://www.ag-grid.com/react-data-grid/view-refresh/#redraw-rows
On reactJS ag-grid, I need to be able to edit a cell on double clicking. I tried the following code. I do not see any error message popping up. But the cell is still read-only.
Am I missing something here please?
Thanks.
function myTest(props)
{
const[gridApi, setGridApi] = userState(null);
...
...
const onCellDoubleClicked = (params) =>
{
gridApi.startEditingCell({rowIndex: params.node.id, colKey: "testField"});
}
const onGridReady = (params) =>
{
setGridApi(params.api);
}
....
...
{headerName:'Test', field:'testField', editable:false};
<AgGridReact columnDefs={...} rowData={...} onCellDoubleClicked=
{onCellDoubleClicked} onGridReady={onGridReady}>
}
Tough to say without seeing your coldef - I'd venture that you need to set the column(s) whose cells you want to be editable to true. See the docs below
Cell Editing
Add editable: true property in your column defs
I have been searching the internet for answer but I am not having any luck. I would like to know if it is possible to only show Kendo detail rows after 19 rows of data? I have a very odd requirement and I'm not sure it can be done. However if there is a solution out there, is there a small example I can see? Or a resource I have not found yet?
As a note a side note I am using Kendo with AngularJS.
Thank you in advance!
AnthonyFastcar
This may not be the best way to do this but I just hid the detail icon for the rows. I used the dataBound event.
dataSource: yourDataSouce,
dataBound: function(e) {
var grid = this,
grid2 = $('#yourGrid').data('kendoGrid');
grid.tbody.find("tr[role='row']").each(function () {
var index = $(this).index();
if (index < 19) {
$(this).find('.k-i-expand').removeClass('k-i-expand');
}
})
}
Additionally if you are trying to use a column, say an ID column you can do it like the below.
dataSource: yourDataSouce,
dataBound: function(e) {
var grid = this,
grid2 = $('#yourGrid').data('kendoGrid'),
grid.tbody.find("tr[role='row']").each(function () {
var data = grid.dataItem(this);
if (data.yourColumnID < 19) {
$(this).find('.k-i-expand').removeClass('k-i-expand');
}
})
}
I hope this helps anyone else who runs into the same issue.
I am using ui-grid - v3.0.0-rc.22 - 2015-06-15.
It is configured to use external sorting, which works fine.
Now i have the requirement to change the sorted column from outside with a select box. On every change of the select box it fires external sorting and the data in the grid is updated correctly. It also updates the gridOptions.columnDefs: It sets the sort object of all columns except the correct one to undefined and updates the sorted column.
But there is one problem, the current sorted column indicator (in the column header) is not updated as it should be.
I tried using gridApi.core.notifyDataChange() with "options" or"column" as parameter value but it didn't work also.
How to update the sort-indicators in ui-grid programmatically?
Here is a part of the code triggered by the select box:
function updateSortColumn() {
if ($rootScope.QuickSearch.sortBy !== undefined) {
$scope.gridOptions.columnDefs.forEach(function (col) {
if (col.field === $rootScope.QuickSearch.sortBy) {
col.sort = {
direction: $rootScope.QuickSearch.sortOrder,
priority: 0
};
}
else
{
col.sort = undefined;
}
});
}
if($scope.gridApi !== undefined)
{
$scope.gridApi.core.notifyDataChange( uiGridConstants.dataChange.OPTIONS );
$scope.gridApi.core.notifyDataChange( uiGridConstants.dataChange.COLUMN );
}
}
You could use the function "sortColumn" of the ui-grid, like this:
$scope.gridApi.grid.sortColumn(column, directionOrAdd, add)
here is the source code of this function : ui-grid source code
in your example it will give somthing like this :
function updateSortColumn() {
if ($rootScope.QuickSearch.sortBy !== undefined) {
$scope.gridOptions.columnDefs.forEach(function (col) {
if (col.field === $rootScope.QuickSearch.sortBy) {
$scope.gridApi.grid.sortColumn(col,$rootScope.QuickSearch.sortOrder);
}
});
}
}
$rootScope.QuickSearch.sortOrder must be in (uiGridConstants.ASC|uiGridConstants.DESC). You do not have to provide it.
I had the same problem -- the solution in my case was what Gho5t helpfully mentioned in a comment on another answer on this question.
I'm adding this response so the solution can have more visibility (alongside a more complete code example).
I needed a way to hook into the sort event on a grid and sort other grids on the page by the same column (they all have the same column definitions).
I was incorrectly passing the gridOptions.colDefinition object to the sortColumn() method and the column header sort indicator was not updating.
The grid.column object was what the sortColumn() method was looking for and caused things to work as expected.
// sortColumns is an array of column objects that gets passed in when a grid column is sorted (this code only considers the first sorted column)
// secondGridObj is an object defined elsewhere that has a reference to another grid's gridApi object
gridApi.core.on.sortChanged(null, function (grid, sortColumns) {
if (sortColumns.length) {
var sortDirection = (sortColumns[0].sort) ? sortColumns[0].sort.direction || uiGridConstants.ASC : uiGridConstants.ASC;
var matchingColumn = _.find(secondGridObj.gridApi.grid.columns, function (v2) { return v2.field === sortColumns[0].field; });
if (matchingColumn) {
secondGridObj.gridApi.grid.sortColumn(matchingColumn, sortDirection, false)
.then(function() {
secondGridObj.gridApi.grid.notifyDataChange(uiGridConstants.dataChange.COLUMN);
});
}
}
});
I been trying to do checkbox Checkall and UnCheckall using subscribe and i'm partially successful doing that but i am unable to find a fix in couple of scenarios when i am dealing with subscribe .
Using subscribe :
I am here able to checkAll uncheckAll but when i uncheck a child checkbox i.e test1 or test2 i need my parent checkbox name also to be unchecked and in next turn if i check test1 the parent checkbox should be checked i.e keeping condition both child checkboxes are checked .
For fiddle : Click Here
ViewModel :
self.selectedAllBox.subscribe(function (newValue) {
if (newValue == true) {
ko.utils.arrayForEach(self.People(), function (item) {
item.sel(true);
});
} else {
ko.utils.arrayForEach(self.People(), function (item) {
item.sel(false);
});
}
});
The same scenario can be done perfectly in easy way using computed but due some performance issues i need to use subscribe which is best way it wont fire like computed onload .
Reference : Using computed same thing is done perfectly check this Fiddle
I tried to use change event in individual checkbox binding but its a dead end till now.
Any help is appreciated .
Your subscription only applies to edits on the selectedAllBox. To do what you want, you'll need subscriptions on every Person checkbox as well, to check for the right conditions and uncheck the selectedAllBox in the right situations there.
It strikes me as odd that this would be acceptable but using computed() is not. Maybe you should reconsider that part of your answer. I would much rather compute a "isAllSelected" value based on my viewModel state, then bind the selectedAllBox to that.
I solved a similar problem in my own application a couple of years ago using manual subscriptions. Although the computed observable method is concise and easy to understand, it suffers from poor performance when there's a large number of items. Hopefully the code below speaks for itself:
function unsetCount(array, propName) {
// When an item is added to the array, set up a manual subscription
function addItem(item) {
var previousValue = !!item[propName]();
item[propName]._unsetSubscription = item[propName].subscribe(function (latestValue) {
latestValue = !!latestValue;
if (latestValue !== previousValue) {
previousValue = latestValue;
unsetCount(unsetCount() + (latestValue ? -1 : 1));
}
});
return previousValue;
}
// When an item is removed from the array, dispose the subscription
function removeItem(item) {
item[propName]._unsetSubscription.dispose();
return !!item[propName]();
}
// Initialize
var tempUnsetCount = 0;
ko.utils.arrayForEach(array(), function (item) {
if (!addItem(item)) {
tempUnsetCount++;
}
});
var unsetCount = ko.observable(tempUnsetCount);
// Subscribe to array changes
array.subscribe(function (changes) {
var tempUnsetCount = unsetCount();
ko.utils.arrayForEach(changes, function (change) {
if (change.moved === undefined) {
if (change.status === 'added') {
if (!addItem(change.value))
tempUnsetCount++;
} else {
if (!removeItem(change.value))
tempUnsetCount--;
}
}
});
unsetCount(tempUnsetCount);
}, null, 'arrayChange');
return unsetCount;
}
You'll still use a computed observable in your viewmodel for the the select-all value, but now it'll only need to check the unselected count:
self.unselectedPeopleCount = unsetCount(self.People, 'Selected');
self.SelectAll = ko.pureComputed({
read: function() {
return self.People().length && self.unselectedPeopleCount() === 0;
},
write: function(value) {
ko.utils.arrayForEach(self.People(), function (person) {
person.Selected(value);
});
}
}).extend({rateLimit:0});
Example: http://jsfiddle.net/mbest/dwnv81j0/
The computed approach is the right way to do this. You can improve some performance issues by using pureComputed and by using rateLimit. Both require more recent versions of Knockout than the 2.2.1 used in your example (3.2 and 3.1, respectively).
self.SelectAll = ko.pureComputed({
read: function() {
var item = ko.utils.arrayFirst(self.People(), function(item) {
return !item.Selected();
});
return item == null;
},
write: function(value) {
ko.utils.arrayForEach(self.People(), function (person) {
person.Selected(value);
});
}
}).extend({rateLimit:1});
http://jsfiddle.net/mbest/AneL9/98/