I have a requirement in angular slickgrid where I want to edit the row with the same option which in result will update the date on which the update was made.
What I actually do is call an API on edit command handler when any changes are made in the table, but when I click on the same option from dropdown, the handler is not triggered(which is valid as there was no change made, but for my purpose I need that to be triggered)
So my code looks something like this:
These are my grid options
{
enableAutoResize: true,
enableSorting: true,
editable: true,
autoEdit: true,
autoCommitEdit: true,
editCommandHandler : (item, column, editCommand) => EditHandler(item, column, editCommand)//This is my EditHandler method which gets triggered and calls an API in backend
}
This is my column definition
{
id: 'status', name: 'Status', field: 'status',
filterable: true,
editor: {
collection: [{ value: 'progress', label: 'Progress' }, { value: 'new', label: 'New' }, { value: 'done', label: 'Done' }],
model: Editors.singleSelect
}
}
Now suppose If a row contains Progress in the status column and when I change that to New from dropdown my EditHandler method triggers and I proceed with my changes.
But what I want is to click on Progress again and want to trigger the EditHandler method and call the API which updates the date with the same status
EDIT
The following works and I tested it. I also added code to keep the last event name triggered (onClose/onOpen) so that you won't trigger the editCommandHandler when opening the select dropdown. You should also use the latest version of Angular-Slickgrid version 2.25.0
, all the Editors/Filters are now Public so it's easier to extend them (see latest Release Note).
export class CustomSelectEditor extends SingleSelectEditor {
private lastEventName = '';
constructor(args) {
super(args);
// retrieve the options that were provided to multipleSelect.JS
// we will override the onClose/onOpen to get last event name triggered
// Note: make sure that the onClose is still calling the this.save() else nothing will work
const libOptions = this.editorDomElement.multipleSelect('getOptions');
libOptions.onClose = () => {
this.lastEventName = 'onClose';
this.save();
};
libOptions.onOpen = () => {
this.lastEventName = 'onOpen';
}
this.editorDomElement.multipleSelect('refreshOptions', libOptions);
}
isValueChanged(): boolean {
// return true only when it's the onClose event to fire the editCommandHandler
if (this.lastEventName === 'onClose') {
return true;
}
// but keep previous logic when it's not the onClose event
if (this.isMultipleSelect) {
return !charArraysEqual(this.$editorElm.val(), this.originalValue);
}
return this.$editorElm.val() !== this.originalValue;
}
}
All Editors were written in a way to avoid triggering events when nothing changed, if you really wish to change that behavior then you could extend the SelectEditor
and override the isValueChanged() function.
Note that I did not test the code below but it should work, I'm not sure if SelectEditor
is actually public, if it's not then try to extend Editors.singleSelect
and Editors.multipleSelect
Try first to extend SelectEditor
directly (I think they are not currently public and that won't work, but I'll probably change that in future version)
import { SelectEditor } from 'angular-slickgrid';
export class CustomSelectEditor extends SelectEditor {
constructor() {
super();
}
isValueChanged(): boolean {
// your custom logic
}
}
or Editors.singleSelect
if SelectEditor
is not publicly available
import { Editors } from 'angular-slickgrid';
export class CustomSelectEditor extends Editors.inputText {
constructor() {
super();
}
isValueChanged(): boolean {
// your custom logic
}
}
then use it in your custom editor in your column definitions
{
id: 'status', name: 'Status', field: 'status',
filterable: true,
editor: {
collection: [{ value: 'progress', label: 'Progress' }, { value: 'new', label: 'New' }, { value: 'done', label: 'Done' }],
model: CustomSelectEditor
}
}