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.
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 have the following angular-List (reduced the content to make it better readable):
<div ng-repeat="element in bigBlock.Elements track by $index"
class="singleBlockElement"
ng-drop="dragSource=='Block'"
ng-drop-success="To($index, $data, bigBlock)">
<div class="bbRange"> </div>
<i class="fa {{GetImage(element)}}" />
<div ng-drag="element.ElementType!=='placeholder'"
ng-drag-data="element"
ng-drag-start="Start()"
ng-drag-success="From(element,bigBlock, $index, bigBlock.$index)"
ng-drag-stop="Stop(element, bigBlock, $index, bigBlock.$index)"
class="cutOff">
{{element.Title}}
</div>
<div class="edit ng-show="GetLinkText(element, true)">
<span class="isvisible">
<i title="{{element.Present?'Präsentieren':'Nicht präsentieren'}}" class="fa fa-{{element.Present?'eye':'eye-slash'}}"></i>
</span>
{{GetLinkText(element,true)}}
</div>
</div>
This is how it looks like:
This is while dragging:
And this is how it looks like when I simply don't drop like described below:
I can now (successfully) drag & drop the two elements ("Welcome" and "Go Away") inside that block changing the order of these two.
But if I abort the drag/drop. e.g. Dragging "Welcome" and not moving it downwards or moving it to an area where I cannot drop (outside the block) the text "Welcome" disappears.
There are no errors. The drop is just not happing (as expected), but Angular seems to be unable to redisplay the text of that element. ({{element.Title}})
I event tried forcing a refresh using $apply(), but this did not change a thing (not creating an error either).
However, if I do ANYTHING on the page like clicking on an edit-button or anything else that causes an event, the date is correctly shown again.
So it looks like a refresh issue for me.
I am using ngDraggable for this (https://github.com/fatlinesofcode/ngDraggable)
(Update: Analyzing the page source in Developer Console of Chrome the text still seems to be there and even "should" be visible (display:block), so this might be more of a browser-issue (chrome) than an angular-issue)
This seems to be a pure Browser/CSS-Issue and not an Angular-Issue. I solved this by forcing the browser to refresh the parent container:
$('.mm-Right')[0].style.display = 'none';
$('.mm-Right')[0].offsetHeight;
$('.mm-Right')[0].style.display = 'block';
where my structure is
<div class='mm-Right'>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
</div>
That did solve the problem but looks like cheating for me. I would prefer that this bug not even appears instead of hiding the symptoms. So I am happy to accept any better answer for that problem.
I was able to identify the error message "Hmm, try again. That's not a valid email." location using following xpath-//*[#id='login-form']//div[1]/p but Im unable to get the text using gettext method to compare the actual versus expected result.Please let me know how to get the error message
<form id="login-form" class="form-signin row ng-untouched ng-pristine ng-valid submitted" _ngcontent-eda-3="" novalidate="" role="form">
<div class="form-group" _ngcontent-eda-3="">
<ra-input class="ng-invalid" _ngcontent-eda-3="" _nghost-eda-5="">
<div _ngcontent-eda-3="">
<div _ngcontent-eda-3="">
<p class="ng-invalid" _ngcontent-eda-3=""> Hmm, try again. That's not a valid email.
</p>
As per the HTML you have displayed in the question, the xpath you have written is not pointing to the desired paragraph(p) tag.
The correct xpath is:-
//[#id='login-form']/descendant::p[1] or simply //[#id='login-form']//p
so use it like
driver.findElement(By.xpath("//*[#id='login-form']/descendant::p[1]")).getText();
if I provoke 'min-length' error and then try to provoke 'required' error, the latter isn't shown, although the input is underlined in red.
<md-input-container class="md-block">
<label for="register_password">Password</label>
<input required minlength="6" maxlength="100" type="password" name="register_password" id="register_password" ng-model="registerData.password">
<div ng-messages="registerForm.register_password.$error">
<div ng-message="maxlength">The password should be shorter</div>
<div ng-message="minlength">The password should be at least 6 characters long</div>
<div ng-message="required">Required</div>
</div>
</md-input-container>
Full working example:
http://codepen.io/AndriusRimkus/pen/mPEjYX
Thanks!
You should use the following code
<md-input-container class="md-block">
<label for="register_password">Password</label>
<input required minlength="6" md-maxlength="100"
type="password" name="register_password"
id="register_password" ng-model="registerData.password">
<div ng-messages="registerForm.register_password.$error">
<div ng-message-exp="['required', 'minlength']">
The password shold be at least 6 characters long</div>
<!-- <div ng-message="minlength">The password should be at least 6 characters long</div> -->
<div ng-message="md-maxlength">The password should be shorter</div>
</div>
</md-input-container>
So there are many things you should consider. Since you are using angular material design I think you should use md-maxlength which will show a hint for how many charcters written against maxlength. I am not sure if there is any md-minlength directive is available. Now require and minlength is kind of same thing so I think you should combine those two as a single error message. Now There are some specific things releated to [ngMessages][1] check the documentaion for detail explation. I'll say couple of things about that. By default ngMessges only displays one error message and if there are more than 1 error message are valid then which ever comes first in DOM will be displayed. you can use multiple or ng-messages-multiple to display more than 1 error messages. I suggest you should write you error in incrementing order like required first followed by minlength(If you want to display it seperately) and at the end md-maxlength. You can use ng-message-exp to combine more than 1 error codes.
Your code is correct but there is one point.
You are using an old version of AngularJS Material.
If You change the last script with this lines then your code will be run properly.
<!-- Angular Material Library -->
<!-- Version 1.1.4 -->
<script src="https://material.angularjs.org/latest/angular-material.min.js"></script>
Check online
Good Luck
I have searched and followed the angular code for a long time and cant find where this error message is coming from. I know the validation works but my code only has this:
<span class="error" ng-show="myForm.input.$error.required">
Required!</span>
<span class="error" ng-show="myForm.input.$error.email">
Not valid email!</span></br>
but this error comes up:
I cant even find where a concatenation might produce this. The word "Please" is not even in the angular code.
The browser is generating this message, because of HTML5 support of "type='email'".
you can add 'novalidate' in form to disable native HTML5 validation.
<form name="form" class="css-form" novalidate>
This is due to HTML5. If you don't want to show these messages, add the following to your css:
::-webkit-validation-bubble-message { display: none; }
However, at the moment this only works for WebKit implementations (Chrome).
More info