Я хочу установить атрибут отключения на основе условия для Html.TextBoxFor в asp.net MVC, как показано ниже
@Html.TextBoxFor(model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" disabled = (Model.ExpireDate == null ? "disable" : "") })
У этого помощника два выхода: disabled = "disabled" или disabled = "". обе темы отключают текстовое поле.
Я хочу отключить текстовое поле, если Model.ExpireDate == null, иначе я хочу его включить
asp.net-mvc
asp.net-mvc-3
razor
html-helper
Гхути Фаранги
источник
источник
Ответы:
Действительный способ:
disabled="disabled"
Браузеры также могут принять,
disabled=""
но я бы порекомендовал вам первый подход.Теперь, как говорится, я бы порекомендовал вам написать собственный помощник HTML, чтобы инкапсулировать эту функцию отключения в многоразовый фрагмент кода:
using System; using System.Linq.Expressions; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Html; using System.Web.Routing; public static class HtmlExtensions { public static IHtmlString MyTextBoxFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled ) { var attributes = new RouteValueDictionary(htmlAttributes); if (disabled) { attributes["disabled"] = "disabled"; } return htmlHelper.TextBoxFor(expression, attributes); } }
которые вы могли бы использовать так:
@Html.MyTextBoxFor( model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" }, Model.ExpireDate == null )
и вы можете добавить еще больше интеллекта в этот помощник:
public static class HtmlExtensions { public static IHtmlString MyTextBoxFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes ) { var attributes = new RouteValueDictionary(htmlAttributes); var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); if (metaData.Model == null) { attributes["disabled"] = "disabled"; } return htmlHelper.TextBoxFor(expression, attributes); } }
так что теперь вам больше не нужно указывать отключенное состояние:
@Html.MyTextBoxFor( model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" } )
источник
Фактически, внутреннее поведение - это перевод анонимного объекта в словарь. Итак, что я делаю в этих сценариях, это ищу словарь:
@{ var htmlAttributes = new Dictionary<string, object> { { "class" , "form-control"}, { "placeholder", "Why?" } }; if (Model.IsDisabled) { htmlAttributes.Add("disabled", "disabled"); } } @Html.EditorFor(m => m.Description, new { htmlAttributes = htmlAttributes })
Или, как здесь прокомментировал Стивен :
@Html.EditorFor(m => m.Description, Model.IsDisabled ? (object)new { disabled = "disabled" } : (object)new { })
источник
Мне нравится метод Дарина. Но быстрый способ решить эту проблему,
Html.TextBox("Expiry", null, new { style = "width: 70px;", maxlength = "10", id = "expire-date", disabled = "disabled" }).ToString().Replace("disabled=\"disabled\"", (1 == 2 ? "" : "disabled=\"disabled\""))
источник
Я использовал один простой подход - условный рендеринг:
@(Model.ExpireDate == null ? @Html.TextBoxFor(m => m.ExpireDate, new { @disabled = "disabled" }) : @Html.TextBoxFor(m => m.ExpireDate) )
источник
Если вы не используете помощники html, вы можете использовать простое тернарное выражение, подобное этому:
<input name="Field" value="@Model.Field" tabindex="0" @(Model.IsDisabledField ? "disabled=\"disabled\"" : "")>
источник
Я добился этого с помощью некоторых методов расширения
private const string endFieldPattern = "^(.*?)>"; public static MvcHtmlString IsDisabled(this MvcHtmlString htmlString, bool disabled) { string rawString = htmlString.ToString(); if (disabled) { rawString = Regex.Replace(rawString, endFieldPattern, "$1 disabled=\"disabled\">"); } return new MvcHtmlString(rawString); } public static MvcHtmlString IsReadonly(this MvcHtmlString htmlString, bool @readonly) { string rawString = htmlString.ToString(); if (@readonly) { rawString = Regex.Replace(rawString, endFieldPattern, "$1 readonly=\"readonly\">"); } return new MvcHtmlString(rawString); }
а потом....
@Html.TextBoxFor(model => model.Name, new { @class= "someclass"}).IsDisabled(Model.ExpireDate == null)
источник
Это поздно, но некоторым людям может быть полезно.
Я расширил ответ @DarinDimitrov, чтобы разрешить передачу второго объекта, который принимает любое количество логических атрибутов html, таких как
disabled="disabled" checked="checked", selected="selected"
и т. Д.Атрибут будет отображаться только в том случае, если значение свойства истинно, все остальное и атрибут не будет отображаться вообще.
Настраиваемый повторно используемый HtmlHelper:
public static class HtmlExtensions { public static IHtmlString MyTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, object booleanHtmlAttributes) { var attributes = new RouteValueDictionary(htmlAttributes); //Reflect over the properties of the newly added booleanHtmlAttributes object foreach (var prop in booleanHtmlAttributes.GetType().GetProperties()) { //Find only the properties that are true and inject into the main attributes. //and discard the rest. if (ValueIsTrue(prop.GetValue(booleanHtmlAttributes, null))) { attributes[prop.Name] = prop.Name; } } return htmlHelper.TextBoxFor(expression, attributes); } private static bool ValueIsTrue(object obj) { bool res = false; try { res = Convert.ToBoolean(obj); } catch (FormatException) { res = false; } catch(InvalidCastException) { res = false; } return res; } }
Что вы можете использовать так:
@Html.MyTextBoxFor(m => Model.Employee.Name , new { @class = "x-large" , placeholder = "Type something…" } , new { disabled = true})
источник
Решается это с помощью RouteValueDictionary (отлично работает как htmlAttributes, поскольку он основан на IDictionary) и метода расширения:
public static RouteValueDictionary AddIf(this RouteValueDictionary dict, bool condition, string name, object value) { if (condition) dict.Add(name, value); return dict; }
Применение:
@Html.TextBoxFor(m => m.GovId, new RouteValueDictionary(new { @class = "form-control" }) .AddIf(Model.IsEntityFieldsLocked, "disabled", "disabled"))
Кредит идет на https://stackoverflow.com/a/3481969/40939
источник
если вы не хотите использовать Html Helpers, взгляните на мое решение
disabled="@(your Expression that returns true or false")"
это
@{ bool isManager = (Session["User"] as User).IsManager; } <textarea rows="4" name="LetterManagerNotes" disabled="@(!isManager)"></textarea>
и я думаю, что лучший способ сделать это - выполнить эту проверку в контроллере и сохранить его в переменной, доступной внутри представления (движок Razor), чтобы сделать
the view free from business logic
источник
Еще одно решение - создать
Dictionary<string, object>
перед вызовомTextBoxFor
и передать этот словарь. В словарь добавляйте"disabled"
ключ только в том случае, если текстовое поле нужно отключить. Не самое изящное решение, но простое и понятное.источник
Другой подход - отключить текстовое поле на стороне клиента.
В вашем случае у вас есть только одно текстовое поле, которое вам нужно отключить, но рассмотрите случай, когда у вас есть несколько полей ввода, выбора и текстового поля, которые вам не нужно отключать.
Намного проще сделать это с помощью jquery + (поскольку мы не можем полагаться на данные, поступающие от клиента), добавьте некоторую логику в контроллер, чтобы предотвратить сохранение этих полей.
Вот пример:
<input id="document_Status" name="document.Status" type="hidden" value="2" /> $(document).ready(function () { disableAll(); } function disableAll() { var status = $('#document_Status').val(); if (status != 0) { $("input").attr('disabled', true); $("textarea").attr('disabled', true); $("select").attr('disabled', true); } }
источник
Мне нравится метод расширения, поэтому вам не нужно передавать все возможные параметры.
Однако использование регулярных выражений может быть довольно сложным (и несколько медленным), поэтому
XDocument
вместо этого я использовал :public static MvcHtmlString SetDisabled(this MvcHtmlString html, bool isDisabled) { var xDocument = XDocument.Parse(html.ToHtmlString()); if (!(xDocument.FirstNode is XElement element)) { return html; } element.SetAttributeValue("disabled", isDisabled ? "disabled" : null); return MvcHtmlString.Create(element.ToString()); }
Используйте такой метод расширения:
@Html.EditorFor(m => m.MyProperty).SetDisabled(Model.ExpireDate == null)
источник