4

Related Question
But this is not exactly the same. I have two components. One component has the input, another component has a button. Now I want to populate some text on click of the button in the input field which is rendered by a different component.

input.component.html

<input #input type="text-area"/>

button.component.html

<li (click)="addText($event)">Click Me !!</li>

button.component.ts

@ViewChild('input') private input; addText(event){
    console.log(this.input); //this is undefined 
} 

Project Structure :

  • ./input/input.component.ts
  • ./input/input.component.html
  • ./button/button.component.ts
  • ./button/button.component.html

I know I can use a service and then have an observable to listen to and subscribe to that for identifying the changes, but I just wanted to avoid that, as the accepted answer in the hyperlink above looked simpler.

1
  • you need to do this using a service. raise an event from the service from button component and subscribe to that event in input component and add the text there. Can you share a sample app for the same? Commented Apr 4, 2018 at 9:57

2 Answers 2

3

Based on the example in the link, I suggest the following solution. As the two components are siblings, use @Viewchild to get the reference of the children DOM elements. @Input and @Output will help for the communication.

parent.component.html

   <div class="wrapper">
      <comp1 #comp1 [myText]="name"></comp1>
      <comp2 (clickEvent)="addText()"></comp2>
   </div>

parent.component.ts

  import { ViewChild } from '@angular/core';
  ...

  name = 'Angular'; 

  @ViewChild('comp1') private comp1;

  addText(event) {
    this.comp1.myInput.nativeElement.focus();
    let startPos = this.comp1.myInput.nativeElement.selectionStart;
    let value = this.comp1.myInput.nativeElement.value;
    this.comp1.myInput.nativeElement.value =
      value.substring(0, startPos) + ' rocks! ' + value.substring(startPos, value.length)
  }

button.component.html

  <ul>
     <li (click)="clickEventMethod()"> Click here to add some text </li>
  </ul>

button.component.ts

  import { Output, EventEmitter } from '@angular/core';
  ...
  @Output() clickEvent = new EventEmitter<boolean>();

  clickEventMethod() {
    this.clickEvent.emit();
  }

input.component.html

  <input [(ngModel)]="myText" #myInput type="text" placeholder="Enter some text">`,

input.component.ts

   import { ViewChild, Input } from '@angular/core';
   ...
   @ViewChild('myInput') private myInput;
   @Input() private myText;

DEMO

Sign up to request clarification or add additional context in comments.

2 Comments

button.component.html does not have <input-component #comp></input-component>
This works, so accepting it. Though I have used a service based approach as some specs changed and needed to make it more generic.
0

Use a separate service to do this. You can push values from the button component to the service from calling a set method on service. And you can get values from the service to the input component by using a subject and subscribing to it. Hope this helps.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.