CSS design for large form - Design Advice - forms

I have a large form that consists of all the input (text, checkbox, radio, etc...), I have them grouped together in a fieldset tag and a legend for each feildset. Each input has a label associated with it as well. My question is what is the best approach to display the information on one screen and take advantage of the horizontal real estate the user might or might not have?
I would love it to be all CSS with minimal (if any) table layout(s) as I think tables are for tablature data and not presentation. CSS3 and HTML5 are welcome as well.
Also I would like to have the ability to add branding as this might need to look like another site instead of the original site developed for.
What would be the best approach for this? I have the idea I would use li tags to do the horizontal look but I would like to break to the next line at the end of the screen (Think no scrolling horizontal but vertical is okay)
CSS Novice looking for design pattern advice
This is an example but I think I have around 50 fields
<!DOCTYPE HTML>
<html>
<head>
<title>Large Form</title>
</head>
<body>
<form action="">
<fieldset>
<legend>***</legend>
<label for="fname">First Name</label><br />
<input type="text" name="fname" id="fname" value="" /><br /><br />
<label for="lname">Last Name</label><br />
<input type="text" name="lname" id="lname" value="" /><br /><br />
<label for="gender">Gender</label><br />
<select name="gender" id="gender">
<option value="">-- select</option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</fieldset>
<br />
<input type="submit" value="Submit" />
</form>
</body>
</html>

The first thing that comes to mind is that you want to remove the <br/> tags from the form. If you need vertical space, use CSS padding and margins since they're easier to change and make spacing consistent.
With that out of the way, other than branding (which will influence the look and feel of the form the most) the things you want to consider the most are accessibility and ease of use. Your use of labels and unwillingness to use tables for layout are a good start for accessibility so I'm not going to mention it further.
For ease of use, you'll need to make sure that each field can be tabbed to (in an order that makes sense), has a clear, meaningful label, has no unnecessary validation rules (such as forbidding whitespace in a phone number - don't force the user to clean data that can be cleaned automatically) and those validation rules that are necessary have clear, easy to understand messages that appear, ideally, as the user is entering the data rather than waiting for the user to submit the form.
Each of your field sets should be visually grouped either by colour, with a border or some other method. Individual field set should not be broken up, but different field sets can be separate from each other as long as they are contextually different (like address versus interests, for example).
Since you're already grouping field sets, you can use them as your basic unit of page layout. Each set could be floated, for example, in order to maximimize horizontal usage regardless of the user's browser width. As long as the sets are visually distinct enough and are clearly labelled there shouldn't really be any issues with that.
If consistency is more your thing, then each field set should be separated from each other vertically. That would make sure the form is ordered and laid out the same way for every user. Again, the important thing is visual consistency and ease of use. Users are used to forms being laid out vertically so the wasted horizontal space of doing it that way shouldn't be a very big concern.
Just remember: you're making something that should be easy to use and not frustrating. The position of fields should reflect that: they should be natural, grouping like fields together and separating groups of like fields from dissimilar fields. As long as you're keeping that in mind you're probably in good shape.
And don't forget to do some quick usability tests to make sure your validations make sense and are clear.

Have a look at CSS3 grid positioning. It has a clear but powerful syntax, e.g. from the link:
body {
grid-columns: * * (0.5in * *)[2];
grid-rows: 20% *;
columns: 3;
column-gap: 0.5in;
}
Elements use gr units to choose their grid cell:
img {
position: absolute;
left: 2gr;
width: 3gr;
}
You would only have to give an id to your fieldsets then set their position and extents in your style file.

One of my favorite ways to group large forms is with the jQuery style accordion. It allows you to abstract the form into key groupings, keep the form all on one page, and eliminate the need for page scrolling; all with an intuitive user interface.
A good example of this is the Barnes & Noble checkout form process.

Check out CSS Flexbox for some liquid flexibility withing you design sets. I would also recommend picking a "style" and sticking with it. Agree with Welbog.

I guess that if you have a form with 50 fields, you surely have to split it to themed tabs. Say 3 to 5 tabs. They can be implemented by Javascript.
You may want to save input data on-the-fly, because the user may need a long time to finish the form, so there is bigger possibility that he will catch a loss of internet connection or some other factor, that will erase his half-finished form, which would probably dissapoint him and leave your site.
Also consider that user has to have a place for his eye to rest, so be sure to make enough blank room between inputs.

Related

Conditional processing within a Sightly/HTL component dependent upon position within a page

I've recently begun as an Ops dev on an AEM project, and we have a component (a table, that has a title, some copy and a field where the author can author some HTML to represent the contents of a table, with and elements. This, for whatever reason, has to sit within a component, called ArticleContainer. The title should have an H1 tag if the table is at the top of the page, and an H2 tag if it's anywhere lower down. I've tried using data-sly-test thus:
<sly data-sly-test.topOfPage="${table.firstPosition==true}">
<h1 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>
</sly>
<sly data-sly-test="${!topOfPage}">
<h2 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h2>
</sly>
Now, this kind of processing has worked elsewhere where the component doesn't sit within a container, but it seems that if it's in a container it always picks up the non-topOfPage condition. I assume there might be a way to maybe do the test within the container component & pass it down into the table component? How would one go about this, or if it's not possible, is there another method by which one might achieve this?
There are two things here:
What does table.firstPosition return? You should be able to debug this in your Sling Model or POJO and probably need to adjust the logic to account for intermediary containers.
HTL/Sightly has a data-sly-element that allows you to change the HTML element based on an expression, you could make your code shorter (and easier to maintain):
<h1 data-sly-test="${table.headerCopy}" data-sly-element="${table.firstPosition ? 'h1' : 'h2'}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>

How do I validate multiple checkboxes, using Statamic forms?

I'm using Statamic CMS
I've got a checkbox group with two checkboxes, I'd like both of them to be checked before the form will submit.
Setting the field as 'required' half works. The form will error if nothing is checked, but it submits if one of the boxes is ticked.
I can see under the validation tab, there's a list of additional rules. But I'm not sure which rule to use.
If it helps, this is what the HTML checkbox group looks like:
<div>
<label>Contact permissions</label>
<span>Please tick both checkboxes</span>
<label>
<input type="checkbox" name="checkboxes[]" value="gdpr" />
Please contact me with the details I've provided
</label>
<label>
<input type="checkbox" name="checkboxes[]" value="terms" />
I agree with the terms and conditions
</label>
</div>
I'm using the {{ fields }} tag to generate the HTML
Within the CMS, under the validation tab, there's a link to the Laravel docs. As I want to validate two checkboxes, I think I need the required_with: rule, but I can't get it to work...
required_with: is looking for two values, the example shows this:
required_with:foo,bar,..
The values of the checkboxes are, value="gdpr" and value="terms" so I (wrongly) assume this should work...
required_with:gdpr,terms
After saving the changes and testing the form, it still submits? Even though only one of the checkboxes might be ticked...
What is the correct syntax/values to use to get this to work?
:) foo,bar in the docs are field names in your form. What you're doing with gdpr,terms are values.
Plus, since both your buttons are named checkboxes[], the form is validating that if either one is selected, then it should be passed. Hopefully this helps!

Chrome/HTML5: Input type number not respecting max attribute?

I have the following markup:
<input type="number" max="99" />
In Google Chrome (and possibly other webkit browsers), this will restrict the spinner's up arrow from going over 99, but it does not prevent the user from typing a number higher than 99. Even onblur, the invalid value is not removed/replaced or even a warning given that the value is invalid.
Am I misinterpreting how it's supposed to work, or is this a bug? I am using the latest version of Chrome (19 at the time of writing).
Edit:
To clarify, I want to know why a number greater than the specified max is allowed to be input in the first place. I realize that it gives a tooltip on form submission telling you that it's invalid, but it seems like inconsistent behavior that the spinner will not allow you to go above the max, yet you can simply type a number above the max at any time to circumvent it.
If this is desired behavior for some reason, why is that? And is there a better option to enforcing the input range without resorting to JS?
It does work but you only see an error message (tooltip) if you put a submit button and a form into your code:
<form action="#" method="get">
<input type="number" max="99" />
<input type="submit" value="Submit!" />
</form>
jsFiddle
​
It's an old question, but I didn't find any relevant answers for this question anywhere.
this behaviour is still around in chrome (version 61).
I have found a little trick that can be used in some situation.
it's relevant for those who use data-binding libraries like aurelia, angular etc.. I tested only on aurelia - but that should work also for others.
the trick relies on the fact that input of type range enforce the min/max constraints.
we simply create another input (of type range) that is bounded to the same value as the regular input, and we hide it via css.
when the user inputs something that is greater than the max value, it will snap back to the max value.
here's a demo in aurelia: https://gist.run/?id=86fc278d3837718be4691acd5625aaad

Add logic to a form when Javascript is disabled

I'd like my form to include a certain value if the quantity is equal to 1 (via a text box).
I've managed to show what the total cost is using JavaScript and I could submit it with this value but I'm worried that when JavaScript is turned off the user will be able to submit the form without the extra fee being added. Therefor escaping the fee.
<form>
<label>Qunatity</label>
<input type="text" name="qyt" />
<input type="text" name="fee" value="250" />
<div class="total">[whatever the total is]</div>
<input type="submit" value="submit" />
</form>
Is there a way I can submit this form so that it submits 250 only if a quantity of 1 is added to the form? I'd like to avoid using a select input.
Will I need to split my form out into two stages to achieve this?
You need to check your logic in server-side code.
Most people have Javascript enabled, so you should do it in Javascript to provide a better experience, but you must always reproduce the logic on the server.
If you need to validate your input without JavaScript, have a server-side component (PHP?) to do the job and return the same form with an error message if no quantity was given. That way you don't have to split your form into two steps.
The best/safest way to handle this would be to do your total calculation on the server side. That way the data you store will always be correct.

jQuery ajaxSubmit(): ho to send the form referencing on the fields id, instead of the fields name?

im pretty new to jQuery, and i dont know how to do that, and if it can be done without editing manually the plugin.
Assume to have a simply form like that:
<form action="page.php" method="post">
Name: <input type="text" name="Your name" id="contact-name" value="" />
Email: <input type="text" name="Your email" id="contact-email" value="" />
</form>
When you submit it, both in 'standard' way or with ajaxSubmit(), the values of the request take the label of the field name, so in the page.php i'll have:
$_POST['Your name'];
$_POST['Your email'];
Instead i'll like to label the submitted values with the id of the field:
$_POST['contact-name'];
$_POST['contact-email'];
Is there a way to do that with jquery and the ajaxsubmit() plugin?
And, maybe, there is a way to do it even with the normal usage of a form?
p.s: yes, i know, i could set the name and id attributes of the field both as 'contact-name', but how does two attributes that contain the same value be usefull?
According to the HTML spec, the browser should submit the name attribute, which does not need to be unique across elements.
Some server-side languages, such as Rails and PHP, take multiple elements with certain identical names and serialize them into data structures. For instance:
<input type="text" name="address[]" />
<input type="text" name="address[]" />
If the user types in 1 Infinite Loop in the first box and Suite 45 in the second box, PHP and Rails will show ["1 Infinite Loop", "Suite 45"] as the contents of the address parameter.
This is all related to the name attribute. On the other hand, the id attribute is designed to uniquely represent an element on the page. It can be referenced using CSS using #myId and in raw JavaScript using document.getElementById. Because it is unique, looking it up in JavaScript is very fast. In practice, you would use jQuery or another library, which would hide these details from you.
It is reasonably common for people to use the same attribute value for id and name, but the only one you need to care about for form submission is name. The jQuery Form Plugin emulates browser behavior extremely closely, so the same would apply to ajaxSubmit.
It's the way forms work in HTML.
Besides, Id's won't work for checkboxes and radio buttons, because you'll probably have several controls with the same name (but a different value), while an HTML element's id attribute has to be unique in your document.
If you really wanted, you could create a preprocessor javascript function that sets every form element's name to the id value, but that wouldn't be very smart IMHO.
var name = $("#contact-name").val();
var email = $("#contact-email").val();
$.post("page.php", { contact-name: name, contact-email: email } );
This will let you post the form with custom attributes.