Reputation: 885
When using an HTML Helper, what is the best method to set an attribute based on a condition. For example
<%if (Page.User.IsInRole("administrator")) {%>
<%=Html.TextBoxFor(m => m.FirstName, new {@class='contactDetails'}%>
<%} else {%>
<%=Html.TextBoxFor(m => m.FirstName, new {@class='contactDetails', disabled = true}%>
<%}%>
There must be a better way to programmatically add just one additional KeyPair to the anonymous type? Can't use
new { .... disabled = Page.User.IsInRole("administrator") ... }
as the browser takes any disabled attribute value as making the input disabled
Upvotes: 19
Views: 45957
Reputation: 37633
It works for me as well...
<%: Html.DropDownList("SportID", (SelectList)ViewData["SportsSelectList"], "-- Select --", new { @disabled = "disabled", @readonly = "readonly" })%>
<%= Html.CheckBoxFor(model => model.IsActive, new { @disabled = "disabled", @readonly = "readonly" })%>
Upvotes: 14
Reputation: 4931
Created an extension method on Object that will create a copy of the input object excluding any properties that are null, and return it all as dictionary that makes it easily used in MVC HtmlHelpers:
public static Dictionary<string, object> StripAnonymousNulls(this object attributes)
{
var ret = new Dictionary<string, object>();
foreach (var prop in attributes.GetType().GetProperties())
{
var val = prop.GetValue(attributes, null);
if (val != null)
ret.Add(prop.Name, val);
}
return ret;
}
Not sure about performance implications of reflecting through properties twice, and don't like the name of the extension method much, but it seems to do the job well ...
new {
@class = "contactDetails",
disabled = Page.User.IsInRole("administrator") ? "true" : null
}.StripAnonymousNulls()
Upvotes: 1
Reputation: 63512
You may want to consider writing your own HtmlHelper Extension class with a new TextBox method:
public static class HtmlHelperExtensions
{
public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression<Func<TModel, TProperty>> expression, string cssClass, bool disabled)
{
return disabled
? Html.TextBoxFor(expression, new {@class=cssClass, disabled="disabled"})
: Html.TextBoxFor(expression, new {@class=cssClass})
}
}
now (if this new class is in the same namespace, or you've imported the new namespace to your page header, or in the pages section of the web.config) you can do this on your aspx page:
<%=Html.TextBoxFor(m => m.FirstName, "contactDetails", Page.User.IsInRole("administrator")) %>
Upvotes: 1
Reputation: 885
Using @SLaks suggestion to use an Extension method, and using Jeremiah Clark's example Extension method I've written an extension method so I can now do
Html.TextBoxFor(m => m.FirstName,new{class='contactDetails', ...},Page.User.IsInRole("administrator"));
Not Sure if there's a better method though
public static class InputExtensions
{
public static IDictionary<string, object> TurnObjectIntoDictionary(object data)
{
var attr = BindingFlags.Public | BindingFlags.Instance;
var dict = new Dictionary<string, object>();
if (data == null)
return dict;
foreach (var property in data.GetType().GetProperties(attr))
{
if (property.CanRead)
{
dict.Add(property.Name, property.GetValue(data, null));
}
}
return dict;
}
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled)
{
IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes);
if (disabled)
values.Add("disabled","true");
return htmlHelper.TextBoxFor(expression, values);
}
public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled)
{
IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes);
if (disabled)
values.Add("disabled", "true");
return htmlHelper.TextAreaFor(expression, values);
}
public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes, bool disabled)
{
IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes);
if (disabled)
values.Add("disabled", "true");
return htmlHelper.CheckBoxFor(expression, values);
}
}
Upvotes: 4
Reputation: 1471
You may also define this param that way:
Page.User.IsInRole("administrator")
? (object)new { @class='contactDetails'}
: (object)new { @class='contactDetails', disabled = true}
Upvotes: 1
Reputation: 887235
You'll need to pass a Dictionary<string, object>
, and add the disabled
key inside an if
statement.
I recommend making an overload of the extension method that takes a bool disabled
parameter and adds it to a RouteValueDictionary
created from the attributes parameter if it's true
. (You could also remove the disabled
entry from the RouteValueDictionary
if it's false
, and not take another parameter)
Upvotes: 2
Reputation: 63512
Page.User.IsInRole("administrator") ? null : new { disabled = "disabled" }
Upvotes: 8
Reputation: 24747
I could suggest you to use mvccontrib.FluentHtml.
You can do something like this
<%=this.TextBox(m=>m.FirstNam ).Disabled(Page.User.IsInRole("administrator"))%>
Upvotes: 14