根据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"))
另一个解决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