Fixer le style des cases à cocher (checkboxes) à l’aide des templates MVC

Certains navigateurs, comme Chrome ou Firefox, vont ignorer les styles appliqués aux cases à cocher (checkboxes), ce que mène à un affichage inconsistant entre les navigateurs. Cet article va montrer comment contourner ce problème dans le cadre d’une solution MVC 4.

Description du problème
Supposons que vous faites une validation classique (par défaut) des données en utilisant le Framework MVC 4. Vous avez un form avec entre autres des cases à cocher. En cas d’erreur sur ces éléments, une classe spéciale CSS l’est attribue – « input-validation-error », définie par default comme suit:

.input-validation-error {
    border: 1px solid #f00;
    background-color: #fee;
}

Pour les checkboxes « en erreur », la bordure et la couleur rouge sont respectées que pour certains navigateurs (comme Internet Explorer V10), mais pas sur les autres (Chrome ou Firefox):

Solution

La solution est de remplacer le modèle d’édition (editor template) Boolean par un modèle personnalisé, en incluant le checkbox dans une balise <div>.

Implémentation
On va ajouter un modèle personnalisé dans le ~/Views/Shared/EditorTemplates/Boolean.cshtml avec un contenu, par exemple, comme suit:

@model bool?

@if (ViewData.ModelMetadata.IsNullableValueType)
{
    @Html.DropDownListFor(m => m, new SelectList(
        new[] {
            new {Value="",      Text="(?)"},
            new {Value="True",  Text="Oui"},
            new {Value="False", Text="Non"}
        }, "Value", "Text", Model))
}
else
{
    ModelState state = ViewData.ModelState[ViewData.ModelMetadata.PropertyName];

    bool value = Model ?? false;

    if (state != null && state.Errors.Count > 0)
    {</pre>
<div class="input-validation-error" style="float: left;">@Html.CheckBox("", value)</div>
<pre>
    }
    else
    {
        @Html.CheckBox("", value)
    }
}

Cette template va « wrapper » la case à cocher dans un élément de type <div>, auquel sera appliqué le style input-validation-error, au cas où des erreurs de validation seront identifiées.

Dans notre cas, une non-acceptation des thermes et conditions amène une erreur. Cette idée est définie dans une action du contrôleur de manière suivante :

[HttpPost]
public ViewResult MakeBooking(Appointment appt)
{
	// ... autres validations ...

	if (!appt.TermsAccepted)
	{
		ModelState.AddModelError("TermsAccepted",
                	"Vous devez accepter les termes et conditions");
	}

	if (ModelState.IsValid)
	{
		// ... ajouter ici l'appointment dans la BD ...
		return View("Completed", appt);
	}
	else
	{
		return View();
	}
}

Et voici le résultat :