Custom helper for generating html tags for radio button and associated label

I was looking for a solution on radio buttons and related shortcuts. I like how we can select each switch by clicking on the appropriate label. By default, this does not work very well. I mean, labels are not properly associated with switches.

Example: let's say we have a property called Revoked with possible Yes / No values. We would like to use switches so that the user can select a value.

Problem: when html tags are generated from MVC (Html.LabelFor, Html.RadioButtonFor), the identifier of both radio buttons (Yes / No) is the same. Thus, it is not possible to associate each label with a corresponding radio button.

Solution: I created my own custom helper to generate html tags with the correct and unique identifier.

Here is my assistant:

public static MvcHtmlString RadioButtonWithLabelFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, object labelText) { object currentValue = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model; string property = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).PropertyName; // Build the radio button html tag TagBuilder htmlRadio = new TagBuilder("input"); htmlRadio.MergeAttribute("type", "radio"); htmlRadio.MergeAttribute("id", property + value); htmlRadio.MergeAttribute("name", property); htmlRadio.MergeAttribute("value", (string)value); if (currentValue != null && value.ToString() == currentValue.ToString()) htmlRadio.MergeAttribute("checked", "checked"); // Build the label html tag TagBuilder htmlLabel = new TagBuilder("label"); htmlLabel.MergeAttribute("for", property + value); htmlLabel.SetInnerText((string)labelText); // Return the concatenation of both tags return MvcHtmlString.Create(htmlRadio.ToString(TagRenderMode.SelfClosing) + htmlLabel.ToString()); } 

It works, but I need to advise. What do you think? Is it effective? I'm still new to the ASP.NET MVC world, so any help is greatly appreciated.

Thanks.

+1
source share
1 answer

Besides the minor improvements that can be made, the assistant looks good:

  • You do not need to call ModelMetadata.FromLambdaExpression twice with the same arguments
  • To generate an identifier, you combine the property name with a value, but this value can contain any characters, while the identifier in HTML allows only certain characters. You must disinfect it.
  • You pass the value value and currentValue to strings that may fail if the helper is used for some other type of property. In this case, either create an assistant with only string properties, reflecting the auxiliary signature, or use Convert.ToString() .

Here's a reorganized version that takes these comments into account:

 public static IHtmlString RadioButtonWithLabelFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, TProperty value, string labelText ) { var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); object currentValue = metadata.Model; string property = metadata.PropertyName; // Build the radio button html tag var htmlRadio = new TagBuilder("input"); htmlRadio.GenerateId(property + value); htmlRadio.Attributes["type"] = "radio"; htmlRadio.Attributes["name"] = property; htmlRadio.Attributes["value"] = Convert.ToString(value); if (object.Equals(currentValue, value)) { htmlRadio.Attributes["checked"] = "checked"; } // Build the label html tag var label = new TagBuilder("label"); label.Attributes["for"] = htmlRadio.Attributes["id"]; label.SetInnerText(labelText); // Return the concatenation of both tags return new HtmlString( htmlRadio.ToString(TagRenderMode.SelfClosing) + label.ToString() ); } 
+2
source

All Articles