Вопрос по asp.net-mvc-3 – Динамически установить отключенный атрибут html для TextBoxFor HtmlHelper

8

Я пытаюсь динамически установитьdisabled атрибут дляTextBoxFor HtmlHelper

<code>@Html.TextBoxFor(model => model.Street, 
                 new
                 {
                    @class = "", 
                    disabled = (Model.StageID==(int)MyEnum.Sth) ? "disabled" : "" 
                 })
</code>

но даже если естьdisabled="" это так же, какdisabled="disabled", Как обойти это?

Ваш Ответ

4   ответа
0

лизовали метод расширения с перегруженными параметрами, который принимает логическое значение, указывающее, хотим ли мы отключить элемент управления. Мы просто добавляем «отключено» атрибут, когда это уместно, и пусть встроенный HtmlHelper обрабатывает тяжелую работу.

Класс и метод расширения:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
public static class OurHtmlHelpers
{
    public const string DisabledAttribute = "disabled";

    public static MvcHtmlString TextBoxFor<TModel, TProp>(this HtmlHelper<TModel> htmlHelper, 
                                                            Expression<Func<TModel, TProp>> expression, 
                                                            object htmlAttributes, 
                                                            bool canEdit)
    {
        var htmlAttributeDictionary = SetDisabledAttribute(htmlAttributes, canEdit);

        return htmlHelper.TextBoxFor(expression, htmlAttributeDictionary);
    }        

    private static RouteValueDictionary SetDisabledAttribute(object htmlAttributes, bool canEdit)
    {
        var htmlAttributeDictionary = new RouteValueDictionary(htmlAttributes);

        if (!canEdit)
        {
            htmlAttributeDictionary.Add(DisabledAttribute, DisabledAttribute);
        }

        return htmlAttributeDictionary;
    }
}

Тогда вам просто нужно сослаться на ваш новый класс и вызвать@Html.TextBoxFor(m => m.SomeValue, new { @class = "someClass" }, <Your bool value>)

Стоит отметить, что вам необходимо определить эти расширения для любой из перегрузок TextBoxFor, которые вы хотели бы использовать, но это кажется разумным компромиссом. Вы также можете использовать большую часть того же кода для других HtmlHelpers, к которым вы хотите добавить функциональность.

0

приведенного ниже, дает аналогичные результаты, но это, возможно, более хрупко:

@Html.TextBoxFor(
     model => model.Street, 
     new { @class = "form-control" }
).DisabledIf(Model.IsReadOnly)

Расширение:

using System.Text.RegularExpressions;
using System.Web.Mvc;

namespace xxx.HtmlHelpers
{
    public static class MvcHtmlStringExtensions
    {

        private static readonly Regex OpeningTagPattern;

        static MvcHtmlStringExtensions()
        {
            OpeningTagPattern = new Regex("<[a-zA-Z]*");
        }

        public static MvcHtmlString DisabledIf(this MvcHtmlString controlHtml, bool isDisabled)
        {
            if (!isDisabled) return controlHtml;
            return
                new MvcHtmlString(OpeningTagPattern.Replace(controlHtml.ToString(),
                    x => string.Format("{0} disabled=\"disabled\"", x.Groups[0])));
        }

    }
}
Я переключаю свой код, чтобы использовать Чака Норриса. версия выше :)
0

@{ 
    if(Model.StageID != null &&   Model.StageID > 0)
    {
        @Html.TextBoxFor(model => model.Street, 
             new
             {
                @class = "", 
                disabled = (Model.StageID==(int)MyEnum.Sth) ? "disabled" : "" 
             })
    }else{

        @Html.TextBoxFor(model => model.Street, 
             new
             {
                @class = ""
             })
    }
}
20

и я закончил, используя этот метод расширения для него

public static class AttributesExtensions
{
    public static RouteValueDictionary DisabledIf(
        this object htmlAttributes, 
        bool disabled
    )
    {
        var attributes = new RouteValueDictionary(htmlAttributes);
        if (disabled)
        {
            attributes["disabled"] = "disabled";
        }
        return attributes;
    }
}

И после этого вы можете использовать это так

@Html.TextBoxFor(
    model => model.Street, 
    new { @class = "" }.DisabledIf(Model.StageID==(int)MyEnum.Sth)
)

EDIT (послеПавел& APOS; sкомментарий):

Использованиеdata-xxx Атрибуты HTML могут быть добыты с помощью конструктораSystem.Web.Routing.RouteValueDictionary класс, так как подчеркивания не будут автоматически преобразованы в знак минус.

Используйте методSystem.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes вместо этого: решит эту проблему.

UPDATED CODE (Только тело метода расширения)

var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (disabled)
{
    attributes["disabled"] = "disabled";
}
return attributes;
это довольно нахально: & gt; но мне нравится это. Однако я добавляю свой (более хрупкий) вариант
Спасибо @ChuckNorris и тоже Полу за исправление. Я только что отредактировал ответ.
В принятом ответе есть проблема. Вы должны вызвать HtmlHelper.AnonymousObjectToHtmlAttributes (htmlAttributes) вместо нового RouteValueDictionary (htmlAttributes) HtmlHelper.AnonymousObjectToHtmlAttributes (htmlAttributes) преобразует все подчеркивания в атрибуте hhens
это работает, я должен тебе пива! Спасибо Tony
Я буду ждать этого xD

Похожие вопросы