Angularjs + bootstrap css, $invalid property doesn't work, whats wrong? - angularjs

I've a form with input controls which I need validate, but the angularjs validation doesn't work as I expected, something I'm doing wrong
This is a control of my form, between tags
<form id="addServiceForm" name="addServiceForm">
<div class="form-group has-feedback" ng-class="{'has-error': addServiceForm.qty.$invalid && addServiceForm.qty.$dirty}">
<label class="control-label" for="qty">Cantidad</label>
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-shopping-cart"></i></span>
<input id="qty" name="qty" type="text" class="form-control" placeholder="Ingresa cantidad" ng-model="service.quantity" ng-required="true"/>
</div>
<span ng-show="addServiceForm.qty.$invalid && addServiceForm.qty.$dirty" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
<span ng-show="addServiceForm.qty.$invalid && addServiceForm.qty.$dirty" id="helpBlockQty" class="help-block">La cantidad es requerida.</span>
</div>
</form>
If I assign ng-class = "'has-error'" directly it works as expected, but when I put conditions like this:
ng-class="{'has-error':addServiceForm.description.$invalid && addServiceForm.description.$dirty}"
Nothing occurs, it doesn't works as I need.
I'm begginer using angularjs and bootstrap, please be patient with me =(

The problem with your code is that there is no condition set on your input such as ng-minlength to tell Angular when .$valid or .$invalid should return true. So Angular just defaults to ng-minlength="1" and the error is never displayed inless you delete all letters.
You should also look into the $submitted method, it is very nice for form validation.
<form id="addServiceForm" name="addServiceForm">
<div class="form-group has-feedback" ng-class="{'has-error': addServiceForm.qty.$invalid && addServiceForm.qty.$dirty}">
<label class="control-label" for="qty">dirty: {{addServiceForm.qty.$dirty}} invalid: {{addServiceForm.qty.$invalid}}</label>
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-shopping-cart"></i></span>
<input id="qty" name="qty" type="text" class="form-control" placeholder="Ingresa cantidad" ng-model="service.quantity" ng-required="true"
ng-minlength="4"/>
</div>
<span ng-show="addServiceForm.qty.$invalid && addServiceForm.qty.$dirty" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true">
Another Div
</span>
<span ng-show="addServiceForm.qty.$invalid && addServiceForm.qty.$dirty" id="helpBlockQty" class="help-block">La cantidad es requerida.</span>
</div>
</form>

finally I could resolve the problem, for a unknown reason the form could not be positioned immediately after the div with the controller inside. I just moved the code at last part of my html before the closing div, and with this move my form works exactly as I need.
Thanks for all your comments and recommendations.
If someone knows why this is necessary, I hope you share.
Regards

Related

On Textbox focus open Popup AngularJs

I have a textbox in AngularJs form. Currently I am using ng-change to open a modal pop-up. However, I would like to open the pop-up, when the focus hits the textbox. Below is the current code:
<div class="form-group col-lg-6">
<div class="input-group col-md-6">
<span class="input-group-addon">
<i class="glyphicon glyphicon-search"></i>
</span>
<input type="text" class="form-control" required="" placeholder="Search the group" ng-model="searchDatalocation" ng-change="searchUsers()" name="searchValue">
</div>
</div>
<span style="color:red" ng-show="submitted == true && mainForm.searchValue.$error.required">Data is required</span>
How to open pop-up on focus? Is there any other event which can be used other than ng-change?
Thanks
try ng-focus="searchUsers()" instead of ng-change="searchUsers()"

Toggle class on input depending on input's value

I am still new to Angular but I have an existing application that uses Angular 1.5 pretty heavily.
I have a basic form that I need to add a class to depending on the following criteria:
The form can only have an End Date value or an Active for value. It cannot have both. I was thinking I need to disable the input box of the input not being used.
Ex. If a user inputs a date into the End Date input, then the Active for input will become disabled.
I looked into ng-if but every example I came across was for checking if the entered input variable was empty or equal to a value in a .js controller, not checking if the current entered variable was equal to another entered variable in the form.
<div class="form-group">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
Here is a screenshot of my modal where this happens. Ignore the other inputs as they are not affected by the conditions I've laid out.
Thanks
Form Screen Shot
You can use ng-disabled.
//initialize your dates with null
$scope.updatePatientLabel = {};
$scope.updatePatientLabel.active_end_date = null;
$scope.updatePatientLabel.expiration_time_number = null;
HTML:
<input id="endDate" ng-disabled="updatePatientLabel.expiration_time_number !== null" ng-model="updatePatientLabel.active_end_date" />
<input id="activeDate" ng-disabled="updatePatientLabel.active_end_date !== null" ng-model="updatePatientLabel.expiration_time_number" />
You have a few options. Classes, as you mentioned, or ng-if. The ng-if seems more elegant, like so:
<div class="form-group" ng-if="updatePatientLabel.active_end_date != ''">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group" ng-if="updatePatientLabel.expiration_time_number > 0">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
Otherwise, you could do an inline conditional outputting "hidden" inside the class attribute only if the value is not present. Something like this:
<div class="form-group {{updatePatientLabel.active_end_date != '' ? '' : 'hidden'}}">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group {{updatePatientLabel.expiration_time_number > 0 ? '' : 'hidden'}}">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
I use both in my projects, and either way is perfectly acceptable. Though, ng-if does seem more elegant and a bit more suited for this scenario.

ng-required not working as expected if parent div is hidden conditionally

In my code I am using ng-show and ng-required in combination. But, ng-required is not working as expected even when the respective $scope variable value is set to false. Please find the code below
<div role="form" name="selectQuestionsForm" id="selectQuestionsForm" ng-form>
<div class="form-group col-sm-12">
<label class="control-label question-answer-label"
for="firstQuestionSelect">First question</label>
<div>
<select class="form-control nopadding">
<option value="">-- Select --</option>
</select>
</div>
<div ng-show="showCustomQuestion.first" >
<input type="text" class="form-control" ng-model="questionsText.first" ng-required="showCustomQuestion.first"
id="firstQuestionInput" name="firstQuestionInput" validation-min-length="3" validation-max-length="100" />
</div>
<label class="control-label question-answer-label"
for="firstAnswerInput">First answer</label>
<div style="padding-bottom: 15px;">
<input type="text" class="form-control" ng-model="answersText.first"
id="firstAnswerInput" validation-min-length="3" validation-field-required="true" validation-max-length="100" required/>
</div>
</div>
</div>
<div id="securityActionBtnContainer" class="visible-md visible-sm visible-lg">
<button id="saveBtn" type="button" ng-disabled="selectQuestionsForm.$invalid" class="btn btn-default btn-xs pull-right" ng-click="saveQuestion(selectQuestionsForm.$valid)">Save</button>
<button id="cancelBtn" type="button" class="btn btn-xs btn-default pull-right" style="margin-right: 10px;" ng-click="redirect['cancel']()">Cancel</button>
</div>
The select element have a logic to display the option and it is working fine. When we select the option 'Write my own question', the hidden input is displayed. If user choose any other question the custom question input is hidden and not part of the form element. But ng-required is still getting applied though the value is set to the false and respective form doesn't validate.
Please let me know what I am missing to make it work. Thanks in advance for your help.
Use ng-if instead of ng-show. Items hidden using ngShow or ngHide still exist in the DOM and will be processed by angular. It's just not visible to a user.

angular validation not working

I am using angular validation on an html page, where I have defined a form along with validation on the form. However, when I run the page, all the validations I have used on the page is visible. Is there a way I can hide all the validations?
<form ng-controller="validateCtrl"
name="loginForm" novalidate>
<p>UserName:<br>
<input type="text" name="uName" ng-model="uName" required>
<span style="color:red" ng-show="loginForm.uName.$dirty && loginForm.uName.$invalid && loginForm.uName.$error.required">
Username is required
</span>
</p>
<p>Password:<br>
<input type="text" name="pwd" ng-model="pwd" required>
<span style="color:red" ng-show="loginForm.pwd.$dirty && loginForm.pwd.$invalid">
<span ng-show="loginForm.pwd.$error.required">Password is required.</span>
</span>
</p>
<p>
<input type="submit" ng-click="popupuser()"
ng-disabled="loginForm.$invalid ">
</p>
</form>
<script src="https://code.angularjs.org/1.2.3/angular.min.js"></script>
Your code for form is fine please see here http://jsbin.com/figuve/1/edit
Make sure that your validateCtrl exist otherwise validation will not work plase see here
http://jsbin.com/figuve/2/edit
or
remove ng-controller="validateCtrl" from your form if you don't need it.
please see here http://jsbin.com/figuve/3/edit
You can try use variable to check is form submited, like that
<span ng-show="(loginForm.uName.$dirty || isSubmitted) && loginForm.uName.$error.required">Username is required</span>

Issue with ng-model and ng-repeat, duplicate forms

I have a page where multiple forms are created based on ng-repeat. Everything works fine until write something into the input and everything gets duplicated on all the other repeated forms input elements. I have used ng-model="Notify.message" which is nothing but object which takes the value from the input and sends to control on button submit and hence rest of the logic.
I am looking for when if one form is been filled, other forms should keep quite and shouldn't duplicate the values written in input text of form 1.
Here is the code:
<div data-ng-show="alluserposts.length > 0">
<div id="b{{userpost.id}}" data-ng-repeat="userpost in alluserposts" >
<div class="row" style="margin-left: -5px">
<form class="text-center" role="form" id=f1{{userpost.id}} name="userForm"
ng-submit="notify(userForm.$valid, userpost, apiMe)" novalidate>
<div class="row">
<div class="col-xs-8 col-md-4">
<div class="form-group">
<input data-container="body" data-toggle="popover" data-placement="top"
data-content="Any message which you would like to convey to post owner"
type="text" ng-model="Notify.message" data-ng-init="Notify.message=''"
id="u{{userpost.id}}"
placeholder="Enter a Message or Phone number" class="form-control"
required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">It is
required.</p>
<script>$(function () {
$("[data-toggle='popover']").popover();
});
</script>
<input type="hidden" ng-model="Notify.loggedInEmail"
ng-init="Notify.loggedInEmail = result.email"/>
<input type="hidden" ng-model="Notify.postId" ng-init="Notify.postId = userpost.id"/>
<input type="hidden" ng-model="Notify.destEmail"
ng-init="Notify.destEmail = userpost.userEmail"/>
</div>
</div>
<div ng-show="loginStatus.status == 'connected'" class="col-xs-4 col-md-2">
<button class="btn btn-primary" ng-disabled="userForm.$invalid || !userForm.$dirty"
type="submit">
Notify Post Owner
</button>
</div>
</div>
</form>
</p>
</div>
</div>
</div>
</div>
Issue fiddle - jsfiddle
Here you can when something is written in one input, other gets filled too :( . Also Notify is a Java mapped object and message is a variable inside it. Pls let me know how can this can be segragated!
You bind all of your inputs to same variable on $scope.
You must bind every text box to a distinct variable on $scope:
View:
<ul ng-repeat="post in posts">
<li>{{$index}}
<input type="text" ng-model="emails[$index]"/>
</li>
</ul>
Controller:
$scope.emails = [];
I am also at the starting phase of angularjs.
I have faced the same issue few days ago and resolved it by providing dynamic model name in ng-model like
<input type="text" ng-model="Notify[post.userEmail]" ng-init="Notify[post.userEmail] = post.userEmail" />
Working fiddle: Fiddle

Resources