I've recently started a new project using ASP.NET MVC 4 and Twitter's Bootstrap. As per the designs I had to provide an indicator on the mandatory fields. Something that looks like:
Twitter's Bootstrap provides prepend and append css-classes in it's form, see here. This gives the ability to prepend and append most any text to various input fields, with the result something like the following:
In the above image there are both prepended and appended elements, set using the following html and css
<div class="input-prepend">
<span class="add-on">@</span>
<input class="span2" id="prependedInput" type="text" placeholder="Username">
</div>
<div class="input-append">
<input class="span2" id="appendedInput" type="text">
<span class="add-on">.00</span>
</div>
While it would be simple but time consuming to manually mark every field, I'm using Data Annotations in my ViewModel classes within ASP.NET MVC 4 and I'd like to make use of that to automatically generate the required markup. All required fields are marked with the [Required] attribute.
One path could be to create a HTML Helper method that would render the appropriate html, but I don't need to go to such complexity. Instead I'm going to create the required field indicates client side, with jQuery. ASP.NET MVC 4 adds the data-val-required attribute to every input field that is required and I'm going to take advantage of that.
This solution could have been implemented in CSS only but I found some (older) browsers don't like the attribute and tend to ignore it. Also, I couldn't get the appended field to like up as well as I'd have liked. My end result will look like this
My view (razor) looks like:
<div class="control-group">
@Html.LabelFor(m => m.UserName, new { @class="control-label"})
<div class="controls">
@Html.TextBoxFor(m => m.UserName, inputSize)
@Html.ValidationMessageFor(m => m.UserName)
</div>
</div>
I need to use jquery to find the resultant element, an input element of type text with the data-val-required HTML5 attribute and add the markup bootstrap requires. For that I use the following simple jquery in the ready event, first wrapping the input field in a div and then adding the extra span for the required indicator
function addRequired(searchClass) {
$(searchClass).each(function () {
if ($this).parent().hasClass("input-append"))
$(this).parent().addClass("input-prepend");
else
$(this).wrap("<div class='input-prepend'>");
});
$(searchClass).before("<span class='add-on requiredmarker'></span>");
}
$(document).ready(function() {
addRequired('input[type=text][data-val-required]');
addRequired('input[type=password][data-val-required]');
addRequired('select[data-val-required]');
});
Finally, I have the following CSS for requiredmarker
.input-append .add-on.requiredmarker {
background-image: url('/Images/required.png');
background-repeat: no-repeat;
background-position: 50% 50%;
}