Установите атрибут disable на основе условия для Html.TextBoxFor
Я хочу установить атрибут disable на основе условия для Html.TextBoxFor in asp.net MVC, как показано ниже
@Html.TextBoxFor(model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" disabled = (Model.ExpireDate == null ? "disable" : "") })
этот помощник имеет два выхода для гостей с ограниченными физическими="disabled" или отключен="". обе темы делают текстовое поле отключенным.
Я хочу отключить текстовое поле, если модель.ExpireDate = = null еще я хочу включить его
11 ответов:
действительный способ:
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\""))
Я достиг этого, используя некоторые методы расширения
public static MvcHtmlString IsDisabled(this MvcHtmlString htmlString, bool disabled) { string rawstring = htmlString.ToString(); if (disabled) { rawstring = rawstring.Insert(rawstring.Length - 2, "disabled=\"disabled\""); } return new MvcHtmlString(rawstring); } public static MvcHtmlString IsReadonly(this MvcHtmlString htmlString, bool @readonly) { string rawstring = htmlString.ToString(); if (@readonly) { rawstring = rawstring.Insert(rawstring.Length - 2, "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"
etc.он будет отображать атрибут только в том случае, если значение свойства true, все остальное и атрибут не будут отображаться вообще.
пользовательский повторно используемый 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})
Если вы не используете HTML-помощники, вы можете использовать простое тернарное выражение следующим образом:
<input name="Field" value="@Model.Field" tabindex="0" @(Model.IsDisabledField ? "disabled=\"disabled\"" : "")>
один простой подход, который я использовал-это условное отображение:
@(Model.ExpireDate == null ? @Html.TextBoxFor(m => m.ExpireDate, new { @disabled = "disabled" }) : @Html.TextBoxFor(m => m.ExpireDate) )
решается это с помощью 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
еще одним решением было бы создать
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); } }
Если вы не хотите использовать HTML-помощники взгляните на это мое решение
disabled="@(your Expression that returns true or false")"
что это
@{ bool isManager = (Session["User"] as User).IsManager; } <textarea rows="4" name="LetterManagerNotes" disabled="@(!isManager)"></textarea>
и я думаю, что лучший способ сделать это - сделать это проверить контроллер и сохранить его в переменной, доступной внутри представления (Razor engine), чтобы сделать
the view free from business logic