Angular 9 ngModel not clearing default selection - javascript

I am trying to autofill a text box based on the state from another component. Which works fine. But when I go to add ngModel to the text box to take in the value when submitting the form. The value is cleared and not displayed to the user.
<div *ngIf="autoFill; else noFillMode" class="row">
<label>Mode of Transport</label>
<input type="text" value="{{state.type}}" readonly />
</div>
<div *ngIf="autoFill; else noFillStop" class="row">
<label>Nearby Stop / Station</label>
<input
type="text"
value="{{state.stopName}}"
[(ngModel)]="stopName"
readonly
/>
</div>
As you can see in the image the text shows up when there is no ngModel placed on the input. But when there is a ngModel it is not shown.
Can anyone help with this?

Use [(ngModel)] for both text boxes
<div *ngIf="autoFill; else noFillMode" class="row">
<label>Mode of Transport</label>
<input type="text" [(ngModel)]="state.type" readonly>
</div>
<div *ngIf="autoFill; else noFillStop" class="row">
<label>Nearby Stop / Station</label>
<input type="text" [(ngModel)]="state.stopName" readonly>
</div>
Note: [(ngModel)] is for two-way binding which will update data from component to view and vice-versa.
In two-way data binding, automatic synchronization of data happens between the Model and the View. Here, change is reflected in both components. Whenever you make changes in the Model(.ts), it will be reflected in the View(html) and when you make changes in View, it will be reflected in Model.
This happens immediately and automatically, ensures that the HTML template and the TypeScript code are updated at all times.

ngModel creates a two-way binding. In your case, you probably don't have stopName attribute in your component and that's why when you add NgModel you get empty input field. Your code is redundant in this case, value and ngModel both try to set the input value.
Try removing value and set existing attributes to ngModel.
<div *ngIf="autoFill; else noFillMode" class="row">
<label>Mode of Transport</label>
<input type="text" value="{{state.type}}" readonly>
</div>
<div *ngIf="autoFill; else noFillStop" class="row">
<label>Nearby Stop / Station</label>
<input type="text" [(ngModel)]="state.stopName" readonly>
</div>
You can also try to use FormControl, which gives option to set, get, clear, check the validity, ... values from specific formControl or from whole form.
Here is a small implementation in StackBlitz
Don't forget to import ReactiveFormModule

Related

Template reference variable undefined in radio buttons

I am having troubles with aplying validations on radio buttons in angular, on other input types, i usualy just create the #templateRefVariable on the input and can then access the NgControl that allows me to use things like the touched property of the control.
What im trying to achieve currently is setting the touched property of the div acording to if any of the radio buttons in the group were touched. (seting it in the div because of css dependencies if it is not in that outer div the validations will not show), but typeCode is always undefined.
<div class="form-group">
<label>Label</label>
<div class="btn-group btn-group-toggle w-100"
[class.ng-invalid]="!viewmodel.typeCode"
[class.ng-touched]="typeCode?.touched">
<label *ngFor="let domain of types" class="btn btn-toogle"
[class.active]="domain.code==viewmodel.typeCode">
<input type="radio" [(ngModel)]="viewmodel.typeCode"
#typeCode="ngModel" name="typeCode"
[value]="domain.code">
{{domain.description}}
</label>
</div>
<validation-message *ngIf="!viewmodel.typeCode"
[message]="'Required'"></validation-message>
</div>
With invalid i can workarround it by using the information in the view model to see if it was set already but the information on touched is not in the view model.
And i cant do the same for ng-touched because i need to set touched when there is an atempt to submit the form (even if the inputs were not actualy touched).
Any idea why typeCode (templateVariableRef) is undefined while using it in radio buttons ? i suspect it might be because of there being multiple in the page but i am not sure.
P.S: Using template driven forms
StackBlitz as requested (note errors on console because of typeCode undefined):
https://angular-5vqi5c.stackblitz.io
It is because ngFor is a structural directive and creates a nested template, and therefore these template variable(s) are out of scope.
Would moving your logic inside the ngFor be an option for you e.g.?
<div class="btn-group btn-group-toggle w-100"
[class.ng-invalid]="!viewmodel.typeCode">
<ng-container *ngFor="let domain of types">
<div [class.ng-touched]="typeCode?.touched>
<label class="btn btn-toogle"
[class.active]="domain.code==viewmodel.typeCode">
<input type="radio" [(ngModel)]="viewmodel.typeCode"
#typeCode="ngModel" name="typeCode"
[value]="domain.code">
{{domain.description}}
</label>
</div>
</ng-container>
</div>
PS. I haven't tested the code above.

AngularJS ng-message directive always showing message

I am trying to set the select field in the view to be required. So I'm having the below tags in my view.html
<form name="homeForm">
<div class="form-group col-md-6 md-padding">
<div>
<label style="font-size: medium">Laboratory Name</label>
<select name="labName" class="form-control" ng-model="request.labName" required>
<option ng-repeat="lab in labList" value="{{lab.id}}">{{lab.value}}</option>
</select>
<div style="color:maroon" ng-messages="homeForm.labName.$error"
ng-if="homeForm.requestTypeName.$touched">
<div ng-message="required">This field is required</div>
</div>
</div>
I was hoping the This field is required will show up only when there is no data selected. But irrespective of the field has data or not This field is required shows up like below
Is there something I am missing here
You need to set the same input name in your input and in your ng-message. Doing this, you don't even need to have ng-if. For example:
<form name="form">
<input name="fullname" type="text" ng-model="fullname" required/>
<div ng-messages="form.$submitted && form.fullname.$error">
<p ng-message="required" class="help-block">This field is required</p>
</div>
</form>
In this case I am using form.$submitted. You can remove that, replace it with touched/dirty or whatever. The principle is the same.
The ng-messages directive is in a separate library module and must be included as a dependency.
Example
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/angular-messages/angular-messages.js"></script>
JS
angular.module("app",["ngMessages"])
For more information, see AngularJS ngMessages Module API Reference.
You are using homeForm.requestTypeName in the ng-if, and there is no input control named requestTypeName, i guess you must use homeForm.labName as you use in the ng-message attribute.
Basically, change the ng-if to ng-if="homeForm.labName.$touched"
TL;DR;
You could use as well the homeForm.labName.$error.required for checking if actually the end user has passed away that field without entering some input.
Source: https://docs.angularjs.org/api/ng/directive/ngRequired

Angular2 form validation for focus()

<div class="col-md-3">
<div class="md-form selecticon form-group rupee-icon" [ngClass]="{'has-error':!loanApplyForm.controls['propval'].valid &&loanApplyForm.controls['propval'].touched}">
<label class="lf-loan-input-label" for="propval">Property Value * </label>
<input #iw_propval (focus)="iw_propval.value = ''" class="form-control emi-input" id="propval" [formControl]="loanApplyForm.controls['propval']"
type="number">
<div *ngIf="!loanApplyForm.controls['propval'].valid&& loanApplyForm.controls['propval'].touched" class="alert-change">*Please enter the property value.</div>
</div>
</div>
This is my .html file.here i am using the focus() method to empty the field on click.but when i focus field the field shows still ng-valid and not showing the error message.my .ts file is all correct.problem with focus method.if i remove focus method from input tag it works fine.The problem is with the condition that i gave in the error message.so what condition i want to give validate this focus method.please help me.Thanks in advance.
Resetting the formcontrol value should work:
.....(focus)="loanApplyForm.controls['propval'].reset()"
try setting the value to null instead of an empty string.

How can I preserve initial value using ngModel in angularJS

I'm trying to add a feature for in line editing.
Here's my html:
<div class="value" data-ng-repeat='value in aaVM.archValues'>
<div class="nameContainer">
<div class='name' data-ng-hide='editing' data-ng-click='editing = !editing'>
<span>{{value.name}}</span>
<div class="icon">
<md-icon class="mdIcon" md-svg-src="./resources/images/icons/edit.svg"></md-icon>
</div>
</div>
<form data-ng-submit='aaVM.updateName(value.name); editing= !editing' data-ng-show='editing'>
<input type="text" data-ng-model='value.name'>
<div class="cancel" data-ng-click='editing = !editing'>X</div>
<input type="submit">
</form>
</div>
</div>
Everything works. Here's the issue, because I'm using ng-model to bind the values name in the form, When I hit cancel, the ui will present the edited version of the input(assuming edits were made) despite hitting the cancel button.
I want the user to be able to edit freely, and upon hitting the cancel button, it revert the value back to the original value of value.name.
I could use a different variable, but I want the initial value of the input to be the value from the ng-repeat. Is there a way to temporarily clone the value and retrieve it later in the scope of an ng-repeat. Or any other work around to enable to cancel button in the way I've described? Thanks.
In Angular, Use directive ngModelOptions to change ng-model value on submit event and use $rollbackViewValue to roll back input original value
Try this:
<form data-ng-submit='aaVM.updateName(value.name); editing= !editing' data-ng-show='editing'>
<input type="text" ng-model-options="{ updateOn: 'submit' }" data-ng-model='value.name'>
<div class="cancel" data-ng-click="editing = !editing; value.name.$rollbackViewValue();">X</div>
<input type="submit">
</form>
Official Documentation for more information

ngMessages not working correctly with nested input

I have an input field that is nested within another <div> element, and I am trying to use ngMessages on that inside input field, but I can't seem to get it to validate correctly.
<div class="form-group" ng-model="object.idnumber" ng-hide="condition.userObjectsHidden">
<label class="form-control-label col-lg-12">ID Number</label>
<div class="col-lg-12">
<input type="text" name="idnumber" placeholder="111001111"
ng-model="user.idnumber"
ng-pattern="idpattern"
class="form-control input-lg"
required="required"></input>
<div ng-messages="idnumber.$error" ng-if="idnumber.$dirty">
<p ng-message="pattern">You are wrong!</p>
</div>
</div>
</div>
I'm not sure if it matters in terms of functionality where the <div ng-messages...> tag is, but I have also tried having it completely outside of this element with the same results. If I understand Angular and ngMessages correctly, I need to assign ng-messages to a directive--$error in this case--that I get to by dot-walking across name assignments. As far as I know, I have done this with idnumber.$error, although to be fair, I have also tried a more extensive dot-walk by using kiosk-form.uin.$error, where kiosk-form is the name of the entire form.
I have tried both ng-message="pattern" as well as ng-message="required". Also, just for clarity, idpattern is defined in my Javascript file as a regex string. It is defined correctly.
Rename your form as kioskFormand then ng-messages ="kioskForm.idnumber.$error"

Categories

Resources