how to make dropdown without warning or ngModel in angular? - javascript

could you please tell me how to make dropdown without warning or ngModel in angular? I am getting warning this
code
https://stackblitz.com/edit/angular-vsjbr9?file=src%2Fapp%2Fapp.component.ts
how I will acheive the same thing without ngModel
<form novalidate [formGroup]="searchForm" class="calform">
<section class="col-sm-6 bg-white pl-20 pr-20">
<div class="form-group col-sm-8 pl-0">
<label class="field-title mb-5">Circle<span class="color-red fontWt"> *</span></label>
<div class="select width-170 mr-20">
<select formControlName="circle" [(ngModel)]="selectedCircle">
<option class='option'
*ngFor='let o of circle'
[disabled]="o.value==''"
[value]="o.value">{{o.option}}</option>
</select>
</div>
</div>
</section>
</form>
I want first option is selected by default and user never select first option in my example ("select from list never selected")

Something like this? https://stackblitz.com/edit/angular-zxeysz?file=src%2Fapp%2Fapp.component.ts
I've removed the ngmodel. You are already using a formgroup so ngmodel is not needed.
Then in your ts file , you do create the 'circle' control, but you assigned null value. I've altered it to empty string ''. This way the the select is pre-checked with the '' value.

Related

Angular 9 ngModel not clearing default selection

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

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

What's wrong with my use of ng-class?

I'm using ui-router and the view below accesses the controller using the 'Controller As' syntax. I'm adding the 'invalid' class onto the 'shift'-radios container. When form loads you can see both validation required messages (for requestDate and shift). When requestDate and shift are set validation messages disappear. Form's $valid is true. The only problem is that the 'invalid' class on the radio-wrapper div stays.
What am I doing wrong?
<form novalidate ng-submit="_form.$valid && formCtrl.getFormData()" name="_form">
<div class="datepicker-wrapper clearfix">
<datepicker date-format="yyyy-MM-dd">
<input required ng-model="formCtrl.requestDate" name="requestDate" type="text" />
</datepicker>
</div>
<div ng-messages="_form.requestDate.$error" role="alert">
<div ng-message="required">Введите дату</div>
</div>
<div class="radio-wrapper clearfix" ng-class="{invalid: _form.shift.$error}">
<div ng-repeat="shift in formCtrl.shifts" class="item half-width pull-left">
<label for="<% shift.name %>">
<input required ng-model="formCtrl.currentShift"
name="shift"
ng-value="shift"
id="<% shift.name %>"
type="radio" />
<span class="text"><span ng-bind="shift.text"></span></span>
</label>
</div>
</div>
<div ng-messages="_form.shift.$error" role="alert">
<div ng-message="required">Укажите смену</div>
</div>
<!-- other inputs... -->
</form>
I think you need to use the $invalid property, which is a boolean, instead of the $error property, which is a hash.
See: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
Your ng-class definition is checking the wrong property of the form controller. You are checking the truthyness of _form.shift.$error. This object will always exist, even if there are no validation errors. When you don't have any errors, the value of _form.shift.$error is empty object {} which is truthy.
You should instead check the _form.shift.$invalid property which will properly update whether there are any problems with that form field.
There is no _form.shift. The input shift is declared inside an ng-repeat so it is a property on the _form.
To fix you could for example, move your ng-class inside the ng-repeat and reference the shift using ng-form to create a sub-grouping:
<div ng-repeat="shift in formCtrl.shifts" ng-form='nestedShiftForm'>
<div ng-class="{invalid: nestedShiftForm.shift.$error}">
<input name="shift" />

How to select a object option in angular controller

I have a select with options getting from server
<div class="form-group">
<label for="exampleInputEmail1">Terminal Type</label>
<select ng-model="terminal.terminalType" id="terminaltype" class="form-control" ng-options="type.name for type in types">
</select>
</div>
but how can I set option in my controller.
I used:
$("#terminaltype").val($scope.types[0]);
and
document.getElementById("terminaltype").options[i];
but it does not work. Please help me
Can't you set the value inside the model?
You have ng-model="terminal.terminalType"
Inside your controller, you just have to set a value to your item.
$scope.terminal.terminalType = "someValue";
Avoid mixing JQuery and Angular together.

Categories

Resources