Установить отключить атрибут на основе условия для Html.TextBoxFor
Я хочу установить атрибут disable на основе условия для 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 else Я хочу включить его
Ответы
Ответ 1
Допустимый способ:
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"
}
)
Ответ 2
Собственно, внутреннее поведение переводит анонимный объект в словарь.
Итак, что я делаю в этих сценариях, зайдите в словарь:
@{
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 { })
Ответ 3
Мне нравится метод Дарина. Но быстрый способ решить эту проблему,
Html.TextBox("Expiry", null, new { style = "width: 70px;", maxlength = "10", id = "expire-date", disabled = "disabled" }).ToString().Replace("disabled=\"disabled\"", (1 == 2 ? "" : "disabled=\"disabled\""))
Ответ 4
Я добился этого с помощью некоторых методов расширения
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)
Ответ 5
Если вы не используете html-помощники, вы можете использовать простое трехмерное выражение:
<input name="Field"
value="@Model.Field" tabindex="0"
@(Model.IsDisabledField ? "disabled=\"disabled\"" : "")>
Ответ 6
Это поздно, но может быть полезно некоторым людям.
Я расширил ответ @DarinDimitrov, чтобы разрешить передачу второго объекта, который принимает любое количество логических атрибутов html, таких как disabled="disabled" checked="checked", selected="selected"
и т.д.
Он отобразит атрибут только в том случае, если значение свойства истинно, что-то еще, и атрибут вообще не будет отображаться.
Пользовательский reuseble 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})
Ответ 7
Один простой подход, который я использовал, - условный рендеринг:
@(Model.ExpireDate == null ?
@Html.TextBoxFor(m => m.ExpireDate, new { @disabled = "disabled" }) :
@Html.TextBoxFor(m => m.ExpireDate)
)
Ответ 8
Решается это с помощью 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"))
Кредит отправляется fooobar.com/questions/86157/...
Ответ 9
если вы не хотите использовать 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
Ответ 10
Еще одним решением было бы создать Dictionary<string, object>
перед вызовом TextBoxFor
и передать этот словарь. В словаре добавьте ключ "disabled"
, только если текстовое поле должно быть отключено. Не лучшее решение, но простое и понятное.
Ответ 11
Другой подход - отключить текстовое поле на стороне клиента.
В вашем случае у вас есть только одно текстовое поле, которое нужно отключить, но рассмотрите случай, когда у вас есть несколько полей ввода, выбора и textarea, которые вам нужно отключить.
Это намного проще сделать с помощью 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);
}
}