Cell Edit
Cell editing is supported programmatically (ColumnApi
) and through the UI (mouse/touch) using the target-events
plugin.
Let's start with a simple example:
The
First Render
column will show if the row was first rendered or it was already rendered, this is valid for Virtual Scroll enabled grid.
If you wondering what is the
[pblCellEditAutoFocus]
directive, it is just a simple
helper
directive that will handle auto-focusing logic of
the input element.
Edit Template
An edit template is one of several template types we can attach to a data column.
The edit template
acts as the write-only cell view and the main template
is the read-only cell view. For cells to be editable they
must belong to a column with an edit template.
There is no default edit template, you can use
*
to define one but the table does not include one like it does for the main template.
In the example above there are 2 cell definitions inside the table that handle the name
column:
pblNgridCellDef
defining the read-only view of the cellpblNgridCellEditorDef
defining the write view of the cell.
These are the specific property directives definitions, there are also type based definitions:
pblNgridCellTypeDef
defining the read-only view of the cellpblNgridCellEditorTypeDef
defining the write view of the cell.
<div *pblNgridCellDef="'name'; let ctx">
<a (click)="ctx.startEdit()">{{ ctx.value }}</a>
</div>
The read-only definition is straight-forward, the main change is that we use the cell context to invoke a startEdit()
command.
<div *pblNgridCellEditorDef="'name'; let ctx">
<input #input [value]="ctx.value" (change)="ctx.value = $event.target.value" (blur)="ctx.stopEdit()" (ngAfterViewInit)="input.focus()"/>
</div>
The write only view also make use if the cell context (`PblNgridCellContext) to assign the new value and to exit editing when the input is out of focus.
Cell context
The cell context is used to toggle between write and read view's, i.e. toggle between the edit and main templates.
We start editing by invoking PblNgridCellContext.startEdit()
and stop editing with PblNgridCellContext.stopEdit()
.
An edit template is mandatory. Calling
PblNgridCellContext.startEdit()
when the column does not have an edit template will be ignored.
Note that this is the only restriction.
The editable
definition
The column definitions include the editable
property, indicating if a column is editable or not.
When set to true
(and an edit template exists) the cell will include the CSS class pbl-ngrid-editable-cell.
The editable
flag has no impact in PblNgridCellContext.startEdit()
but it might be used by plugins or by the developer to
create editing logic
For example, the directives cellEditClick
/ cellEditDblClick
(target-events plugin) allow simple editing integration that
use mouse/touch inputs to toggle editing and use the editable
flag to determine if a cell is editable or not.
Triggering edits globally
The previous example was naive, triggering of cell edit for a specific cell. For scale we want to be able to trigger cell edit at a higher level, once for all editable cells.
For this we make use of the target-events
plugin that allow us to handle specific cell events in a single place.
This time, clicking on a cell in the lead column will start edit mode.
<pbl-ngrid (cellClick)="$event.context.startEdit()"
[dataSource]="ds2" [columns]="columns2">
<div *pblNgridCellEditorDef="'lead'; let ctx">
<input #cb type="checkbox" [checked]="ctx.value"
(change)="changeCheckbox(cb, ctx)"
(blur)="ctx.stopEdit()"
(ngAfterViewInit)="cb.focus()"/>
</div>
</pbl-ngrid>
Now we only need to defined an edit template for the cell and let the table handle the click events.
This time we used (cellClick)
but we can also use (cellDblClick)
When the checked value changes we use a method to assign the new value and stop cell editing:
changeCheckbox(input: HTMLInputElement, ctx: PblNgridCellContext): void {
ctx.value = input.checked;
setTimeout( () => ctx.stopEdit(true) );
}
Some notes:
- We use
setTimeout
to defer the operation because we are probably within aclick
event which will will start editing right after we stop it. - We set
markForCheck
to true (ctx.stopEdit(true)
) to tell the table that something has changed (the editor template is now the read-only template).
We make use ofctx.startEdit()
andctx.stopEdit()
without safety checks, some cell's might not have a cell edit template, some might be editing while we callctx.startEdit()
. This is safe because both methods will check that the above conditions are met.
Cell edit directives
Up to this point we've triggered editing using listeners to click events and without using column metadata.
The target-events
plugin comes with a directive that simplify the process, this directive will allow edit for columns with an edit template and
the editable
property set to true.
In this example we've used an advanced editing component, the data picker from @angular/material2
applied on every column
of type date
, in our case the birthdate column.
We used the cellEditClick
directive to apply cell editing when a click event is fired on a cell, for double click we will use cellEditDblClick
.