2012-01-31 17 views
26

Tengo una aplicación web de C# .Net. En esa aplicación, debo deshabilitar de forma condicional los controles Html.TextBoxFor (también controles Html.DropDownListFor) según quién haya iniciado sesión en el sistema. He intentado utilizarMVC3 Deshabilitar condicionalmente Html.TextBoxFor()

@Html.TextBoxFor(model => model.ProposalName, new { @ViewBag.IsDisabled }) 

Dónde @ViewBag.IsDisabled se ha configurado como String.Empty o "desactivado" en el controlador. Sin embargo, esto se representa como IsDisabled='disabled' o IsDisabled="" por lo que el control no está deshabilitado. Cuando traté

@Html.TextBoxFor(model => model.ProposalName, new { @ViewBag.Disabled }) 

El control siempre se desactivará aun cuando ViewBag.Disabled no contenían texto. ¿Cómo puedo deshabilitar condicionalmente los controles Html.TextBoxFor()?

Respuesta

51

Trate

@Html.TextBoxFor(model => model.ProposalName, ViewBag.Disabled ? (object)new { disabled="disabled" } : new {}) 
+0

@epig .... interesante. ¿Cuál debería ser el valor de ViewBag.Disabled? – MikeTWebb

+1

@MikeTWebb ViewBag.Disabled debe ser un valor booleano. – epignosisx

+0

@epig .... verdadero o falso son los valores. ¡Funciona genial! Gracias – MikeTWebb

19

La solución Publicado por @epignosisx funciona, pero puede ser un problema si desea agregar algún otro atributo, ya que tendrá que añadir que las dos objetos (el que tiene disabled y el ahora está vacío).

Peor aún si tiene alguna otra propiedad bool porque tendrá cuatro objetos diferentes, cada uno para cada combinación.

La mejor solución aquí (con un poco más de código) es crear un método de extensión para que HtmlHelper reciba su propiedad booleana como parámetro.

public static MvcHtmlString TextBoxDisabledFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool disabled, object htmlAttributes = null) 
{ 
    return TextBoxDisabledFor(htmlHelper, expression, disabled, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 
} 

public static MvcHtmlString TextBoxDisabledFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool disabled, IDictionary<string, object> htmlAttributes) 
{ 
    if (htmlAttributes == null) 
     htmlAttributes = new Dictionary<string, object>(); 
    if (disabled) 
     htmlAttributes["disabled"] = "disabled"; 
    return htmlHelper.TextBoxFor(expression, htmlAttributes); 
} 

Here there is another example

8

tenía este mismo problema y decidí escribir mi propio método HtmlHelper extensión.

public static MvcHtmlString Disable(this MvcHtmlString helper, bool disabled) 
    { 
     if (helper == null) 
      throw new ArgumentNullException(); 

     if (disabled) 
     { 
      string html = helper.ToString(); 
      int startIndex = html.IndexOf('>'); 

      html = html.Insert(startIndex, " disabled=\"disabled\""); 
      return MvcHtmlString.Create(html); 
     } 

     return helper; 
    } 

Esto aceptará un valor booleano para indicar si el control debe estar desactivado o no. Simplemente agrega disabled="disabled" justo dentro del primer > que aparece en una cadena.

Puede utilizarlo como a continuación.

@Html.TextBoxFor(model => model.ProposalName).Disable(true)

+0

muy bien ...... – Bohn

5

Aquí es el método que utilizo, que no requiere extensiones, y no lo limita a un solo atributo HTML. Se asume que hay una propiedad booleana denominada "discapacitados" en su modelo, pero se puede poner lo que quería en ese país, siempre y cuando se evalúa como booleanas para el operador ternario:

@Html.TextBoxFor(model => model.Whatever, 
    new Dictionary<string, object>() { 
    { "size", "5" }, 
    { "class", "someclasshere" }, 
    { model.Disabled ? "disabled" : "data-notdisabled", "disabled" } 
    }) 

La limitación con el acceso directo estándar la notación es que el nombre del atributo no puede ser dinámico. Al crear un diccionario del tipo correcto, puede hacer que el nombre del atributo sea dinámico, y luego pasar ese diccionario al cuadro de texto como el diccionario de atributos. Cuando no se debe deshabilitar el campo, pasa un atributo llamado "datos no desactivados" en lugar de uno llamado "deshabilitado", que el navegador ignorará.

2

Extendiendo @ respuesta de James, escribí esta extensión HtmlHelper que las actualizaciones/elimina el atributo disabled si ya está presente, o lo añade si no:

public static MvcHtmlString Disable(this MvcHtmlString helper, bool disabled) { 
    string html = helper.ToString(); 
    var regex = new Regex("(disabled(?:=\".*\")?)"); 
    if (regex.IsMatch(html)) { 
     html = regex.Replace(html, disabled ? "disabled=\"disabled\"" : "", 1); 
    } else { 
     regex = new Regex(@"(\/?>)"); 
     html = regex.Replace(html, disabled ? "disabled=\"disabled\"$1" : "$1", 1); 
    } 
    return MvcHtmlString.Create(html); 
} 

También juega muy bien con las etiquetas de cierre automático (como <input />).

El uso es el mismo:

@Html.TextBoxFor(model => model.PropertyName).Disable(true) 

se evalúa en ambos @Html.DropDownListFor() y @Html.TextBoxFor().

Cuestiones relacionadas