Search code examples
angulartypescriptdrop-down-menutextareaonchange

change text area value when select (dropdown) changes using Typescript (Angular6)


I have an issue trying to change the text area value depending on dropdown selection.

This is the dialog design:

enter image description here

The code I implemented for it is as follows:

<div class="modal-content">
<div class="modal-header">
    <h5>Send Text Message</h5>
</div>

<div class="sub-title">
  <b>SELECT MESSAGE TEMPLATE:</b>
</div>

<form>
  <div>
    <select name="textmessage" class="select" [(ngModel)]="selectedMessageContentType" (change)="getSelectedTextMessage()">
        <option *ngFor="let messageContentType of messageContentTypes" [value]="messageContentType">
          {{messageContentType.messageDescription}}
        </option>
      </select>
  </div>
  <br>
  <div>
    <textarea #textmessagecontent [(ngModel)]="selectedMessageContentType.messageContent" class="textarea" maxlength="5000" type="text" name="textmessagecontent" disabled></textarea>
  </div>
</form>

<div class="modal-footer">
  <button type="button" class="btn btn-outline-primary font-weight-bold" (click)="onSendMessageClicked()">SEND</button>
  <button type="button" class="btn btn-primary font-weight-bold" (click)="onCancelClicked()">CANCEL</button>
</div>

This is the Typescript component:

import { Component, ElementRef, Input, OnInit, ViewChild } from "@angular/core";
import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';
import { IssueService } from '../../../../services/issue.service';
import { IssueTextMessageRequestInput, IssueMessageContent } from "../../../../models/inputs/issue.model";
@Component({
    selector: 'textmessage',
    templateUrl: './textmessage.component.html',
    styleUrls: ['./textmessage.component.scss']
})
export class TextMessageComponent implements OnInit {
    messageContentTypes : IssueMessageContent[] = [
        { contentId: 50, messageDescription: 'Change', messageContent: 'Change something.' },
        { contentId: 51, messageDescription: 'Send Baseline', messageContent: 'Send Base' },
        { contentId: 52, messageDescription: 'Adapter', messageContent: 'Change to Lead Wire Adapter' }
    ];
    selectedMessageContentType: IssueMessageContent;
    @Input() messageData: IssueTextMessageRequestInput;
constructor(private activeModal: NgbActiveModal, private issueService: IssueService) { }

ngOnInit() {
    this.selectedMessageContentType = this.messageContentTypes[0];
}

onCancelClicked() {
    this.activeModal.close();
}

getSelectedTextMessage() {
        debugger;
        this.textarea.nativeElement.innerText = "test";
    }

onSendMessageClicked() {
    this.messageData.message = this.getMessageContentById(this.selectedMessageContentType).messageDescription;
    console.log(this.messageData);
    /*this.issueService.processAndSendMessageWithIssueActivityTracking(messageData)
    .subscribe((resp) => {});*/
}

getMessageContentById(msgId: number) {
    return this.messageContentTypes.find(content => content.contentId === msgId);
}

}

I tried following a couple of tutorials around it, but I am still having the following issues:

  • When I activate the "onchange" event I see that "this.selectedMessageContentType" has [object Object] and I cannot pick the properties. I mean, whenever I call for this.selectedMessageContentType.contentId I get undefined.
  • When I change the text area value to "test", the text area never displays the change

Any clue or direction will be highly appreciated. Thanks in advance.


Solution

  • So, first of all, to make each option's value to be an object, instead of a string, you need to use [ngValue], instead of [value], as per the official docs: https://angular.io/api/forms/NgSelectOption#properties. In your case the change would look like this:

    <select name="textmessage" class="select" [(ngModel)]="selectedMessageContentType">
      <option *ngFor="let messageContentType of messageContentTypes" [ngValue]="messageContentType">
       {{messageContentType.messageDescription}}
     </option>
    </select>
    

    So now selectedMessageContentType will now hold a reference to the selected messageContentType from the select.

    This should also fix your issue with the textarea value, since now selectedMessageContentType will be an object, instead of a string. You don't need the getSelectedTextMessage() logic at all - changing form elements' values using plain JS is discouraged in Angular, since you are already using the template form approach with [ngModel].

    Here is a StackBlitz of the proposed solution: https://stackblitz.com/edit/angular-ivy-ytvrp2?file=src/app/app.component.html