Last update on Sunday, June 26th 2016

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.

Let's start an open source Angular 2 project: ng2-drag-drop-tree

ng2-drag-drop-tree: Search And Node Deletion Features

ng2-drag-drop-tree: Adding a new node and demo available!

Stay up to date


Join over 4000 other developers who already receive my tutorials and their source code out of the oven + other free stuff!