根据Html.TextBoxFor的条件设置禁用属性

我想根据下面的asp.net MVC中的Html.TextBoxFor条件设置禁用属性

@Html.TextBoxFor(model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" disabled = (Model.ExpireDate == null ? "disable" : "") }) 

这个帮手有两个输出禁用=“禁用”或禁用=“”。 这两个主题使文本框禁用。

我想禁用文本框,如果Model.ExpireDate == null否则我想启用它

有效的方法是:

 disabled="disabled" 

浏览器也可能接受 disabled=""但我会build议你第一种方法。

现在这么说,我会build议你写一个自定义的HTML帮助器,以封装这个禁用function到一个可重用的一段代码:

 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 }) 

或者,正如Stephen 在这里评论的那样:

 @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\"")) 

这已经很晚了,但可能对一些人有所帮助。

我已经扩展@ DarinDimitrov的答案,允许传递第二个对象,可以采取任何数量的布尔html属性,如disabled="disabled" checked="checked", selected="selected"

它只会在属性值为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}) 

我用一些扩展方法实现了它

 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) 

我使用的一个简单的方法是有条件的渲染:

 @(Model.ExpireDate == null ? @Html.TextBoxFor(m => m.ExpireDate, new { @disabled = "disabled" }) : @Html.TextBoxFor(m => m.ExpireDate) ) 

解决这个使用RouteValueDictionary(正常工作,因为它基于IDictionary htmlAttributes)和扩展方法:

 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

另一个解决scheme是在调用TextBoxFor并传递该字典之前创build一个Dictionary<string, object> 。 在字典中,只有在文本框被分类的情况下,才添加"disabled"键。 不是最简单而直接的解决scheme。

如果你不使用html助手,你可以使用如下简单的三元expression式:

 <input name="Field" value="@Model.Field" tabindex="0" @(Model.IsDisabledField ? "disabled=\"disabled\"" : "")> 

另一种方法是禁用客户端的文本框。

在你的情况下,你只有一个文本框,你需要禁用,但考虑你有多个input,select和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); } } 

如果你不想使用Html Helpers看看我的解决scheme

 disabled="@(your Expression that returns true or false")" 

 @{ bool isManager = (Session["User"] as User).IsManager; } <textarea rows="4" name="LetterManagerNotes" disabled="@(!isManager)"></textarea> 

我认为最好的办法是在控制器中进行检查,并将其保存在视图内可访问的variables(Razor引擎)中,以使the view free from business logic