WAI ARIA alert on form submit (with page reloading) - accessibility

Let's say we have a classic form - a few input fields that must meet some pattern. When user enters incorrect data and submits this form all the fields that are filled wrong are marked as invalid and appropriate error message is provided for every incorrect field.
I need to make this form WAI ARIA compliant, so that after form submission the accessibility tools will see these errors first.
I've found solution that implements it by dynamic html modification using JS (http://jsfiddle.net/nS3TU/1/):
HTML:
<form id="signup" method="post" action="">
<p id="errors" role="alert" aria-live="assertive"></p>
<p>
<label for="first">First Name (required)</label>
<input type="text" id="first">
</p>
<p>
<input type="submit" id="button" value="Submit">
</p>
</form>
JS:
$('#signup').submit(function () {
$('#errors').html('');
if ($('#first').val() === '') {
$('#errors').append('Please enter your first name.');
}
return false;
});
Here validation does not reload page, and the "alert" area is dynamically modified.
In my case the page is reloaded on validation phase, and I don't know how to make aria alert work. After hours of investigation I didn't find any solution at all. Any ideas?

I think there's a simple solution, but you'll have to say if it covers your cases.
I would be careful about making something "WAI-ARIA compliant", that should not be a goal in itself. WAI-ARIA is intended to map web pages to application roles, but only applications are actually suitable for this treatment.
For a classic web-form, you do not need WAI-ARIA at all. The alert aspect would not work if the page reloads, as it would only alert if the content changed dynamically.
If the page does not reload (as per the example), you would want to ensure that submitting the form doesn't just leave the user sitting on the button. You can manage the focus to achieve this:
$('#errors').append('Please enter your first name.');
// Make the error message focusable, but not in the default tab-order:
$('#errors').attr('tabindex', '-1').css('outline', '0');
// Set the focus on the (first) error message:
$('#errors').focus();
JSFiddle updated here.
A couple of articles on error-message best-practices your question reminded me of, which would help extend this answer to other use-cases:
Displaying error messages
Accessible form validation.

Related

How to get input values from mgt-people-picker when a FORM is submitted

I'm using mgt-people-picker from within an ASP.Net Razor application, using a ProxyController to get all the data from the Graph API.
Everything is working fine.
Now I want to get the infos from a Form I've created, containing a people list, from the mgt-people-picker element :
From my ASP.NET backend, once the form is submitted; I have all the info from my inputs, except the mgt-people-picker element.
Anyone knows a simple solution to get the list of people form the input text, issued during the POST action ?
Or should we use a javascript trick ?
Ok, if anyone has the same issue, here is the solution, after a LOT of investigations.
You have to use the template of <mgt-people-picker> with data-type=selected-person.
In this template section, you need to add
An <mgt-person> with the correct properties (That I've found in the source code)
An <input type=hidden /> to store the values:
<mgt-people-picker>
<template data-type="selected-person">
<input type="hidden" value="{{person.userPrincipalName}}" name="people" id="people" />
<mgt-person view="oneLine" person-details="{{person}}" fetchImage=true></mgt-person>
</template>
</mgt-people-picker>
From within your backend handler, you will get all the persons selected in the Request.Form["people"] property
public void OnPost()
{
foreach (var personSelected in Request.Form["people"])
Debug.WriteLine(personSelected);
}
The solution is elegant and easy to use & understand.
Unfortunatelly, the documentation lacks details on the customization, especially on templates :)

ASP.Net MVC - Stop auto complete password

I have an existing asp.net mvc web application which I would like to stop browsers from auto remembering passwords for next time. Can I do this without needing to change the input autocomplete="off" on the password as whilst I can see this should resolve future ones any one who has already done this action can probably still login as the password is cached.
Indeed autocomplete="off" will do the trick. You'll see it being used here in SO as well (top right):
<input style="display: inline-block; width: 188px; max-width: 188px;" name="q" placeholder="search" value="" tabindex="1" autocomplete="off" maxlength="240" type="text">
You can add it to your input using Razor:
#Html.TextBoxFor(model => model.Input, new { autocomplete="off" })
You can also target all of them at once with jQuery:
$(document).ready(function() {
$("input:text, form").attr("autocomplete", "off");
})
For the caching part, have a look at this excerpt from "How to Turn Off Form Autocompletion" (MDN) (the whole document is worth a read):
Setting autocomplete="off" here has two effects:
it stops the browser saving field data for later autocompletion on similar forms though heuristics that vary by browser.
it stops the browser caching form data in session history. When form data is cached in session history, the information the user has
filled in will be visible after the user has submitted the form and
clicked on the Back button to go back to the original form page.
In some case, the browser will keep suggesting autocompletion values
even if the autocomplete attribute is set to off. This unexpected
behavior can be quite puzzling for developers. The trick to really
force the no-completion is to assign a random string to the attribute
like so :
autocomplete="nope"
Since this random value is not a valid one, the browser will give up.
You should also check if this behavior is consistent between all major browsers (depending on what browser support you are after).
Update: Michael Liu has noted in the comments that "Modern browsers ignore the autocomplete attribute on password fields", in which case I am not aware of a legitimate solution.
You could try placing an additional input field of type password on top of your actual one and set it to hidden, the browser should attempt to autocomplete that instead:
<!-- before your actual password field -->
<input style="display: none;" type="password" name="pwdplaceholder"/>
...it is however messing with browser behavior which is not best practice.
Also have a look at another SO question (shared by Michael Liu in the comments).
You can try using this (Preventing autofilling with autocomplete="new-password"):
autocomplete = "new-password"
For example:
#Html.PasswordFor(m => m.NewPassword, new { #class = "form-control", autocomplete = "new-password" })
And this is the Browser Compatibility:

Drupal views - splitting up the exposed form possible?

I need to display part of the exposed form in my page's sidebar, and the rest of the form and content in the $content area. There's really no good way that I can find to do this. I sort of got it to show up in a way by making a "block" view with "exposed form" set and then trying to only show the part that i needed through .tpl files. The problem is that then, when the submit button is clicked (the submit button is in the $content area), then the filters that are in the sidebar are not taken into account.
Some lateral thinking... Why not explore CSS-only options? You can place that form element playing with position:absolute ? Or (considering is a right-sidebar) float:right and then some negative right margin to push it to the sidebar? If you are using 960 grid system, play with pull and push classes.
First I am going to answer your question, then I will explain why you are asking the wrong question:
If you build the form outside of the formapi, you might have some luck. This will get upgly and will require you to take a lot of extra care about attack-vectors such as mass-assignment.
views_some_view.tpl.php:
<form name="input" action="/link/to/view" method="get">
Country: <input type="text" name="country" />
my_custom_exposed_view.module:hook_block()
City:
That would make a form, which in most situations will start with <form>, have some input fields, then have a lot of random HTML, then some more input fields and then the closing .
As you may know, a <input type="submit" value="Submit" /> will only post everything of the form tags it is enclosed in. The submit button in the following HTML:
<form name="input_1" action="/link/to/view" method="get">
Country: <input type="text" name="country" />
</form>
<form name="input_2" action="/link/to/view" method="get">
City: <input type="text" name="city" />
<input type="submit" value="Submit" />
</form>
will only send the City. These are not the droids you are looking for.
It will need to be one, big form, but since everything between form and /form is very dynamic, and contains a large quantity of HTML, including potential other forms, this is really not what you want. Moreover: a blocks appearance (shown/not-shown) is controlled completely independent of the content. You will need a lot of sturdy code to ensure the block a) never shows up when the starting form tag is not present, and b) the block will guaranteed to be shown when that opening form tag is present. Else you have not just invalid HTML, but broken HTML that will truly render your page unusable in most cases.
You simply don't want a part of the form in a block and the other part in the content.
However, you want it visualised as if one part is in the body, the rest in a sidebar.
The good news, is that with HTML presentation structure are independant. That is where your solution lies.
Give your form-fields good ids and classes. You could use a hook_form_alter to change existing forms, but you probably simply just want to create the HTML for that entire form yourself. The theme layer allows that.
Use CSS to pick out either single form-fields by ID and position:absolute them into the correct place. Or pick out classes of fields by CLASS and position:relative them into the correct place.
Make a simple identification-routine that allows adding a class to the body-tag. (see below).
Add some CSS to shift the sidebar lower, making space for the form-fields to be moved in, when that class is in the body-tag.
<body class="<?php print $splitform ?>">
function my_themename_preprocess_page() {
if ($GET['q'] == 'path/to/view') {
$vars['spliform'] = "splitform"
}
}
From the above explanation I am assuming that you are printing same form in block and in content area and you are hiding some part of form in page.tpl , if this is true then you can use hook_form_alter() in your custom module then
Store the value of the form element(present in block) in global variable.
Now use that global variable and set form element(present in content area, this form element is not visible to user).
Provide more information if you implemented other way.
Regards,
Chintan.
There is a related issue here:
https://drupal.stackexchange.com/questions/3827/multiple-copies-of-views-filter-form-exposed-filters
which describes how to duplicate your filters. However it seems like an ugly hack.
A bit cleaner seems this solution mentioned in #6:
http://drupal.org/node/641838#comment-3247748
Haven't tested it out, but it looks good.
It will still give you some overhead (duplicate views) but it might be the easiest way doing this using views.
On the other hand you might write a module and build your own custom filter block which hooks into your view. Here is a blog post about this:
http://www.hashbangcode.com/blog/creating-custom-views-filters-exposed-form-element-drupal-6-561.html
If you use something like context you could get the exposed filters block to display twice in the same page. You could then use CSS to hide the fields you don't want to do display in each form.
The fundamental problem you're having is that to have the two forms in different places, they'll each have their own form element - when a submit is triggered, only the form fields within the same form element are sent. You need to move them into one form, or rely on JavaScript to gather the fields from both forms and construct the post.
You could create the block as an empty div and have javascript from the main page populate it with the secondary filter form and whatever else you need in there. Again, you could use javascript to copy the form values from the block form to hidden fields in the main form on submit. That gives you all the control you need from one place (the node output). Only caveat is that it relies a lot more on javascript to join it all together.

I am trying to refresh a sidebar.php in wordpress on a form submit

I am trying to refresh a sidebar.php in wordpress on a form submit (that is in a widget on the sidebar.php).
I have video on the page and if the entire page refreshes, the video has to play from the beginning.
I need a solution to simply refresh the sidebar.php when someone submits the form ... I am not an expert php programmer so simple is best!
btw. I am using formidable plugin for the form.
thanks in advance!
Sounds like a job for ajax!
Now, you could do it from scratch, but that would be unnecessarily painful. Instead, I recommend including jquery into your page by adding this into your header
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
(which uses the latest version, which is hosted on google)
Now that you have jquery loaded, there are many easy ways to submit your data without interrupting the flow of things. Here is how I would do it (I am assuming that you are using method="post"):
Change your <input type="submit" > into a <button>, so clicking on it doesn't trigger the built-in form submit (which would interrupt your video).
Set the id attribute of your button to something so that you can reference it easily like <button id="mysubmitbutton">. (While you are at it, give id attributes to all the form fields you care about if you have not already so that you can reference them easily as well, like <input type="text" name="firstName" id="firstName"> instead of just <input type="text" name="firstName">)
Inside the <head> portion of your website, add some code that looks like something like this:
<script type="text/javascript">
//makes it so that it goes after the html document is ready for it
$(document).ready(function() {
//this ties a onclick event to your button you made
$("#mysubmitbutton").click(function(){
//when the button is clicked, it will asychronously post to where you want it to
$.post("urlthatwasinyouractionequalsattribute.php",
{
//put all your post variables here, referencing the ids you made earlier
firstName: $("#firstName").val(),
time: $("#time").val() //be sure you don't have a trailing comma on the last one
},
function(data) {
//data is whatever the other website sends back. do whatever you want here...
alert("Result: " + data);
});
});
});
</script>
Fire it up and it should work. Obviously, you will need to change the values so that it matches your form, etc.
Hope that helps! Please mark as answer if it did.

(Custom) WAI-ARIA role

I'm pretty new to ARIA and the roles, states, and properties it provides. I understand that there are different types of roles (e.g. landmarks, regions, etc) but none of them represent areas like "login region" or something similar. I wonder if there are ways to specify the grouping of this information so that the screen reader can read out this information for the users? E.g. "Login region. User name ... Password ..."
If this is not possible with ARIA, what is the general way of doing it in HTML?
Thanks in advance
WAI-ARIA is generally for dynamic content, like a news headline ticker, and not for static content, like a login form. Static content is best achieved using plain HTML.
Assuming you have a page where the login form is always displayed, the following should help.
For a login form, from an accessibility point of view, you should primarily ensure that the form fields are correctly labelled. A fieldset\legend is really optional for such as small form.
Coding labels up correctly means using matching for\id attributes e.g.
<label for="loginName">Login name</label>
<input type="text" id="loginName" name="loginName" size="30" />
<label for="loginPassword">Login password</label>
<input type="password" id="loginPassword" name="loginPassword" size="10" />
This ensures that screenreader (blind) users can properly hear the form fields corresponding label read out. For other form elements, such as checkboxes and radio buttons, using correct labelling like this allows users with dexterity issues to click on the text label to toggle the form input (checkbox\radio button), meaning they have larger target area to click on the page.
To let the user know they were about to access a login form, you could use either a heading, or the fieldset\legendf combo e.g.
<h2>Login form</h2>
<FORM HERE>
Or
<fieldset>
<legend>Login form</legend>
<FORM HERE>
</fieldset>
Either of these would be fine, although the heading approach would create slightly less audio clutter for screenreader users (WIth a fieldset\legend, the legend is read out before each form field)
Yes and no. The form should be given a landmark role of "form". This allows the assistive technology to see the landmark for navigation purposes.
Refer to the spec.
While using the landmark will aid in navigating the page, the landmark itself won't produce the reading of the items in the form itself. Following the already known HTML practices mentioned will take care of the rest.

Resources