自定义帮手生成HTML标签单选按钮和相关联的标签 [英] Custom helper for generating html tags for radio button and associated label

查看:151
本文介绍了自定义帮手生成HTML标签单选按钮和相关联的标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个关于单选按钮和相关的标签解决方案。我想我们可以通过点击相关的标签上选择每个单选按钮的方式。默认情况下,这并不能很好地工作。我的意思是标签不正确地与单选按钮关联。

I was searching for a solution about radio buttons and associated labels. I like the way we can select each radio button by clicking on the label associated. By default, this doesn't work very well. I mean the labels are not correctly associated with radio buttons.

示例:让我们说我们有被吊销的可能值命名属性是/否。我们想用单选按钮来让用户选择的值。

Example: let's say we have a property named Revoked with possible values Yes/No. We would like to use radio buttons to let the user choose the value.

问题:当html标签从MVC(Html.LabelFor,Html.RadioButtonFor)产生的,无论是单选按钮的ID(是/否)是相同的。因此,它是不可能的每个标签与对应的单选按钮相关联。

The problem: when html tags are generated from MVC (Html.LabelFor, Html.RadioButtonFor), the ID of both radio buttons (Yes/No) are the same. Thus it is impossible to associate each label with the corresponding radio button.

解决方案:我创建自己的自定义帮助与正确和唯一的ID生成HTML代码

The solution: I created my own custom helper for generating html tags with correct and unique ID.

下面是我的帮助:

    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());
    }

它的工作原理,但我需要提醒。你怎么看?它是有效的?我还是新的ASP.NET MVC的世界,因此任何帮助是极大的AP preciated。

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

感谢。

推荐答案

除此之外,可以作出辅助一些细微的改进,看起来不错:

Other than some minor improvements that could be made the helper looks fine:


  • 您不需要调用 ModelMetadata.FromLambdaEx pression 使用相同的参数两次

  • 在为了产生id您在使用值级联属性名称,但这个值可以包含任意字符,而在HTML中一个ID只允许某些字符。你需要清理它。

  • 您都价值和CurrentValue的铸造如果助手是一些其他的属性类型使用的可能会失败的字符串。在这种情况下,无论是反映辅助签名使只有字符串属性辅助工作或使用 Convert.ToString()

  • You don't need to call ModelMetadata.FromLambdaExpression twice with the same arguments
  • In order to generate the id you are concatenating the property name with the value but this value could contain any characters while an id in HTML allows only certain characters. You need to sanitize it.
  • You are casting both the value and currentValue to strings which might fail if the helper is used on some other property type. In this case either make the helper work only with string properties by reflecting on the helper signature or use Convert.ToString().

下面是重构后的版本,其中考虑到这些意见:

Here's the refactored version which takes into account those remarks:

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()
    );
}

这篇关于自定义帮手生成HTML标签单选按钮和相关联的标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆