1

Using ionic 3 on a desktop. I have a list of items. Each item can be edited and then the changes saved or cancelled. If I hit edit and the input box opens, I want to be able to close the edit/input box by hitting escape. I also have an alert controller to add an item to the list. I would like the alert controller to go away upon hitting escape. Neither of these functions work now, and I'm not sure how to add them. I've searched the ionic docs, but I guess I am not understanding them.

Here is the code:

settings.ts

itemTapped(item) {
    this.selectedItem = item;
    this.selectedItem.wasClicked = true;
    console.log(this.selectedItem);
    this.addTable = true;
    this.refreshRows();
}

refreshRows() { 
    this.editRowIndex = null;
    this.selectedItem.service.find()
      .subscribe(data => {
          this.rows = data;
          console.log("The data id is: " + data.id);
    });
  }

  cancelTapped() {
      this.addTable = false;
  }

  addTapped(event, cell, rowIndex) {
      const prompt = this.alertCtrl.create({
          title: "Add " + this.selectedItem.label.slice(0, 
          this.selectedItem.label.length-this.selectedItem.trimSingle),
      cssClass: 'buttonCss',
      enableBackdropDismiss: false,
      inputs: [
          {
              name: 'name',
          }
      ],    
      buttons: [      
        {
          text: 'Cancel',
          cssClass: 'item-button button button-md button-outline button-outline-md'
        },
        {
          text: 'Save',
          handler: data => {
            this.saveNewRow(data);
          },
          cssClass: 'buttonColor item-button button button-md button-default button-default-md button-md-pm-yellow'          
        },               
      ],
    });
    prompt.present();
    console.log("You clicked on a detail.");
  }

  saveNewRow(data) {
    this.selectedItem.service.findOne({order: "id DESC"}).subscribe(result => {
      console.log('The result is ', result);
      this.editRowId = result.id+1;
      this.editRowData = { id: this.editRowId, name: data.name };
      console.log('editRowData is ', this.editRowData);
      this.selectedItem.service.create(this.editRowData).subscribe(result => {
        this.refreshRows();
      });
    })
  }

  saveRow(name) {
   let newName = name.nativeElement.value;  
   if (newName !== this.editRowData["name"]) {
     this.editRowData["name"] = newName;
     this.selectedItem.service.updateAttributes(this.editRowData["id"], 
this.editRowData).subscribe(result => {
       let rows = this.rows;
       this.editRowIndex = null;
       this.rows = [...this.rows];
     })
   }
  }

  editRow(rowIndex) {
    this.editRowData = this.rows[rowIndex];
    this.editRowId = this.rows[rowIndex].id;
    this.editRowName = this.rows[rowIndex].name;
    this.editRowIndex = rowIndex;
    setTimeout(() => this.name.nativeElement.focus(), 50);
  }

  cancelEditRow(rowIndex) {
    this.rows[rowIndex].name = this.editRowName;
    this.editRowIndex = null;
  }

  deleteRow(rowIndex) {
      this.selectedItem.service.deleteById(this.rows[rowIndex].id)
      .subscribe(result => {              
          this.refreshRows()
      }, error => {
          console.log(error);
          const noDelete = this.alertCtrl.create({
            title: this.rows[rowIndex].name + ' is in use and cannot be deleted.',
        // subTitle: 'You cannot delete this ' + 
      this.selectedItem.label.slice(0, this.selectedItem.label.length-this.selectedItem.trimSingle),
        buttons: [
          {
            text: 'Dismiss',
            cssClass: 'item-button button button-md button-outline button-outline-md'
          }
        ]
      });
      noDelete.present();
    });
  }
}

Thanks!

apex2022
  • 777
  • 2
  • 8
  • 28

2 Answers2

1

If it's viable, you can set enableBackdropDismiss to true, that would solve your issue. But I guess you have set it for a reason ;)

Otherwise, to make some changes to JGFMK's answer, this is how you can do it, assign your alert to a variable, so that you can reference it in the @HostListener and there dismiss the alert, when user hits esc-key:

import { AlertController, Alert } from 'ionic-angular';

// ...

prompt: Alert;

@HostListener('document:keydown.escape', ['$event'])
onKeydownHandler(event: KeyboardEvent) {
  this.prompt.dismiss();
}

addTapped() {
  this.prompt = this.alertCtrl.create({ ... })
  this.prompt.present();
}

StackBlitz

AT82
  • 71,416
  • 24
  • 140
  • 167
  • I think op changed title of question. It originally mentioned a Modal and even using a browser on a desktop in the question text. So can't fault my answer for that. – JGFMK Feb 21 '19 at 19:08
  • @JGFMK I'm not faulting at all! I just wanted to reference your code, so that I wouldn't get blamed for just copying your code or something :D I usually do that in my answers if I take some bit from another answer. That's just polite in my opinion :) – AT82 Feb 21 '19 at 19:13
  • It worked! The only other thing I had to do was import Alert. Thanks again! – apex2022 Feb 26 '19 at 18:56
  • Yeah, I just had that part included in the stackblitz, but I'll update my answer to make it clear what `Alert` is. Glad my answer helped you! :) – AT82 Feb 26 '19 at 19:04
0

Let me know if this helps.

import { HostListener}    from '@angular/core';
import { ViewController } from 'ionic-angular';
export class ModalPage {
  private exitData = {proceed:false};
  constructor(
    private view:ViewController
  )
  ...
  @HostListener('document:keydown.escape', ['$event']) 
  onKeydownHandler(event: KeyboardEvent) {
    this.view.dismiss(this.exitData);
  }
}

Courtesy of here.

JGFMK
  • 8,425
  • 4
  • 58
  • 92