Asp.net mvc MVC 3:有条件地使用HtmlHelpers添加Disabled属性
我有一个ASP.NETMVC3Web应用程序,我正在使用HtmlHelper类向视图页面添加一个复选框,如下所示Asp.net mvc MVC 3:有条件地使用HtmlHelpers添加Disabled属性,asp.net-mvc,asp.net-mvc-3,html-helper,Asp.net Mvc,Asp.net Mvc 3,Html Helper,我有一个ASP.NETMVC3Web应用程序,我正在使用HtmlHelper类向视图页面添加一个复选框,如下所示 @Html.CheckBox("CheckBox1", true, new { @class = "Class1" }) 我想做的是根据视图状态属性有条件地添加disabled属性。基本上以下是理想的 @Html.CheckBox("CheckBox1", true, new { @class = "Class1", @disabled = Model.ReadOnly }) 不
@Html.CheckBox("CheckBox1", true, new { @class = "Class1" })
我想做的是根据视图状态属性有条件地添加disabled属性。基本上以下是理想的
@Html.CheckBox("CheckBox1", true, new { @class = "Class1", @disabled = Model.ReadOnly })
不幸的是,由于禁用属性的性质,这将不起作用,因为分配给禁用属性的任何值(甚至“false”)都将转换为true
我已经想到了一些解决这个问题的办法,所以问题不在于我如何才能做到这一点。但是,有没有一种简单的方法像上面想要的方法?或者我必须求助于下列方法之一
我知道我能做什么
Html.CheckBox
行(可读性不好-可能会抛出标记警告-不确定)在视图/帮助程序中的某个位置定义此项
@functions {
object getHtmlAttributes (bool ReadOnly, string CssClass)
{
if (ReadOnly) {
return new { @class = CssClass, @readonly = "readonly" };
}
return new { @class = CssClass };
}
}
然后使用:
@Html.TextBox("name", "value", @getHtmlAttributes(Model.ReadOnly, "test"))
下面是我对这个类似问题的回答:
我创建了以下帮助器-它接受一个布尔值和一个匿名对象。如果disabled为true,则将disabled属性添加到值为“disabled”的匿名对象(实际上是一个字典),否则根本不添加属性
public static RouteValueDictionary ConditionalDisable(
bool disabled,
object htmlAttributes = null)
{
var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (disabled)
dictionary.Add("disabled", "disabled");
return dictionary;
}
这方面的一个例子是:
@Html.TextBoxFor(m => m.SomeProperty,
HtmlHelpers.ConditionalDisable(true, new { @class = "someClass"))
对我来说,这种方法的一个巨大优势是,它几乎适用于所有MVC HTMLHelper,因为它们都有接受RouteValueDictionary而不是匿名对象的重载
注意事项:HtmlHelper.AnonymousObjectToHtmlatAttributes()
使用一些奇特的代码忍者工作来完成任务。我不完全确定它的性能如何。。。但这已经足够我用它做什么了。您的里程可能会有所不同
我并不特别喜欢它的名字,但我想不出更好的名字了。重命名很容易
我也不喜欢使用语法,但我还是想不出更好的方法。这应该不难改变。对象的扩展方法是一种思想。。。您将以
new{@class=“someClass”}.ConditionalDisable(true)
结束,但是如果您只想要disable属性,并且没有任何附加内容,那么您将以类似new{}.ConditionalDisable(true)的东西结束代码>并且您还将得到一个扩展方法,该方法将显示所有对象
。。。这可能是不可取的。如果您想要更简洁的语法而不需要helper函数,那么在定义用于@html.Checkbox helper的html属性的字典时,可以使用三元语句
@Html.CheckBox("CheckBox1", true, Model.ReadOnly
? new { @class = "Class1", @disabled = Model.ReadOnly }
: null)
在本例中,is Model.ReadOnly为false,null作为html属性的字典传递。执行添加禁用属性客户端的操作对我有效。注意:您应该检查哪些字段允许在服务器端进行编辑,但对于以装饰性方式声明禁用属性的情况也是如此
在本例中,我使用jQuery禁用了表单的所有子元素
if (Model.CanEdit)
{
<script type="text/javascript">
$(document).ready(function() {
$('#editForm *').attr('disabled', true);
});
</script>
}
if(Model.CanEdit)
{
$(文档).ready(函数(){
$('editForm*').attr('disabled',true);
});
}
@Html.TextBoxFor(m=>m.FieldName,Html.fixBoolatAttributes(新){
@class=“myClass”,
@readonly=myFlag
}))
公共静态类BooleanAttributeFix
{
///
///规范化HTML布尔属性,使readonly=true变为readonly=“readonly”,并
///readonly=false将完全删除该属性。
///
///
///
///
公共静态RouteValueDictionary FixBoolatAttributes(此HtmlHelper HtmlHelper,对象htmlAttributes)
{
var attrs=HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
foreach(新[]{“disabled”,“readonly”}中的var attrName)
{
目标价值;
if(attrs.TryGetValue(attrName,out值))
{
如果(真实性(值))
{
//从readonly=“true”更改为readonly=“readonly”
attrs[attrName]=attrName;
}
其他的
{
//完全删除属性
attrs.Remove(attrName);
}
}
}
返回属性;
}
///
///对于值是否为真,应用类似于javascript的松散规则。
///例如,1=true,非空字符串=true等等。
///
///
///
私有静态布尔值(对象值)
{
if(val==null)
返回false;
if(val是字符串)
{
return!String.IsNullOrEmpty((String)val);
}
类型t=val.GetType();
if(t.IsValueType&&Nullable.GetUnderlineType(t)==null)
{
//如果是不可为null的值类型,如int,则需要检查
//默认值,例如0。
object defaultValue=Activator.CreateInstance(t);
//使用.Equals比较值,而不是要比较的==值
//值而不是装箱对象。
//看http://stackoverflow.com/questions/6205029/comparing-boxed-value-types
return!val.Equals(默认值);
}
返回true;
}
}
您认为我的简单解决方案怎么样?它可以轻松处理两种可能的HtmlAttributes
类型:
字典
- 匿名
@Html.TextBoxFor(m => m.FieldName, Html.FixBoolAttributes(new {
@class = "myClass",
@readonly = myFlag
}))
public static class BooleanAttributeFix
{
/// <summary>
/// Normalises HTML boolean attributes so that readonly=true becomes readonly="readonly" and
/// readonly=false removes the attribute completely.
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public static RouteValueDictionary FixBoolAttributes(this HtmlHelper htmlHelper, object htmlAttributes)
{
var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
foreach(var attrName in new[] { "disabled", "readonly" })
{
object value;
if(attrs.TryGetValue(attrName, out value))
{
if(isTruthy(value))
{
// Change from readonly="true" to readonly="readonly"
attrs[attrName] = attrName;
}
else
{
// Remove attribute entirely
attrs.Remove(attrName);
}
}
}
return attrs;
}
/// <summary>
/// Apply similar loose rules like javascript does for whether a value is true or not.
/// e.g. 1 = true, non-empty string = true and so on.
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
private static bool isTruthy(object val)
{
if(val == null)
return false;
if(val is string)
{
return !String.IsNullOrEmpty((string)val);
}
Type t = val.GetType();
if(t.IsValueType && Nullable.GetUnderlyingType(t) == null)
{
// If a non-nullable value type such as int we want to check for the
// default value e.g. 0.
object defaultValue = Activator.CreateInstance(t);
// Use .Equals to compare the values rather than == as we want to compare
// the values rather than the boxing objects.
// See http://stackoverflow.com/questions/6205029/comparing-boxed-value-types
return !val.Equals(defaultValue);
}
return true;
}
}
public static class HtmlAttributesExtensions
{
public static IDictionary<string, object> AddHtmlAttrItem(this object obj, string name, object value, bool condition)
{
var items= !condition ? new RouteValueDictionary(obj) : new RouteValueDictionary(obj) {{name, value}};
return UnderlineToDashInDictionaryKeys(items);
}
public static IDictionary<string, object> AddHtmlAttrItem(this IDictionary<string, object> dictSource, string name, object value, bool condition)
{
if (!condition)
return dictSource;
dictSource.Add(name, value);
return UnderlineToDashInDictionaryKeys(dictSource);
}
private static IDictionary<string, object> UnderlineToDashInDictionaryKeys(IDictionary<string,object> items)
{
var newItems = new RouteValueDictionary();
foreach (var item in items)
{
newItems.Add(item.Key.Replace("_", "-"), item.Value);
}
return newItems;
}
}
@{
var hasDisabled=true;
}
@Html.CheckBox("CheckBox1"
, true
, new { @class = "Class1"}
.AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.
@Html.CheckBox("CheckBox1"
, true
, new Dictionary<string, object> { { "class", "Class1" }
.AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.
@{
var hasDisabled=true;
var hasMax=false ;
var hasMin=true ;
}
@Html.CheckBox("CheckBox1"
, true
, new { @class = "Class1"}
.AddHtmlAttrItem("disabled", "disabled", hasDisabled)
.AddHtmlAttrItem("data-max", "100", hasMax)
.AddHtmlAttrItem("data-min", "50", hasMin))
.
<script type="text/javascript">
var list, index;
list = document.getElementsByClassName("form-control");
for (index = 0; index < list.length; ++index) {
list[index].setAttribute('disabled', true);
}
</script>