7

A bit tricky situation. For the code below, I have added (keydown.enter)="false" to ignore the break line/enter button in textarea

This is causing a user issue and would like the existing behaviour where Pressing enter should automatically trigger the "Save button"

Any idea how to trigger the Save button when still focusing in textArea but ignore the breakline?

    <textarea #textArea
    style="overflow:hidden; height:auto; resize:none;"
    rows="1"
    class="form-control"
    [attr.placeholder]="placeholder"
    [attr.maxlength]="maxlength"
    [attr.autofocus]="autofocus"
    [name]="name"
    [attr.readonly]="readonly ? true : null"
    [attr.required]="required ? true : null"
    (input)="onUpdated($event)"
    [tabindex]="skipTab ? -1 : ''"
    (keydown.enter)="false"
    [(ngModel)]="value">
    </textarea >
ove
  • 3,092
  • 6
  • 34
  • 51
  • Any help? This looks trickier than I thought – ove May 03 '17 at 06:24
  • there is a difference between AngularJS and Angular. It would help your question, if you specify the one you are using correctly. (It looks like Angular, also know as Angular 2 to me.) – hirse May 04 '17 at 08:45
  • @hirse updated. Yes it is angular 2 – ove May 04 '17 at 13:13
  • Can you make an edit and give more details about your file structure ? I've seen many comments from you in the answers but still unclear. Please give your components structure :) – maxime1992 May 12 '17 at 07:53

5 Answers5

2

Extending the answer by @Pengyy

You can bind the bind the enter key to a pseudoSave function, and preventDefault inside of that, thus preventing both the Save function and the newline. Then you can either call the save function from there(assuming it is accessible such as a service) or you can emit an EventEmitter, and have that emit get caught to trigger the Save function.

Joo Beck
  • 1,863
  • 1
  • 18
  • 21
1

you can bind the same function of Save button to keydown.enter of texterea, and call $event.preventDefault to avoid the newline.

sample plunker.

Pengyy
  • 37,383
  • 15
  • 83
  • 73
  • Problem is my save() is in another file. The textarea is in its own control file. – ove May 03 '17 at 06:44
  • @ove another file means another component? you can refer https://angular.io/docs/ts/latest/cookbook/component-communication.html – Pengyy May 03 '17 at 06:50
  • @Penyy This control is used everywhere and looks like I need to handle the onenterkey event and call save everywhere. I am trying to avoid that if possible – ove May 03 '17 at 07:23
  • @ove ok, then you can wrap the elements with a `form`, and bind `save` to form's `keydown.enter`. I have updated the plunker. – Pengyy May 03 '17 at 07:28
  • Putting key.onenter event on the whole form caused issue with the tab and button. If you tab to a button and enter. it saved the form but should open up a model instead. – ove May 04 '17 at 04:12
  • I am worndering if there is another way. I can use the $event.preventDefault() and somehow do a event proparagation to call the Save button. Any help is appreciated – ove May 04 '17 at 13:16
1

Assuming that your textarea is inside a form element.

{Plunker Demo}

You can achieve it by using a hidden submit input, like this

@Component({
  selector: 'my-app',
  template: `
    <form (submit)="formSubmitted($event)">
      <input #proxySubmitBtn type="submit" [hidden]="true"/>

      <textarea #textArea (keydown.enter)="$event.preventDefault(); proxySubmitBtn.click()">
    </textarea>
    </form>
  `,
})
export class App {
  formSubmitted(e) {
    e.preventDefault();
    alert('Form is submitted!');
  }
}
Ankit Singh
  • 24,525
  • 11
  • 66
  • 89
  • I don't understand how it's similar, can you elaborate on the problem with this – Ankit Singh May 09 '17 at 04:48
  • My textarea control encapsulated in a different file. The submit button is in another area/file. – ove May 09 '17 at 11:43
  • but you can still have another `submit input` beside your `textarea`. In fact you can have as many `submit` buttons/ inputs as you want. have you tried this ? – Ankit Singh May 09 '17 at 12:16
  • I don't undestand why I need to have submit button in my input. I need to call the right submit button – ove May 11 '17 at 13:41
0

You can create a service which can send a notification to other components that will handle the command. The service could look like this:

import { Injectable } from "@angular/core";
import { Subject } from "rxjs/Subject";

@Injectable()
export class DataSavingService {

    private dataSavingRequested = new Subject<void>();
    public dataSavingRequested$ = this.dataSavingRequested.asObservable();

    public requestDataSaving(): void {
        this.dataSavingRequested.next();
    }
}

... and should be registered in the providers section of the module. Note: if data must be passed in the notification, you can declare a non-void parameter type for the dataSavingRequested Subject (e.g. string).

The service would be injected in the component with the textarea element and called in the handler of the Enter keypress event:

import { DataSavingService } from "./services/data-saving.service";
...

@Component({
    template: `
        <textarea (keypress.enter)="handleEnterKeyPress($event)" ...></textarea>
    `
})
export class ComponentWithTextarea {
    constructor(private dataSavingService: DataSavingService, ...) {
        ...
    }

    public handleEnterKeyPress(event: KeyboardEvent): void {
        event.preventDefault(); // Prevent the insertion of a new line
        this.dataSavingService.requestDataSaving();
    }
    ...
}

The component with the Save button would subscribe to the dataSavingRequested$ notification of the service and save the data when notified:

import { Component, OnDestroy, ... } from "@angular/core";
import { Subscription } from "rxjs/Subscription";
import { DataSavingService } from "../services/data-saving.service";
...

@Component({
    ...
})
export class ComponentWithSaveButton implements OnDestroy {

    private subscription: Subscription;

    constructor(private dataSavingService: DataSavingService, ...) {
        this.subscription = this.dataSavingService.dataSavingRequested$.subscribe(() => {
            this.saveData();
        });
    }

    public ngOnDestroy(): void {
        this.subscription.unsubscribe();
    }

    private saveData(): void {
        // Perform data saving here
        // Note: this method should also be called by the Save button
        ...
    }
}

The code above assumes that the saving must be performed in the component with the Save button. An alternative would be to move that logic into the service, which would expose a saveData method that could be called by the components. The service would need to gather the data to save, however. It could be obtained with a Subject/Observable mechanism, or supplied directly by the components as a parameter to saveData or by calling another method of the service.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • Thanks for that. I was hoping for something simpler. I will need to change the code a bit and a lot of retest in different area – ove May 08 '17 at 04:52
  • @ove - I added another suggestion for implementing a service to save the data. – ConnorsFan May 09 '17 at 11:54
0

it could be 2 solutions:

  1. Use javascript to handle enter event and trigger Save function in it

or

  1. Use Same thing from Angular side as describe in this.

This may also help you

Narm
  • 10,677
  • 5
  • 41
  • 54
Asav Vora
  • 61
  • 6