MVC3 Условно отключить Html.TextBoxFor()

У меня есть веб-приложение С#.Net. В этом приложении мне нужно условно отключить элементы управления Html.TextBoxFor (также Html.DropDownListFor controls) на основе того, кто зарегистрировался в системе. Я попытался использовать

 @Html.TextBoxFor(model => model.ProposalName, new { @ViewBag.IsDisabled })

Где @ViewBag.IsDisabled установлено значение String.Empty или "disabled" в контроллере. Однако это отображается как IsDisabled='disabled' или IsDisabled="", поэтому элемент управления не отключается. Когда я попробовал

@Html.TextBoxFor(model => model.ProposalName, new { @ViewBag.Disabled })

Элемент управления всегда отключен, даже если ViewBag.Disabled не содержит текста. Как я могу условно отключить элементы управления Html.TextBoxFor()?

Ответ 1

Try

@Html.TextBoxFor(model => model.ProposalName, ViewBag.Disabled ? (object)new { disabled="disabled" } : new {})

Ответ 2

Решение, отправленное с помощью @epignosisx, работает, но может быть проблемой, если вы хотите добавить какой-то другой атрибут, потому что вам придется добавить его в оба объекта (один с disabled и тот, который теперь пуст).

Еще хуже, если у вас есть другое свойство bool, потому что у вас будет четыре разных объекта, каждый из которых будет для каждой комбинации.

Лучшее решение здесь (с небольшим количеством кода) заключается в создании метода расширения для HtmlHelper для получения вашего логического свойства в качестве параметра.

public static MvcHtmlString TextBoxDisabledFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool disabled, object htmlAttributes = null)
{
    return TextBoxDisabledFor(htmlHelper, expression, disabled, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}

public static MvcHtmlString TextBoxDisabledFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool disabled, IDictionary<string, object> htmlAttributes)
{
    if (htmlAttributes == null)
        htmlAttributes = new Dictionary<string, object>();
    if (disabled)
        htmlAttributes["disabled"] = "disabled";
    return htmlHelper.TextBoxFor(expression, htmlAttributes);
}

Вот еще один пример

Ответ 3

У меня была такая же проблема и я решил написать собственный метод расширения HtmlHelper.

public static MvcHtmlString Disable(this MvcHtmlString helper, bool disabled)
    {
        if (helper == null)
            throw new ArgumentNullException();

        if (disabled)
        {
            string html = helper.ToString();
            int startIndex = html.IndexOf('>');

            html = html.Insert(startIndex, " disabled=\"disabled\"");
            return MvcHtmlString.Create(html);
        }

        return helper;
    }

Это будет принимать логическое значение, чтобы указать, должен ли элемент управления быть отключен или нет. Он просто добавляет disabled="disabled" только внутри первого >, который встречается в строке.

Вы можете использовать его, как показано ниже.

@Html.TextBoxFor(model => model.ProposalName).Disable(true)

Ответ 4

Вот метод, который я использую, который не требует расширений, и не ограничивает вас только одним атрибутом HTML. Предполагается, что в вашей модели есть логическое свойство с именем "Отключено", но вы можете поставить туда, где хотите, до тех пор, пока он вычисляет логическое значение для тернарного оператора:

@Html.TextBoxFor(model => model.Whatever,
  new Dictionary<string, object>() {
    { "size", "5" },
    { "class", "someclasshere" },
    { model.Disabled ? "disabled" : "data-notdisabled", "disabled" }
  })

Ограничение стандартной нотной заметкой заключается в том, что имя атрибута не может быть динамическим. Создав словарь правильного типа, вы можете сделать динамическое имя атрибута, а затем передать этот словарь в текстовое поле в качестве словаря атрибутов. Когда поле не должно быть отключено, оно передает атрибут с именем "data-notdisabled" вместо одного "disabled", который браузер игнорирует.

Ответ 5

Расширение ответа @James, я написал это расширение HtmlHelper, которое обновляет/удаляет атрибут disabled, если он уже присутствует, или добавляет его, если нет:

public static MvcHtmlString Disable(this MvcHtmlString helper, bool disabled) {
    string html = helper.ToString();
    var regex = new Regex("(disabled(?:=\".*\")?)");
    if (regex.IsMatch(html)) {
        html = regex.Replace(html, disabled ? "disabled=\"disabled\"" : "", 1);
    } else {
        regex = new Regex(@"(\/?>)");
        html = regex.Replace(html, disabled ? "disabled=\"disabled\"$1" : "$1", 1);
    }
    return MvcHtmlString.Create(html);
}

Он также отлично работает с самозакрывающимися тегами (например, <input />).

Использование одинаковое:

@Html.TextBoxFor(model => model.PropertyName).Disable(true)

Протестировано на @Html.DropDownListFor() и @Html.TextBoxFor().