I'm trying to apply the datepicker from angular ui in my application but for some reason it results in the following error:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.3.15/$rootScope/infdig?p0=10&p1=%5B%5D
I don't understand why this error is triggered because. In the link above the description reads:
This error occurs when the application's model becomes unstable and
each $digest cycle triggers a state change and subsequent $digest
cycle. Angular detects this situation and prevents an infinite loop
from causing the browser to become unresponsive.
I don't see how this is applicable to my situation at all.
If I'm using a regular input field like this:
<input type="text" class="form-control" id="my-date" name="myDate" data-ng-model="ctrl.myDate"
data-ng-model-options="{updateOn: 'blur'}" data-ng-change="ctrl.changeDetected()" >
There's no problem and the date is displayed just fine, but this:
<p class="input-group">
<input type="text" class="form-control" datetime-picker="'yyyy-MM-dd'" data-ng-model="ctrl.myDate" data-is-open="ctrl.isOpen" data-enable-time="false" data-show-button-bar="false" data-timepicker-options="ctrl.dateOptions" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" data-ng-click="ctrl.openCalendar($event, date)"><i class="fa fa-calendar"></i></button>
</span>
</p>
will result in the error. Can someone smarter than me give me a pointer as to what it is that I'm missing. I'm just loading the date from the backend and trying to display it as the current date in a datepicker.
/Regards Kris
Sorry, apparently I'm a dumbass. there's nothing wrong with the datepicker and the code above. I had missed that the surrounding div was using a validation directive that was bound to the name attribut of the input field and I forgot to add this name attribut to the corresponding datepicker input field.
Related
I'm trying to learn forms in AngularJS 1.x. But I have error messages that are always on when it first loads. How to develop behaviour such that they are blank on load, and only red after a submit if fields were not entered? Seems to be a few states I have to use the built-in directives for.
All the elements are similar so let's just take apart this bit. Also if different for a radio and dropdown list maybe we can discuss that too.
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required">The first name is required.</span>
</p>
Do I chain a few directives with || or && ?
Behaviour I'm aiming for
How to keep the error messages off when it loads?
when I hit submit, and a field is blank, will it then activate the css red error messages?
I'd like the error messages to clear as I fill in the form without reloading.
Yeah, so any tips greatly appreciated. Doesn't have to be particularly pretty
Thanks
UPDATE 1
gist of current code
Well I took a stab at it. Still really a hot mess at this point. Don't know how to use submit to test for each field and then display the error message if blank. Also seems like a lot of duplication on the testing of field states. Is there a better way to break up that logic? Ugggghhhhh
UPDATE 2
This one's weird, the form now has all text boxes not buttons or checkboxes!? But the HTML hasn't changed. Sigh
ng-if="identification.firstName.$error.required && !$pristine"
Go search more on $pristine and $dirty validator
You can add some other property to your ng-if and set its value to true only when form is submitted.
in your html add this new property
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required && running">The first name is required.</span>
</p>
in your controller set this property to true when form is submitted
$scope.submit = function(){
$scope.running = true;
...
}
I am using angularjs and trying to make the website accessible. When a user doesn't enter or forget to enter into required field, jaws doesn't read out the error message. I have tried adding role="alert" to the div but it doesn't seem to like it. Any suggestions
<div aria-type-label="{{'some:error'}}">
<span role="alert" class="error-message">Error</span>
</div>
Jaws and the browser are looking for updated content to alert so I found that I had to add and remove the data completely in order to get the alerts to work consistently. For example, I had the text removed when the error would go away, and had the text placed back in once there was an error. This can be done in a couple ways. One, using an ng-if={{error}} then the HTML will get removed from the DOM if there is no error, and put back into the DOM once there is an error.
The other way is to set an errorMessage value to either an empty string when there is no error, or an error message when there is an error. That way the text in the DOM is actually changing, resulting in an alert.
Possible example using both methods mentioned:
<input name="theTextInput" type="text" ng-model="filled" placeholder="Add something"/>
<div role="alert" ng-if="filled" aria-type-label="">
<span class="error-message">{{message}}</span>
</div>
<span class="sr-only" style="display: none;">{{message = "Has Error"}}</span>
Plunker
NOTE: This worked in Chrome in October 2016 and November 2016, but today it looks like it's not alerting at the moment. Still works in Firefox.
You have to use aria-described by and role alert together.
Please have a look:
<input type="textbox" id="yourField" aria-describedby="yourFieldError">
<span role="alert" data-bind="visible:yourCondition" class="error-message" id="yourFieldError">Error</span>
Hope it will help.
Like others, I have been looking for a good way to validate my forms with Angular without the messages being too aggressive. The closest I have gotten is checking for $dirty and $touched prior to firing the messages. Which works for most situations.
The one situation I can't figure out is when the user edits, for example, a required field. The field has text in it, is valid, dirty, and touched. The user goes back into the field to change it. They backspace what is in the input and immediately the message fires because the input is now dirty, touched, and invalid. I'd rather it "reset" at that point and reevaluate when the user blurs the input again. Give them a chance to fill in the input while it's still focused.
Make sense? Any ideas?
Thanks!
Matt
Perhaps this works:
ng-model-options="{ updateOn: 'blur' }"
Add it to your input element. I believe the validation will occur when the model is updated, this way the model gets updated on blur.
Here you can see more options for this directive: https://docs.angularjs.org/guide/forms in Custom model update triggers. And a more detailed explanations in ngModelOptions.
Let me know if it works :)
Use function on ng-blur to validate and show messages if invalid.
ng-blur="validate()"
In your controller -
$scope.validate = function(){
//Validate logic
//If invalid
//Show message logic here
}
Take a look at the ngMessages documentation:
https://docs.angularjs.org/api/ngMessages/directive/ngMessages
You have an example there that shows you how to use it:
<form name="myForm">
<label>
Enter your name:
<input type="text"
name="myName"
ng-model="name"
ng-minlength="5"
ng-maxlength="20"
required />
</label>
<pre>myForm.myName.$error = {{ myForm.myName.$error | json }}</pre>
<div ng-messages="myForm.myName.$error" style="color:maroon" role="alert">
<div ng-message="required">You did not enter a field</div>
<div ng-message="minlength">Your field is too short</div>
<div ng-message="maxlength">Your field is too long</div>
</div>
</form>
I think this is the best way to do it (at least it's how I do it).
I store time as an integer of minutes in the database/model. However, I want to display it to the user in decimal hours (and let them edit the value using a number of buttons).
At the moment I have this:
<p class="input-group">
<input type="text" readonly="readonly" value="{{vm.time.minutes|hoursMinutes}}" class="form-control" />
<span class="input-group-btn">
<ix-time-picker minutes="vm.time.minutes"></ix-time-picker>
</span>
</p>
Of the 2 elements in the p tag:
The input type="text" works fine as the display mechanism. The hoursMinutes filter returns a formatted value, e.g. for 90 mins it will return '1 hour 30 mins'.
The ix-time-picker directive pops up a modal window with buttons such as 15 mins, 30 mins, 45 mins, 1 hour, 1:15 hours, etc.
This works fine - except for validation. I'm using ng-messages and I can't work out how to display the validation for the required state:
<li class="help-block has-error"
ng-if="mainForm.$submitted"
ng-messages="mainForm.minutes.$error">
<span ng-message="required">
Minutes is required.
</span>
</li>
I don't have a control on the form called minutes (at least with an ng-model) so it won't display the message. I could add a hidden input with ng-model="vm.times.minutes" but as I need to use this repeatedly through the application, I'd prefer not to do that. Or at least I'd like to build some kind of common directive that merges the ability to have an ng-model on a control with the ability to display a value that is different to the model value, if that's possible.
Any suggestions?
Aha - one option is to make the input a label:
<p class="input-group">
<label id="minutes" name="minutes" readonly="readonly" class="form-control">{{vm.time.minutes|hoursMinutes}}</label>
<span class="input-group-btn">
<ix-time-picker minutes="vm.time.minutes"></ix-time-picker>
</span>
</p>
Then it displays correctly and it validates.
Actually, I am using this combined date and time picker, but it simply an extension of the standard , so I doubt that it is causing my problem.
Here's my HTML
<input type="text" class="form-control" datetime-picker
ng-model="campaign.start_time" is-open="startDateTimePicker.isOpen" />
I open the picker and select a date & time (which are, in any case, now by default), then I click a "Save" button which should send he data to the server.
However, when I breakpoint and look at campaign, several other fields which were bound to it, such as campaign.title (froma text input field) are set, but campaign.start_time is nulll.
Obviously, I am making a very simple mistake, but what?
The "Save" button looks like this
<button type="button" class="btn btn-outline btn-default"
ng-click="SaveCampaignEdit(campaign);"
accesskey='s' style="margin-left:10%">Save</button>