Angularjs : check if input is empty with ng-form - angularjs

My code is the following :
<ng-form name="invitationForm">
<div ng-repeat="email in emails" ng-form='lineForm'>
<div class="has-feedback" ng-class="{'has-error': lineForm.$invalid && lineForm.input, 'has-success': lineForm.input && !lineForm.$invalid}">
<label class="control-label sr-only" for="inputSuccess">Input with success</label>
<input ng-change="inputCheck($index)" id="inputSuccess" placeholder="Enter your friend's email" name="input" ng-model="email.value" class="form-control input-mini" aria-describedby="inputSuccessStatus" type="email" />
</div>
</div>
</ng-form>
What I want to do is have the div with class "has-feedback" have class "has-error" when the lineForm is invalid and the input is not empty.
I put the condition lineform.$invalid && lineForm.input but lineForm.input doesn't seem to be working.
I also tried lineForm.input.length to no avail.
Thanks

http://plnkr.co/edit/se8iBxlUK6J0oS8lUWTn?p=preview
I don't think you need to create that many forms. Check out this example (several elements with required input:
<form role="form" name="theform">
<div ng-repeat="number in [1,2,3]">
<input type="text"
name="{{$index}}"
ng-model="number"
required="" />
</div>
{{ theform.$valid ? 'yes, valid form' : 'no, invalid' }}
<br/><br/>
<div ng-repeat="element in theform">
{{ element.$valid }}
</div>
<br/>
Explore this:
<br/><br/>
{{ theform }}
</form>
For further examples on what you can do with the formController:
https://docs.angularjs.org/api/ng/type/form.FormController

Related

Ensure at least one checkbox is selected in angular

I need to validate that at least one checkbox, in 3, has been selected. I can't use radio buttons because two of the options are can be selected and exclude the third. I'm not really sure if it's best to put these checkboxes into a model array, rather than binding them to separate models and creating a longer ng-required expression. The docs aren't particularly helpful in describing what 'best practise' is for this sort of thing...
Code:
<div class="form-inline form-group">
<div class="row">
<div class="col-xs-12">
<h4 class="card-title left test-list-header">Balcony</h4>
</div>
</div>
<fieldset class="form-group">
<input type="checkbox" id="balconyBalcony" ng-model="balcony">
<label for="balconyBalcony">Balcony</label>
</fieldset>
<fieldset class="form-group">
<input type="checkbox" id="patioBalcony" ng-model="patio">
<label for="patioBalcony">Patio</label>
</fieldset>
<fieldset class="form-group">
<input type="checkbox" id="noBalcony" ng-model="noBalcony" ng-disabled="balcony || patio">
<label for="noBalcony">No</label>
</fieldset>
<fieldset class="form-group" ng-show="noBalcony && !patio && !balcony">
<div class="md-form">
<input
type="text"
id="{{ Plot::FIELD_BALCONY_NOTES }}"
class="form-control"
name="{{ Plot::FIELD_BALCONY_NOTES }}"
inline-edit
inline-edit-callback="UpdateHandler()"
ng-model="Model.BalconyNotes.Value"
ng-class="{ invalid: createPlot.balconyNotes.$invalid && submitted, valid: createPlot.floor.$valid }"
ng-init="Model.BalconyNotes.Value = '{{ old(Plot::FIELD_BALCONY_NOTES) or $Model->BalconyNotes }}'" ng-required="noBalcony">
<label for="{{ Plot::FIELD_BALCONY_NOTES }}" data-error="#{{ Model.BalconyNotes.ValidationMessage }}" class="w-100">Comments</label>
<span class="help-block" ng-show="createPlot.balconyNotes.$invalid && submitted">As there is no balcony or patio, you must enter a comment</span>
</div>
</fieldset>
You could use ng-required built in directive to validate your form.
Like this:
<form novalidate name="myForm" ng-submit="mySubmitFunc()">
<label>Checkbox 1
<input ng-required="!(cb2 || cb3)" ng-model="cb1" type="checkbox">
</label>
<label>Checkbox 2
<input ng-required="!(cb1 || cb3)" ng-model="cb2" type="checkbox">
</label>
<label>Checkbox 3
<input ng-required="!(cb1 || cb2)" ng-model="cb3" type="checkbox">
</label>
<input type="submit" ng-disabled="myForm.$invalid" value="submit">
</form>
Here is a fiddle demonstrating how to handle such logic.
You could add a validation line:
<div ng-show="myForm.$submitted">
<p style="color: red" ng-show="!myForm.balcony && !myForm.patio && !myForm.noBalcony">You must select at least one of the options above.</p>
</div>
That div shows when the user tries to submit and the p shows when none are selected.
Your button will also need an ng-disabled directive with the same condition.

How to disable submit button untill all the fields are filled in a form?

I have a form with a set of fields. My problem is, submit button is disabled initially but the moment any one of the field goes valid or non-empty button is getting enabled. Here is my source code:
<form class="aui newDiscoveryForm" name="newDiscoveryForm" ng-submit="createNewDiscovery(user)" novalidate>
<fieldset class="group">
<div class="field-group">
<label class="label">Product Name</label>
<input class="text" type="text" name="input1" ng-model="user.productName" value="" id="productName" required/>
<p ng-show="newDiscoveryForm.input1.$invalid && !newDiscoveryForm.input1.$pristine" style="color: #880000">Product name is required.</p>
<div class="error"></div>
<span class="result_product" style="color: #880000"></span>
</div>
<div class="field-group">
<input class="text" type="text" name="input2" ng-model="user.endUsers" value="" required/>
<p ng-show="newDiscoveryForm.input2.$invalid && !newDiscoveryForm.input2.$pristine" style="color: #880000">EndUsers required.</p>
<label class="label">Who are end users</label>
<div class="description">[Gamers, Engineers, Commuters, Media, Goverment]</div>
</div>
<div class="field-group">
<label for="licenseKey">What Problem Are They Facing Today</label>
<textarea class="textarea" rows="4" cols="10" name="input3" ng-model="user.problemsArea" id="problemsarea" value="" required></textarea>
<p ng-show="newDiscoveryForm.input3.$invalid && !newDiscoveryForm.input3.$pristine" >ProblemsArea required.</p>
<div class="description">Spend So much in .....</div>
</div>
<div class="field-group">
<label class="label">What kind of product is this</label>
<input class="text" type="text" name="input4" ng-model="user.productKind" id="productkind" value="" required/>
<p ng-show="newDiscoveryForm.input4.$invalid && !newDiscoveryForm.input4.$pristine" >ProductKind required.</p>
<div class="description">[Software, MobileApp, JIRA-Plugin]</div>
</div>
<div class="field-group">
<label for="d-lname">How do you plan to solve the problem</label>
<input class="text long-field" type="text" id="problemSoln" name="input5" ng-model="user.problemSoln" value="" required />
<p ng-show="newDiscoveryForm.input5.$invalid && !newDiscoveryForm.input5.$pristine" >ProblemSolution required.</p>
<div class="error"></div>
<div class="description">[Load Balancing of Personal, Automated Traffic Info]</div>
</div>
<div class="field-group">
<label for="d-lname">Who are your competitors</label>
<input class="text long-field" type="text" id="competitors" name="input6" ng-model="user.competitors" value="" required/>
<p ng-show="newDiscoveryForm.input6.$invalid && !newDiscoveryForm.input6.$pristine" >Competitors required.</p>
<div class="error"></div>
<div class="description">Traditional Commuting Solution</div>
</div>
<div class="field-group">
<label for="d-lname">How do you differntiate from your competitors</label>
<input class="text long-field" type="text" id="differentiator" name="input7" ng-model="user.differentiator" value="" required/>
<p ng-show="newDiscoveryForm.input7.$invalid && !newDiscoveryForm.input7.$pristine" >Differentiator required.</p>
<div class="error"></div>
<div class="description">[Automated, Secure]</div>
</div>
</fieldset>
<div class="buttons-container">
<div class="buttons">
<button class="aui-button aui-button-primary ap-dialog-submit" value="Submit" type="submit"
id="save-button" ng-click = "createNewDiscovery(user)" ng-disabled="newDiscoveryForm.$invalid">Save</button>
<button id="close-button" type="button" class="aui-button aui-button-link ap-dialog-cancel" ng-click = "cancelClick()">Cancel</button>
</div>
</div>
</form>
How can I make sure that submit button is disabled untill all the fields are filled.
I tried almost all the available solutions like make all the fields required, make the submit button as ./. But nothing seems to be working.
You are almost doing it right. To use angular's form validation, you have to use the angular directives for that. For example, use the ng-required instead of the normal required (though it will work, but you should use ng-required for best practices):
<form name="newDiscoveryForm">
<input type="text" name="someName"
ng-model="someModel"
ng-required="true" /> <!-- use ng-required -->
<!-- other inputs -->
<!-- $invalid will evaluate to true if the `ng-required` are not valid -->
<button type="submit"
ng-disabled="newDiscoveryForm.$invalid">
Submit!
</button>
</form>
See this JSFIDDLE

ng-pattern not working for form validation

I have tried to use a lot of regex which I found on the internet but with no luck. I am trying to validate if a form's input ranges between 0-100 (both 0 & 100 are valid inputs) but for some reason The error is not showing up. Pasting my code below
<form class="row" name="myForm">
<div ng-repeat="month in plan.months" class="form-group">
<div class="col-sm-2">{{month.label}} : </div>
<div class="col-sm-10">
<input type="text"
name="name"
ng-model="month.value"
class="form-control"
ng-pattern="/^([1-9]?[0-9])$/"
/>
<br />
</div>
<span class="error" style="color:red" ng-show="myForm.name.$error.pattern">Please enter a Percentage value between 1 & 100</span>
</div>
</form>
try this,
<form class="row" name="myForm">
<div ng-repeat="month in plan.months" class="form-group">
<div class="col-sm-2">{{month.label}} : </div>
<div class="col-sm-10">
<input type="text"
name="name"
ng-model="month.value"
class="form-control"
ng-pattern="/^([0-9]|[1-9][0-9]|[1-9][0-9][0])$/"
/>
<br />
</div>
<span class="error" style="color:red" ng-show="myForm.name.$error.pattern">Please enter a Percentage value between 1 & 100</span>
</div>
</form>
Also refer this
Is there a reason you're using a text input rather than a number input?
If not, try this:
https://jsfiddle.net/kqupg84y/
<form class="row" name="myForm">
<div class="col-sm-2">{{month.label}} : </div>
<div class="col-sm-10">
<input type="number"
name="name"
ng-model="month.value"
class="form-control"
min="0"
max="100"
/>
<br />
</div>
<span class="error" style="color:red" ng-show="myForm.name.$error.pattern">Please enter a Percentage value between 1 & 100</span>
{{myForm.$error}}
(i removed ng-repeat for simplicity of fiddle)
That doesn't answer your question about using an ng-pattern though.
That being said, your regex may just be a bit off. rather than
/^([1-9]?[0-9])$/
you could try:
/^[0-9]+$/
if you're trying to match any number between 0 and 100.
Your regex looks like it's trying to match any number that is between 1 and 9, potentially followed by any other number... but if you're trying to make it inclusive of 0 and 100, i'm not sure it works as expected.
The tool I generally use for checking my regular expressions is:
http://regexr.com/
Your problem is that multiple inputs in your form have the same name. You need to add some uniqueness to the input names. A quick and dirty way to make form element names unique is to bind the name property to an expression that uses the $index of the ng-repeat like name="month{{$index}}. Then you can use Javascript's bracket notation to access the correct form element from the form controller:
<div ng-repeat="month in plan.months" class="form-group">
<div class="col-sm-2">{{month.label}} : </div>
<div class="col-sm-10">
<input type="text"
name="month{{$index}}"
ng-model="month.value"
class="form-control"
ng-pattern="/^[1-9]?[0-9]$|^100$/"
/>
<br />
</div>
<span class="error" style="color:red"
ng-show="myForm['month' + {{$index}}].$error.pattern">
Please enter a Percentage value between 1 & 100
</span>
</div>
Here's a plunker demonstrating this in action. As an aside, your pattern incorrectly failed the string "100", so I added an alternative to the regex.
It's because you cannot use a regular form with ng-repeat because of multiple inputs with the same name. Use ng-form inside ng-repeat to get isolated forms.
Also if you want numbers, just use input type=number with min and max values instead of using ng-pattern.
See working example https://jsfiddle.net/asimgeker/yjmoLtvv/
<div ng-app>
<div ng-controller="MyCtrl">
<div ng-repeat="month in months" class="form-group">
<ng-form name="myForm">
<div class="col-sm-2">{{month.label}} : </div>
<div class="col-sm-10">
<input type="number" min="0" max="100" name="myName" ng-model="month.value" class="form-control" />
<br />
</div>
<div style="color: red" ng-show="myForm.myName.$error.max">Should be less than 101</div>
<div style="color: red" ng-show="myForm.myName.$error.min">Should be greater than -1</div>
</ng-form>
</div>
</div>
</div>
#anurag -- the Solution you provided worked for numbers above 100 but was failing for below 0 numbers
& #andrew -- The same with your solution, was not throwing a validation error unless I enter -100 (ng-maxlength = 3) is working but that is not how we need it.
The original issue was with my Regex, finally the code that worked for me is
<form class="row" name="myForm">
<div class="col-sm-2">{{month.label}} : </div>
<div class="col-sm-10">
<input type="number"
name="percent_monthly_targets"
ng-model="month.value"
class="form-control"
ng-pattern="/^[0-9][0-9]?$|^100$/"
/>
<br />
<span class="alert alert-danger" ng-show="myForm.percent_monthly_targets.$error.pattern">Please enter a Percentage value between 1 & 100</span>
</div>
</form>

Cannot clear form

I am trying to reset the form after the submit button is clicked. I understand that setting the form to pristine alone should not clear the input fields. I tried implementing the various suggestions to clear form by setting the form to pristine and then assigning null to all input fields. Is there a more neat way to implement it ?
Template:
<p>{{contactForm.$pristine}}</p>
<div class="inBox">
<form name="contactForm" novalidate>
<div class="form-group" ng-class="{ 'has-error' : contactForm.name.$invalid && !contactForm.name.$pristine }">
<label>Name</label>
<input type="text" ng-model="tabVm.name" class="form-control" name="name" required>
<p ng-show="contactForm.name.$invalid && !contactForm.name.$pristine" class="help-block">You name is required.</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.email.$invalid && !contactForm.email.$pristine }">
<label>Email</label>
<input type="email" ng-model="tabVm.email" name="email" class="form-control" required>
<p ng-show="contactForm.email.$invalid && !contactForm.email.$pristine" class="help-block">Enter a valid email.</p>
</div>
<div class="form-group">
<label>Contact Number</label>
<input type="tel" ng-model="tabVm.number" class="form-control">
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.message.$invalid && !contactForm.message.$pristine }">
<label>Message</label>
<textarea type="text" rows="5" ng-model="tabVm.message" name="message" class="form-control textBox" required></textarea>
<p ng-show="contactForm.message.$invalid && !contactForm.message.$pristine" class="help-block">Brief message is required.</p>
</div>
</form>
<button type="submit" ng-click="sendMsg()" class="btn large-btn"
ng-disabled="contactForm.message.$invalid || contactForm.name.$invalid||contactForm.email.$invalid " >Send</button>
</div>
app.js
$scope.contactForm.$setPristine();
and I also tried
$scope.contactForm.$pristine=true;
Neither of them seem to work. I use angular 1.4.8.
Thank you.
You should use $setPristine() and then reset the ng-model object. Also pay attention you have the submit button outside the <form>.
This is a working JSFiddle (I used only one input for example)
$scope.sendMsg = function() {
$scope.contactForm.$setPristine();
$scope.tabVm = {};
}
You referenced controlForm, but the html you posted have contactForm
I finally got it working by making the following changes :
<div class="container box col-lg-6" >
<p>{{contactForm.$pristine}}</p>
<p>name state: {{contactForm.name.$pristine}}</p>
<div class="inBox">
<form name="contactForm" ng-submit="sendMsg(contactForm)" novalidate>
<div class="form-group" ng-class="{ 'has-error' : contactForm.name.$invalid && !contactForm.name.$pristine }">
<label>Name</label>
<input type="text" ng-model="tabVm.name" class="form-control" name="name" required>
<p ng-show="contactForm.name.$invalid && !contactForm.name.$pristine" class="help-block">You name is required.</p>
</div>
<input type="submit" class="btn large-btn"
ng-disabled="contactForm.message.$invalid || contactForm.name.$invalid||contactForm.email.$invalid " >
</form>
</div>
</div>
and app.js :
$scope.sendMsg=function(form){
if(form.$valid){
console.log("Form is valid"); //this was a check I used to confirm that the controller recognized the form.
}
form.$setPristine();
tabVm.name="";
}
}
I do not clearly understand why this works or what was I doing wrong earlier. I would appreciate if anyone could explain. Thank you.
Do as follows
$scope.sendMsg = function(){
//your function code
$scope.tabVm={};
$scope.tabVm.name='';
$scope.tabVm.email='';
$scope.tabVm.number='';
$scope.tabVm.message='';
}

ng-disabled is not working

This might be a silly question. But I just started experimenting with AngularJS. Can someone point out what I'm doing wrong in validation. The button is not disabled even when the fields are invalid.
What's the difference between
ng-disabled="myForm.$invalid" and
ng-disabled="myForm.cuisine.$invalid || myForm.title.$invalid || myForm.description.$invalid || myForm.cost.$invalid"
I think using myForm.$invalid is a cleaner way of disabling the button. Any tips?
<form name="myForm">
<div class="form-group">
<select ng-required="true" name="cuisine" ng-model="model.food.cuisine" class="form-control" type="text">
<option ng-repeat="c in model.cuisines" value="{{c}}">{{c}}</option>
</select>
<p ng-show="myForm.cuisine.$invalid && myForm.cuisine.$touched">
Please select cuisine type.</p>
</div>
<div class="form-group">
<input ng-required="true" name="title" ng-minlength="4" ng-maxlength="25" ng-model="model.food.title"
type="text" class="form-control">
<p ng-show="myForm.title.$invalid && myForm.title.$touched">Please pick a valid title with atleast 4
characters.</p>
</div>
<div class="form-group">
<textarea ng-required="true" name="description" ng-minlength="10" ng-maxlength="255"
ng-model="model.food.description" type="text" class="form-control"></textarea>
<p ng-show="myForm.description.$valid && myForm.description.$touched">Please describe your food with 10 - 255
characters.</p>
</div>
<div class="form-group">
<input name="cost" ng-pattern="/0-9/" ng-required="true" min="1" ng-model="model.food.cost" type="number"
class="form-control" placeholder="Cost">
<p ng-show="myForm.cost.$error.pattern">Please enter a valid number</p>
<p ng-show="myForm.cost.$invalid && myForm.cost.$touched">Please enter cost of food item.</p>
</div>
<div class="form-group">
<button ng-disabled="myForm.$invalid" class="btn btn-success btn-block">Add Food</button>
</div>
</form>
Apparently, validations don't work if the form element is inside the body of a table.
It works fine if I moved the form tag outside the table.
Thanks everyone.

Resources