Friday, February 4, 2011

Styles for IE 6/7 Select in MVC validation CSS

IE 6 and 7 use the in-built OS for select lists, which don't behave when using the standard styles for MVC validation:

.input-validation-error { border: 1px solid red; }

Your textboxes will receive a red outline but your select lists will not. The best way I have seen to achieve a generic cross-browser style definition is to add more css styles to handle select lists with a light-red shaded background:

select.input-validation-error { background-color:#FFA5A5; }
.input-validation-error option { background-color:white; }


Now select boxes will be marked in all browser types, and error conditions on select lists have improved visibility.

Thursday, February 3, 2011

Change ASP.NET MVC Validaton To Display Icon Instead Of Error Message Span

While developing my first MVC application I found, after extensive googling, no solution for the common validation feedback technique of using error icons. ie. Instead of your validation text appearing next to your form element, an error icon appears and hovering the mouse over the icon shows the error message.

This is often used in conjunction with a validation summary, which contains all the descriptive text, and then the various fields on the form are marked invalid with a small error icon for added visibility. Such a thing is easy to do with ASP.NET webforms validators, allowing you to specify whatever markup you wish in the validation message. But in MVC the client-side behaviour is locked away in the javascript validation libraries. ValidationExtensions can allow you to create different types of validators, and even manipulate the validator container (a span), but you are still subject to client-side behaviour where a second span, containing the validation message, is dynamically generated and set inside the validator container span.

Fortunately, if you are using the MicrosoftMvcJQueryValidation javascript library, a two line change can modify this behaviour. Search for the code snippet below (expanded from MicrosoftMvcJQueryValidation.min.js) and add the lines in bold:

errorPlacement: function (error, element) {
var messageSpan = fieldToMessageMappings[element.attr
("name")];
$(messageSpan).empty();
$(messageSpan).removeClass("field-validation-valid");
$(messageSpan).addClass("field-validation-error");
error.removeClass("input-validation-error");
error.attr("_for_validation_message", messageSpan);
    //Change - replace span contents with error icon and 
alternate text
var errorMessage = error.html();
error.html('<img src="/Images/Icons/Error.gif"
alt="' + errorMessage + '"
title="' + errorMessage + '"
width="16"
height="16" />'
);
    error.appendTo(messageSpan);
},

This replaces the span's text contents with an error icon of your choice with appropriate alternate text.

I hope this code helps, I'll be pursuing the MVC team to bake this functionality into the framework so it can be easily configured, as of MVC 3 it doesn't appear to be implemented.

Friday, January 21, 2011

Generic Enum to List converter (C#)

Sometimes it is necessary to take enumerations and bind them to some kind of UI control requiring a list. There are various ways to do this, but after some research nobody had included a solution that has the numeric index of the enumeration. The code below shows this implementation, which involves a class of type EnumItem (to store invidivual enum values) and a static conversion function EnumToList, which does the work :

///
/// Generic EnumItem class for Enum item representation.
///

public class EnumItem
{
///
/// The enum index, it is a 1-based index.
///

/// The enum index value (1-based).
public int Index { get; set; }

public string Name { get; set; }
public object Value { get; set; }
}

///
/// Converts an Enum to a List of type EnumItem.
///

/// The type of enum to convert.
/// List of type EnumItem.
public static List EnumToList()
{
//Validate T is an enum
Type enumType = typeof(T);
if (enumType.BaseType != typeof(Enum))
{
throw new ArgumentException("T must be of type System.Enum");
}

var valueArray = (T[])(Enum.GetValues(typeof(T)).Cast());
var nameArray = Enum.GetNames(typeof(T)).ToArray();
List enumItemList = new List();
for (int i = 0; i < valueArray.Length; i++)
{
string name = nameArray[i];
T value = valueArray[i];
enumItemList.Add(new EnumItem { Index = i + 1, Name = name, Value = value });
}
return enumItemList;
}


By calling List myList = EnumToList() you will receive a 3-column list containing the 1-based index, the enum name, and the enum value.