ng2-drag-drop-tree: Text Modification And OSS Inception
Feature wise we are approaching the end of the journey.
Let's add the possibility to modify the text of a node.
As you have noticed, the project is focused on making things simple, I was thinking of only using textfields and cycle back here later to make it UX-friendly, however I remembered that a cool JS XEditable plugin that allows to switch between textfield and label existed, so I thought about using it :D.
After a quick search ... nothing available for Angular 2 :(. So let's do some inception and create another OSS project for our OSS project!
Let's call this new project ng2-xeditable-text.
ng2-xeditable-text
How does it work?
When the user clicks on the label, switch the element to an input text, then switch back to label when leaving the input text.
Let's create the directive now:
import { Component, Input } from "@angular/core";
@Component({
selector: "editable-text",
template: `
<span *ngIf='isEditable'> <input type='text' (blur)="setEditable(false)"
[(ngModel)]='node.text'> </span>
<span *ngIf='!isEditable' (click)='setEditable(true)'> {{node.text}} </span>
`
})
export class XEditableText {
@Input() node;
isEditable: boolean;
constructor() {}
setEditable(isEditable) {
this.isEditable = isEditable;
}
ngOnInit() {
this.isEditable = false;
}
}
Very simple here, the child is received through the node Input, then init a variable named "isEditable" to false that we can toggle through the setEditable method.
In the template:
<span *ngIf='isEditable'>
<input type='text' (blur)="setEditable(false)" [(ngModel)]='node.text'>
</span>
If it's editable we display the textfield with the node value, on blur we set "isEditable" to false hence switch to label mode.
<span *ngIf='!isEditable' (click)='setEditable(true)'> {{node.text}} </span>
If it's not editable we display the text with the node value and listen for a click on the label to set "isEditable" to true in order to switch to text mode. We import it into our lib:
export * from "./ng2-xeditable-text/ng2-xeditable-text.directive";
And in our node component:
import {XEditableText} from '../ng2-xeditable-text/ng2-xeditable-text.directive';
@Component({
selector: 'tree-node',
directives: [Draggable,Droppable, TreeNode, XEditableText]
.
.
.
In tree-node.html before the X mark, just replacing the binding:
{{child.text}}
<span (click)='deleteNode(child)'>X</span>
By the editable-text tag directive which requires the child for modifications:
<editable-text [node]="child"></editable-text>
<span (click)='deleteNode(child)'>X</span>
And voila! We have our cool x-editable textfield in every node now!
This serie is coming to an end, what remains to do : allow the user to choose the CSS (at the moment it's a liiiittle bit basic), handling multiple nodes and a some bug squashing.