I have the following HTML Angular tags, which need to trigger a validation error when there is a negative value entered in any of the groups of textboxes (dynamic array).
<tr *ngFor="let order of configWT.get('wtFormArray').controls; let i =index" formArrayName ="wtFormArray">
<input natinput type ="number" [formControlName]="i" id="wtage" ngModelChange="updateWTage(i)" required>
ngOnInit
ngOnInit():void
{
this.configWT = this.formBuilder.group({
wtFormArray: new FormArray(['',[Validators.min(0)]])
}
Here is the error condition which is working for required validation, but not working for min validation.
Working
<nat-error *ngIf="configWT.get('wtFormArray').at(i).hasError('required'))"
error test
<nat-error>
Not Working
<nat-error *ngIf="configWT.get('wtFormArray').at(i).hasError('min')"
error test
<nat-error>
Here is the DOM
I am feeling like I am comparing min value with an array which may be causing this problem? please help!
I think, you should use minlength for minimum validation, it will be easier, because for new FormArray it's not correct to add validation in such way
<input natinput type ="number"
[formControlName]="i"
id="wtage"
ngModelChange="updateWTage(i)"
required
minlength="4">
<nat-error *ngIf="configWT.get('wtFormArray').at(i).hasError('minlength')">
error test
<nat-error>
Related
I'm trying to implement a new Angular component with template-driven form validation. I have been following the documentation here, but cannot seem to replicate the results. Specifically, the div showing the error just doesn't appear when the input is invalid.
Here is the source code for context:
Template:
<mat-form-field class="input">
<input matInput matTooltip="Float value between 0.0 and 1.0"
type="number"
placeholder="Confidence"
min="0.0"
max="1.0"
[(ngModel)]="confidence"
#value="ngModel">
<mat-error *ngIf="value.invalid && (value.errors.min || value.errors.max)">
Confidence must be an decimal value between 0.0 and 1.0.
</mat-error>
</mat-form-field>
Relevant component code:
metadata = {confidence: 0.0, ...};
get confidence(): number {
return this.metadata.confidence;
}
set confidence(confidenceIn: number) {
this.metadata.confidence = confidenceIn;
}
My understanding is that the line #value="ngModel" makes a local variable value containing the value of the input element it was declared on, which then allows me to reference value as in the following *ngIf directive to check for errors.
However, the mat-error element never shows up when the input value is out of range (less than 0, more than 1), so my understanding is probably wrong and/or I've implemented this incorrectly.
Any explanations would be greatly appreciated!
i have an Angular Factory that gets a single date from the backend of my spring application, and i wanted to add it to an Input so the calendar input is always set with the date obtained from the backend, without the possibility for the user to change it. How could i achieve this? Should i put it on my controller or directly on the button? This is my code:
Factory(concatenated with other .factory):
.factory('DataInizioGeneraCalendario', function ($resource) {
return $resource('rest/anagrafica/dataInizioGeneraCalendario', {
get: {
method: 'GET'
}
});
Controller Function:
$scope.generaCalendario = function () {
$scope.modificaCalendarioDiv = true;
$scope.successMessage = false;
$("#idModificaCalendarioDiv").hide();
$scope.element = new Calendario();
autoScroll('generaCalendario');
$("#idErrorTemplate").hide();
$('#data').attr('disabled', false);
$("#idGeneraCalendarioDiv").show();
};
Input :
<div class="col-xs-12 col-md-2" >
<label for="dataInizio" class="row col-xs-12 control-label" style="text-align: left">da Data</label>
<input class="datepicker form-control" placeholder="gg/mm/aaaa" required type="text" id="data" ng-disabled="true" />
</div>
Edit : forgot to add, the controller function is called by the button that displays the input for the calendar.
Because your factory's GET request will return the date value asynchronously, it's better to have a $scope.date in your controller that will hold the date value that is returned from the server. Also, depending on the format in which you store dates on the backend, you might need to transform the value that is returned from the backend into the string format, so it would be properly consumed by the <input type="date"> as per Angular docs.
In your code, you need to bind the input element to this value, like this: <input ng-model="date">.
What it will do is bind this input to the data model, so that every time when user edits the input the $scope.date would be updated too.
If you do not want users to be able to edit this date, then you need to:
Keep the input field disabled <input disabled> (no need to use ng-disabled here, because you want to keep it always disabled). And also remove this line: $('#data').attr('disabled', false); in your function.
You the one-way binding, instead of two0way binding, like this: <input disabled ng-value="date">
Here is the working DEMO that shows two inputs: one that is editable and another that is not.
The code/demo is at https://stackblitz.com/edit/angular-jx7fdu
I am trying to create a nested Reactive Form. It is a simple signup form. It has Firstname, Lastname, email, Password and VerifyPassword Field. I have also created validators for the fields. The html also assigns Bootstrap's classes depending on whether a field has errors or not.
<input id="firstname" type="text" class="form-control" formControlName="firstName" [ngClass]="validateField(signupForm,'firstName')" >
<app-show-errors [control]="signupForm.controls.firstName"></app-show-errors>
validateField in helper.service.ts assigns Bootstraps is-valid and is-invalid classes for visual representation. app-show-errors component gives texttual representation of the error.
For verify password, I want to check that its value is same as that of password field. To do this, I have clubbed them into a FormGroup and am passing that FormGroup to the validator function.
In signup-component.component.ts
createForm(){
this.signupForm = this.fb.group({
firstName:[null,[Validators.required,this.helper.validateName]], lastName:[null,[Validators.required,Validators.pattern(/[A-Za-z]+/)]],
email:[null,[Validators.required,Validators.pattern(this.EMAIL_PATTERN)]],
/*new group for password and verify password. Each of them should match the password criteria and the group should validate that the values of password and verify password is same*/
passwordGroup:this.fb.group({
password:[null,[Validators.required,Validators.minLength(8),this.helper.validatePassword]], confirmPassword:[null,[Validators.required,Validators.minLength(8),this.helper.validatePassword]]
},{validator:this.helper.confirmPasswordValidator})
});
}
Now my main issue is that I am unable to get the nested form (passwordGroup) working. I am seeing the following error in the console.
ERROR Error: formGroup expects a FormGroup instance. Please pass one in.
Example:
<div [formGroup]="myGroup">
<input formControlName="firstName">
</div>
In your class:
this.myGroup = new FormGroup({
firstName: new FormControl()
});
Change your
<div class="form-group" [formGroup]="passwordGroup">
into
<div class="form-group" formGroupName="passwordGroup">
Nested form groups use formGroupName
You can find more documentation here
I am using angular 5
In my html I generate the value of a input field using
<input type="number" class="form-control" id="unitCost" name="unitCost" [(ngModel)]="unitCost" placeholder="Average Unit Price">
document.getElementById("unitCost").value = avgVal;
then I want to retrieve that generated value in my component.ts using
this.unitCost = form2.value.unitCost;
But it returns null value. instead if I type any value in the text field it works fine and returns the value I typed. Can I solve this issue?
the best way to achieve what you want is
<input type="number" class="form-control" id="unitCost" [(ngModel)]="unitCost" placeholder="Average Unit Price">
now in your component class you will have a variable called unitCost and you can get or set the value of the text field like this
setting value - unitCost = 'value'
gettingValue - unitCost
let me know if this is clear or i will create an example for you
Use [ngValue] directive of angular.
<paper-input
id="server"
floatinglabel=""
label="Server Address"
value=""
required
type="URL">
</paper-input>
the example above worked until the latest polymer update now even the required attribute does nothing. was there some change to core-input that i am missing in documentation? all my inputs with patterns, numbers, urls, or emails nothing causes it to get the invalid class.
<paper-input-decorator
id="address"
labelVisible
floatinglabel
error="URL Required"
label="Server Address">
<input is="core-input" type="URL" id="server" required>
</paper-input-decorator>
above is the updated markup for checking input of url. before the changes the input had invalid by default cause the field was required and updated as you type.
with the new changes you have to call a function to get the input to return the invalid class. (you could put a event listener on the input and run that function every time the input is updated. but i only check on attempted submission) to check i put all the inputs i want to check in a container (a div with a id) then when user click to submit i run the function below.
validate: function (id) {
'use strict';
var $d = document.getElementById(id).querySelectorAll('paper-input-decorator');
Array.prototype.forEach.call($d, function(d) {
d.isInvalid = !d.querySelector('input').validity.valid;
});
}
and pass in the id of the input container. validate(id);
that will cause the input to display the invalid class if input doesn't meet type / pattern requirement. you can then check for invalid class in the same method as before.
invalid = document.querySelector("#address").classList.contains("invalid");
outside a custom element or
invalid = this.$.address.classList.contains("invalid");
inside custom element
then some logic to check for invalid class before running the save function
if (!invalid) {
save();
}
also keep in mind that the decorator and input both have a id. the id on the decorator is used to check for validity while the id on the input is there for getting the value from the committedValue attribute.
info above is for the master branch pulled after 10 - 16 - 14