0

I'm working on an in-browser editor, and I want users to be able to select a word, and immediately start typing to replace the word. I'm planning to change how it looks with styling in the future, but currently, I'm having trouble with the editing mechanism.

Every time I type a word in the input field, the area is deselected and I have to click in the input box again. Is this a problem in the code or the way I'm building it with angular?

Here is a link to a demo of the app working. The console logs should show how many times I'm pressing a button, and as you may notice after every input the box is deselected.

https://i.gyazo.com/c38c0edd506f9ed131d1bbcfef0e6f9f.mp4

I learned that I need to add this to enable global key controls in the @Component selector:

host: { '(window:keydown)': 'onKey($event)' },

Here is the html template:

<div class="content" *ngFor="let sentence of sentences; let s_i = index;">
<span class="content" *ngFor="let word of sentence; let i = index;">

  <span *ngIf="(currentIndex === i) && (currentSentence === s_i) && !(editing)"
          class="selectedWord"
          (click)="onClick(s_i, i)">{{word}} </span>
  <input *ngIf="(currentIndex === i) && (currentSentence === s_i) && (editing)"
          class="editingWord"
          (click)="onClick(s_i, i)"
          type="text"
          [(ngModel)]="sentences[s_i][i]">
  <span *ngIf="(currentIndex !== i) || (currentSentence !== s_i)"
          (click)="onClick(s_i, i)">{{word}} </span>
</span>
<br>
</div>

<span class="content" *ngFor="let word of array; let i = index;"> 

</span>

and here is the class (and the relevant methods) the template is attached to:

export class EditorComponent { 
    text: string;

    sentences: string[][];
    sentenceCount: number;

    currentSentence: number;
    currentIndex: number;
    editing: boolean;

    constructor() {
      this.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
      var array = this.text.split(" ");
      console.log(array);  
      this.sentences = [];
      this.sentenceCount = this.sentences.push(array);
      this.currentIndex = 0;
      this.currentSentence = 0;
      this.editing = false;
    }

    onKey(event: KeyboardEvent) {
      var keycode = event.keyCode;
      console.log("You pressed", keycode);

      switch (keycode) {
        case 13: // ENTER
          this.createSentence();
          break;
        case 27: // ESC
          this.finishWord();
          break;
        case 72: // 'h'
          this.moveLeft();
          break;
        case 74: // 'j'
          this.moveDown();
          break;
        case 75: // 'k'
          this.moveUp();
          break;
        case 76: // 'l'
          this.moveRight();
          break;
        case 82: // 'r'
          this.editWord();
          break;
      }
    }

    private editWord = function() {
      this.editing = true;
    }

    private finishWord = function() {
      this.editing = false;
    }

    private isEditing = function() {
      return this.editing;
    }
}
shifubear
  • 21
  • 4
  • [*keyCode*](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) has been removed from standards, you shouldn't use it. – RobG Jun 22 '17 at 02:00
  • 1
    @RobG So what's the new standard it's been replaced with? – shifubear Jun 22 '17 at 02:40
  • It's explained in the [*MDN link*](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) I provided: "*Instead, you should use KeyboardEvent.code, if it's implemented. Unfortunately, some browsers still don't have it…*". Generally I've found key events to be a real mess and try to avoid them as much as possible, though if you only want to detect certain keys that can be done reliably for the most part. – RobG Jun 22 '17 at 06:08
  • Well the root problem is that your array is of primitive type. Check my answer here: https://stackoverflow.com/questions/42322968/angular2-dynamic-input-field-lose-focus-when-input-changes Without checking the rest of the code, so I do not know if there are other problems, but this could actually solve your problem completely. – AT82 Jun 22 '17 at 20:29
  • @AJT_82 Thank you so much that solved my problem! You're a lifesaver! – shifubear Jun 23 '17 at 02:21
  • @shifubear Very glad to hear it worked out!! :) :) You could consider accepting the duplicate which a proposed, so it marks this question as solved. – AT82 Jun 23 '17 at 09:10

0 Answers0