Ajax Form + HTML5 Feature Support
As part of a new UI library, I have created a full-featured, HTML5-enhanced Ajax Form framework in a manner that follows
the guidelines found in the Webgrown Solutions UI Manifesto. The Ajax Form supports the following features:
- Automated form field to JSON mapping for Ajax POST.
- Settings-based Ajax POST call (no additional Ajax call scripting for each form). Via simple custom data (data-*) attributes the service
call and any related parameters are mapped to the corresponding form fields.
- Built in error handling of Ajax request.
- Simple method to clear/reset form fields.
- HTML5 input "placeholder" support (see Future Compatibility).
- HTML5 input "autofocus" support (see Future Compatibility).
- HTML5 input "required" support (see Future Compatibility).
- Automatic required field indication (asterisk added to label).
- HTML5 input "pattern" support (see Future Compatibility).
- Flexible layout (vertical or horizontal flow).
- Can also use the UI Library - Button features.
- UI Manifesto compliance:
The Demo
Form Test #1 (Sign In) - Horizontal Layout
Form Test #2 (Add Person) - Vertical Layout
The Markup
The form consists of just basic form fields (<input>, <select>, etc) and corresponding <label>s for the flexible layout. The button decorated
with the "ajaxFormPost" class attribute and some custom data (data-*) attributes is all that is needed to enable the Ajax call. The "data-formGroup" custom data
attribute is what ties the fields with the button (think ValidationGroup in ASP.NET). No <form> tag is required for the grouping, which works great with
ASP.NET Web Form's single server form limitations. The "data-parameterName" custom data attribute on the form field is what maps each form field to its related
service call parameter. The only scripting to be added for each form would be any "success" actions to be performed with the JSON data returned by the service call.
That is it! Once the CSS and Script stuff are in place on a website, any page can take advantage of this full-featured Ajax Form by simply setting the button's class
attribute and setting the needed button and form field custom data attributes. And don't forget, this gives you HTML5 form feature support ("placeholder", "autofocus",
"required", and "pattern") on every browser, regardless as to whether the browser natively supports this new HTML5 feature or not. That means form validation ("required" and "pattern") is built in,
with no additional scripting.
That sounds like a DRY solution to me (see UI Manifesto).
<h3>Form Test #1 (Sign In) - Horizontal Layout</h3>
<div class="form legendLook horizontalFormLayout">
<div id="hdivFormTest1ConfirmationMessage" class="confirmationMessageWrapper hide"></div>
<div id="hdivFormTest1ErrorMessage" class="errorMessageWrapper hide"></div>
<label for="txtUsername">Username:</label>
<input type="text" id="txtUsername" placeholder="E-mail Address" required autofocus
data-formGroup="formAuthenticate"
data-parameterName="username" />
<label for="txtPassword">Password:</label>
<input type="password" id="txtPassword" placeholder="e.g. demo123" required
data-formGroup="formAuthenticate"
data-parameterName="password" />
<div class="formButtonWrapper clearFix">
<input type="submit" class="ajaxFormPost buttonStrong" value="Sign In"
data-formGroup="formAuthenticate"
data-serviceRequestUrl="/WebServices/AjaxFormTestClientService.svc/Authenticate"
data-successFunction="successFormTest1"
data-confirmAction="false"
data-confirmActionMessage=""
data-processingMessage="signing in..."
data-overlayWindowWhileProcessing="true" />
</div>
<p>HINT: By entering "" for the username and "demo123" for the password, the JSON data returned will come back with a status of "Valid".</p>
</div>
<h3>Form Test #2 (Add Person) - Vertical Layout</h3>
<div class="form legendLook">
<div id="hdivFormTest2ConfirmationMessage" class="confirmationMessageWrapper hide"></div>
<div id="hdivFormTest2ErrorMessage" class="errorMessageWrapper hide"></div>
<label for="txtPersonFirstName">First Name:</label>
<input type="text" id="txtPersonFirstName" required
data-formGroup="formAddPerson"
data-parameterName="FirstName" />
<label for="txtPersonMiddleName">Middle Name:</label>
<input type="text" id="Text1"
data-formGroup="formAddPerson"
data-parameterName="MiddleName" />
<label for="txtPersonLastName">Last Name:</label>
<input type="text" id="txtPersonLastName" required
data-formGroup="formAddPerson"
data-parameterName="LastName" />
<label for="txtPersonCity">City:</label>
<input type="text" id="txtPersonCity" required
data-formGroup="formAddPerson"
data-parameterName="City" />
<label for="ddlPersonStateAbbreviated">State:</label>
<select id="ddlPersonStateAbbreviated" required
data-formGroup="formAddPerson"
data-parameterName="StateAbbreviated">
<option value="">Please select a state...</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">America Samoa</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="AA">Armed Forces - Americas (AA)</option>
<option value="AE">Armed Forces - Europe (AE)</option>
<option value="AP">Armed Forces - Pacific (AP)</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="DC">District of Columbia (DC)</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="PR">Puerto Rico</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VI">Virgin Islands</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>
<!-- I know having two columns for the full name and abbreviated name for a state is not normalized and a bad idea,
but this is just for testing purposes to see how to massage the form as needed before the submit. -->
<input id="hfPersonState" type="hidden"
data-formGroup="formAddPerson"
data-parameterName="State" />
<label for="txtPersonZipCode">Zip Code:</label>
<input type="text" id="txtPersonZipCode" class="postalCodeTextbox"
required
placeholder="ZIP or ZIP+4"
data-allowExtended="true"
data-formGroup="formAddPerson"
data-parameterName="ZipCode" />
<div class="formButtonWrapper">
<input type="submit" class="ajaxFormPost buttonStrong" value="Add Person"
data-formGroup="formAddPerson"
data-serviceRequestUrl="/WebServices/AjaxFormTestClientService.svc/AddPerson"
data-parameterObjectName="person"
data-successFunction="successFormTest2" />
</div>
<p>HINT: By entering "William" for the first name and "Familia" for the last name, the JSON data returned will come back with a status of "Duplicate".</p>
</div>
The CSS
Not shown to the general public.
The Script
Not shown to the general public.
In addition to the markup, CSS, and JavaScript code samples found below the demo, the following resources/files are required: