How to validate input field inside ng-repeat - javascript

I want to validate an input field where i want to be able to check whether the current input is greater than the previous input.
Here is what i mean
<div class="col-xs-10" ng-repeat="period in trim.rent_period" >
<div class="col-xs-6">
<div class="form-group">
<label class="col-xs-5 control-label" for="rentperiod">Rental Period
<span class="colon--label">:</span>
</label>
<div class="col-xs-6">
<input id="rentperiod" name="rentperiod" type="text" class="form-control" ng-model="rent.period" ng-change="checkRentPeriod($index);" required>
</div>
</div>
</div>
</div>
<div class="col-xs-2">
<i class="pull-left fa fa-plus-circle add-rent--icon" ng-click="addRent(currentIndex);"></i>
</div>
Here the add button adds an input into the list , and i want to make sure that the current input is greater than the previous input.

Try to wrap your code with form tag. And then check for validation of form if everything is okay. You can do this by following this guide here as a way to solve your question
https://docs.angularjs.org/guide/forms

change your ng-model="rent.period" to correct, something starting from "period", like ng-model="period.rent"
no need for extra method ng-change="checkRentPeriod($index);"
add that simple block after input:
<span ng-if="$index > 0 && period.rent && period.rent > trim.rent_period[$index - 1].rent">
Rent is greater than {{trim.rent_period[$index - 1]}}
</span>

Related

ngIf an angular reactive form component value

I have a set of radio buttons. If a user selected the value "yes" I want to show an additional box on the form.
https://stackblitz.com/edit/angular-4bgahw?file=src/app/personal/personal.component.ts
HTML.component
<div formGroupName="radioButtonsGroup" class="form-group col-6 pl-0 pt-3">
<div class="form-check-inline" *ngFor="let item of personal.radioButtonsdata">
<label for="{{item.section}}" class="col-12 customradio"
><span>{{item.section}}</span>
<input [value]="item" id="{{item.section}}" type="radio" formControlName="selectedButton"/>
<span class="checkmark"></span>
</label>
</div>
<!-- <div class="col-md-8" *ngIf="selectedButton.control.item === 'yes'"> --> //my attempt to target above input value
<div class="col-md-8" >
<input type="text" formControlName="title" class="form-control" placeholder="Title">
</div>
</div>
Can anybody get this to work and show me what I am doing wrong here please?
You need to access the value of the form control:
*ngIf="form.get('radioButtonsGroup.selectedButton').value.section === 'yes'">
STACKBLITZ
Everything you write in the template is resolved against the corresponding class (or against template variables), so you have to refer to the JavaScript control like this:
*ngIf="form.controls['selectedButton'].value === 'yes'"
Call a function to set flag based on value of the radio button, (ngModelChange)="onRadiochange($event)"
Try like this:
Working Demo
.html
<input [value]="item" (ngModelChange)="onRadiochange($event)" id="{{item.section}}" type="radio" formControlName="selectedButton" />
<div class="col-md-8" *ngIf="showTitle">
<input type="text" formControlName="title" class="form-control" placeholder="Title">
</div>
.ts
onRadiochange(e) {
if(e.section == 'yes'){
this.showTitle = true
} else {
this.showTitle = false
}
}
It can also be done in one line like this:
<input [value]="item" (ngModelChange)="$event.section == 'yes' ? showTitle=true:showTitle=false" id="{{item.section}}" type="radio" formControlName="selectedButton" />
Whenever yes checkbox is selected, you have to display the title textbox.
In that case, change your code like this.
In personal.component.ts, add this variable.
yesSelected: boolean = true;
Also in ngOnInit(),
this.form.valueChanges.subscribe(val=>{
if(val.radioButtonsGroup.selectedButton.section === "yes")
this.yesSelected = true;
else
this.yesSelected = false;
});
In personal.component.html, rewrite your if condition like this.
<div class="col-md-8" *ngIf="yesSelected">
<input type="text" formControlName="title" placeholder="Title">
</div>
These changes will show the title textbox only when the yes check box is selected.

Razor View - jQuery .val() is updating some components visually -- but not all

I have a search feature built into a page that hits an API to get a list of items if a user chooses to search instead of manually enter (in an attempt to get some clean data). I have the first column of said table set to call a JavaScript function onclick. That function looks similar to this:
function loadDataFromTable(fname, lname, mname, stn, grade, school) {
$('#StudentFirstName').val(fname);
$('#StudentLastName').val(lname);
if (mname !== "undefined") {
$('#StudentMiddleName').val(mname);
}
else {
$('#StudentMiddleName').val('');
}
$('#StudentNumber').val(stn);
$('#Grade').val(grade);
$('#School').val(school);
return false;
}
The associated HTML elements are all ASP.NET Core Razor View input elements. They look like this:
<div class="form-group">
<label class="col-md-3 control-label">Last Name</label>
<div class="col-md-9">
<input type="text" asp-for="StudentLastName" class="form-control" />
<span asp-validation-for="StudentLastName" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">STN</label>
<div class="col-md-9">
<input type="text" asp-for="StudentNumber" class="form-control" />
<span asp-validation-for="StudentNumber" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Grade</label>
<div class="col-md-9">
<input type="text" asp-for="Grade" class="form-control" />
<span asp-validation-for="Grade" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="School" class="col-md-3 control-label"></label>
<div class="col-md-9">
<select asp-for="School" asp-items="ViewBag.SchoolList" class="form-control"></select>
<span asp-validation-for="School" class="text-danger"></span>
</div>
</div>
Now, if a user clicks on one of the links from the table, all of the values are properly passed into the function, and all of the values for First Name, Last Name, Middle Name, and STN properly update on the view. Grade and School do not update on the View, but their value attribute does update. When I submit the form after the data fills, the correct values are passed to my controller.
What I can't figure out is why the Grade and School values are not populating on the view. The only thing that stands out as different for these two are within the model they are nullable integers, whereas other fields are strings.
I have tried a mixture of .attr('value', grade), .text(grade), and .val(grade), and none of them are working. I can verify that the proper elements are being selected because if I output $('#Grade') I get the input object.

Angular: Why does field $invalid is true in other view?

I have added some condition to show my revision field. Basically it will accept a number and a required field , so i added some validation check. I have excluded this field from 'edit' view. and for that i specified condition as well.
ng-show="editMode=='addNew' || editMode=='addDate'"
even though in edit view my field is not showing up.. but somewhere $invalid is becoming true for all view
<div class="form-group" ng-show="editMode=='addNew' || editMode=='addDate'">
<label for="editmyRevision" ng-class="{'col-sm-3':editMode=='addNew'}" class="col-md-2 control-label">Revision</label>
<div ng-class="{'col-sm-9':editMode=='addNew'}" class="col-md-10">
<input class="form-control" ng-model="editmyRevision"name="revision" ng-required="editMode=='addNew' || editMode =='addDate'" ng-maxlength="5" ng-Pattern="/^[0-9]*$/"></input>
<span class="has-error help-block" data-ng-show="prodEdit.revision.$invalid">Acceptable formats: 100~99999</span>
</div>
</div>
What am i doing wrong here?
ng-show will not remove the input from the form. It will just set display:none style to it, so it will still make the form invalid.
Try using ng-if instead.
<div class="form-group" ng-if="editMode=='addNew' || editMode=='addDate'">
Many error syntax in your code. $invalid apply for form not input.
Change:
<input class="form-control" ng-model="editmyRevision"name="revision" ng-required="editMode=='addNew' || editMode =='addDate'" ng-maxlength="5" ng-Pattern="/^[0-9]*$/"></input>
<span class="has-error help-block" data-ng-show="prodEdit.revision.$invalid">Acceptable formats: 100~99999</span>
To:
<input class="form-control" ng-model="editmyRevision" name="revision" ng-pattern="/^[0-9]{3,5}$/"/>
<span class="has-error help-block" data-ng-show="prodEdit.revision.$error">
Acceptable formats: 100~99999
</span>

textbox validation for number and required in repeating mode angular js

Please refer below link
https://plnkr.co/edit/9HbLMBUw0Q6mj7oyCahP?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.NDCarray = [{val: ''}];
$scope.NDCadd = function() {
$scope.NDCarray.unshift(
{val: ''}
);
};
$scope.data = angular.copy($scope.NDCarray);
$scope.NDCcancel=function(){debugger
$scope.NDCarray=$scope.data;
}
$scope.NDCdelete = function(index) {
if(index != $scope.NDCarray.length -1){
$scope.NDCarray.splice(index, 1);
}
};
});
It contains the textbox with add button. I have added validation for number and required field, it is working fine. but when i click add button it will create another textbox with entered value that time it showing the validation message for all the textboxes , i don't want to show validation message for all the textboxes. need to show validation for corresponding textbox only. that means when i enter something wrong in second textbox it is showing message to that textbox only.refer below screenshot.
validation message displaying for all textboxes.that should display for only one textbox.
Working plnkr : https://plnkr.co/edit/f4kAdZSIsxWECd0i8LDT?p=preview
Your problem is in your HTML, to get independant fields you must :
Move outside the form of the ng-repeat
Provide a dynamic name using $index on your fields, because name is what make each fields independant on the validation.
Here is the final HTML from the plnkr i didn't touch at all the javascript :
<body ng-controller="MainCtrl">
<form name="myForm">
<div ng-repeat ="ndc in NDCarray">
<div class="col-sm-4 type7" style="font-size:14px;">
<div style="margin-bottom:5px;">NDC9</div>
<label>Number:
<input type="number" ng-model="ndc.value"
min="0" max="99" name="{{'input_'+$index}}" required>
</label>
<div role="alert">
<span class="error" ng-show="myForm.input.$dirty && myForm.input.$error.required">
Required!</span>
<span class="error" ng-show="myForm.input.$error.number">
Not valid number!</span>
</div>
<tt>value = {{example.value}}</tt><br/>
<tt>myForm['input_{{$index}}'].$valid = {{myForm['input_'+$index].$valid}}</tt><br/>
<tt>myForm['input_{{$index}}'].$error = {{myForm['input_'+$index].$error}}</tt><br/>
</div>
<div class="col-sm-4 type7 " style="font-size:14px;">
<div style="padding-top:20px; display:block">
<span class="red" id="delete" ng-class="{'disabled' : 'true'}" ng-click="NDCdelete($index)">Delete</span>
<span>Cancel </span>
<span id="addRow" style="cursor:pointer" ng-click="NDCadd()">Add </span>
</div>
</div>
</div>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
</form>
</body>
Couple of changes:
If you add "track by $index" to your ng-repeat it will make each group of elements unique so that you don't have to worry about deriving unique names for elements.
Your validation on the number (myForm.ndcValue.$error.number) didn't work so I changed it to myForm.ndcValue.$error.max || myForm.ndcValue.$error.min
Also, you can throw an ng-form attribute directly on the div with your ng-repeat.
Like this:
<div ng-repeat="ndc in NDCarray track by $index" ng-form="myForm">
<div class="col-sm-4 type7" style="font-size:14px;">
<div style="margin-bottom:5px;">NDC9</div>
<label>Number:
<input type="number" ng-model="ndc.value" min="0" max="99" name="ndcValue" required>
</label>
<div role="alert">
<span class="error" ng-show="myForm.ndcValue.$dirty && myForm.ndcValue.$error.required">
Required!</span>
<span class="error" ng-show="myForm.ndcValue.$error.max || myForm.ndcValue.$error.min">
Not valid number!</span>
</div>
<tt>value = {{example.value}}</tt>
<br/>
<tt>myForm.ndcValue.$valid = {{myForm.ndcValue.$valid}}</tt>
<br/>
<tt>myForm.ndcValue.$error = {{myForm.ndcValue.$error}}</tt>
<br/>
</div>
Here's the working plunker.
I changed the input element name from "input" to "ndcValue" to be less confusing.

Angular JS: ngShow isn't binding my change

I've got an Angular module here within a larger rails project. I'm new to Angular and wish to avoid jQuery if I can (but do use it throughout the rails project and can use it if necessary). What I'm trying to do is hide a checkbox if the End Time is "", and show a checkbox if there's a value in the End Time. Unfortunately I have been unable to hide it if End Time is "". See:
You can see my HTML code below:
<div class="control-group span8">
<h4 class="pull-left"><strong>Active Hours (UTC):</strong></h4>
</div>
<div class="control-group span1">
<label class="control-label label-unstyled font-size-14" for="inputStartTime">Start Time</label>
<div class="controls">
<select ng-model="geoRegion.start_time" id="inputStartTime" class="input-small" ng-options="thisHour.value as thisHour.name for thisHour in hours" value="{{geoRegion.start_time}}"></select>
</div>
</div>
<div class="control-group span1">
<label class="control-label label-unstyled font-size-14" for="inputEndTime">End Time</label>
<div class="controls">
<select ng-model="geoRegion.end_time" id="inputEndTime" class="input-small" ng-options="thisHour.value as thisHour.name for thisHour in hours" value="{{geoRegion.end_time}}"></select>
</div>
</div>
<div class="control-group span8">
<div ng-show="clearGeoSegment(geoRegion.end_time)"><label class="inline checkbox label-unstyled font-size-14"><input type="checkbox" id="clearGeoSegment" ng-model="geoRegion.clear_segment">Clear Geo Segment at end of active time period.</label></div>
</div>
<div class="control-group span8">
<p id="broadcast-notice" class="pull-left font-size-14"><strong>Note:</strong> If active hours is blank, the Geo Segment is always active.</p>
</div>
My controller code (yes, I used jQuery. But please suggest otherwise!):
$scope.clearGeoSegment = (endTime) ->
if endTime is ''
$('#clearGeoSegment').hide()
else
$('#clearGeoSegment').show()
Any help would be greatly appreciated!
So you don't need to do the hide/show with jquery. You need to just bind to an expression that will be truthy when the checkbox should be visible. In this case it should be as simple as:
<div ng-show="geoRegion.end_time">
And you can delete your clearGeoSegment function entirely.

Categories