asp.net-mvc - htmlattributes - validation asp net mvc
¿Cómo hago Editor para condicionalmente de solo lectura? (6)
Al escribir un método de ayuda, el director DRY puede ser respetado.
using System.Web.Mvc.Html;
public static MvcHtmlString Concat(this MvcHtmlString first, params MvcHtmlString[] strings)
{
return MvcHtmlString.Create(first.ToString() + string.Concat(strings.Select(s => ( s == null ? "" : s.ToString()))));
}
public static MvcHtmlString ConditionalEditFor<TModel,TValue>(this HtmlHelper<TModel> helper, bool EditCondition, Expression<Func<TModel, TValue>> Expression)
{
helper.ConditionalEditFor(EditCondition,Expression,false);
}
public static MvcHtmlString ConditionalEditFor<TModel, TValue>(this HtmlHelper<TModel> helper, bool EditCondition, Expression<Func<TModel, TValue>> Expression, bool IncludeValidationOnEdit)
{
if (EditCondition)
{
if (!IncludeValidationOnEdit)
return EditorExtensions.EditorFor<TModel, TValue>(helper, Expression);
else
return EditorExtensions.EditorFor<TModel, TValue>(helper, Expression).Concat(ValidationExtensions.ValidationMessageFor<TModel, TValue>(helper, Expression));
}
else
{
return DisplayExtensions.DisplayFor<TModel, TValue>(helper, Expression);
}
}
entonces en su opinión:
agregue una declaración condicional para determinar solo lectura, por ejemplo
@{bool IsReadOnly = YourCondition;}
@Html.ConditionalEditFor(!IsReadOnly/*condition*/, model => model.YourProperty,true /*do validation*/)
A continuación, puede agregar cualquier otra anulación que desee.
Tengo esta línea de código:
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })
Tengo una variable en mi diccionario de datos de vista llamado Readonly. ¿Cómo hago que la Cantidad sea de solo lectura si ViewBag.Readonly
es verdadera y no de solo lectura si es falsa?
Lo simple, pero la combinación de Razor con HTML (que es antiguo) hace que las cosas simples sean imposibles.
Ediciones:
No quiero usar una sentencia if. Es un último recurso porque viola la SECA, que en el pasado me han quemado severamente muchas veces por no haber seguido.
La línea que tengo arriba funciona en la medida en que hace que el cuadro de texto sea de solo lectura. Necesito hacer esto condicional basado en mi estado de vista.
Solución:
He usado lo siguiente. Todavía es una violación SECA, pero la reduce a una línea.
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = ViewBag.Readonly ? (object)new { @class = "form-control", @readonly = "htmlsucks" } : (object)new { @class = "form-control" } })
En caso de que tenga muchos lugares en su vista con tal lógica, creo que usar la biblioteca FluentDataAnnotations puede mantener su código limpio y claro.
Si está familiarizado con FluentValidator , su uso es muy similar.
En su caso, toda la lógica se moverá de una vista a la clase de anotación del modelo. En solo tendrá @Html.EditorFor(model => model.Quantity)
Incluso permite usar las propiedades del modelo en condiciones, por ejemplo, this.When(model => !model.AllowEditPhone, () => { this.For(m => m.Phone).SetReadOnly(false); });
Aquí está el paquete NuGet que requiere ASP.NET MVC 5. (El soporte para ASP.NET Core está en progreso).
Es muy sencillo. Hazlo asi.
@if((bool)ViewBag.Readonly)
{
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })
}
else
{
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } })
}
Hoy tuve que lidiar con este problema, ya que tuve que establecer Html.TextBoxFor
un atributo "solo lectura" en un elemento Html.TextBoxFor
. Terminé escribiendo el siguiente método de ayuda que me permitió solucionar el problema manteniendo un enfoque DRY:
/// <summary>
/// Gets an object containing a htmlAttributes collection for any Razor HTML helper component,
/// supporting a static set (anonymous object) and/or a dynamic set (Dictionary)
/// </summary>
/// <param name="fixedHtmlAttributes">A fixed set of htmlAttributes (anonymous object)</param>
/// <param name="dynamicHtmlAttributes">A dynamic set of htmlAttributes (Dictionary)</param>
/// <returns>A collection of htmlAttributes including a merge of the given set(s)</returns>
public static IDictionary<string, object> GetHtmlAttributes(
object fixedHtmlAttributes = null,
IDictionary<string, object> dynamicHtmlAttributes = null
)
{
var rvd = (fixedHtmlAttributes == null)
? new RouteValueDictionary()
: HtmlHelper.AnonymousObjectToHtmlAttributes(fixedHtmlAttributes);
if (dynamicHtmlAttributes != null)
{
foreach (KeyValuePair<string, object> kvp in dynamicHtmlAttributes)
rvd[kvp.Key] = kvp.Value;
}
return rvd;
}
Se puede utilizar de la siguiente manera:
var dic = new Dictionary<string,object>();
if (IsReadOnly()) dic.Add("readonly", "readonly");
Html.TextBoxFor(m => m.Name, GetHtmlAttributes(new { @class="someclass" }, dic))
El código se explica por sí mismo, sin embargo, también expliqué la lógica subyacente en esta publicación en mi blog.
JQUERY para leer el valor del control SETUP_TYPE y deshabilitar los controles con un selector CSS en particular.
$(function () {
if ($("#SETUP_TYPE").val() == "1") { $(''.XXX'').attr(''disabled'', true); }
})
$(function () {
if ($("#SETUP_TYPE").val() == "2") { $(''.YYY'').attr(''disabled'', true); }
})
Este control está deshabilitado si SETUP_TYPE es 1 o 2.
@Html.EditorFor(model => model.CLAIM, new { htmlAttributes = new { @class = "form-control XXX YYY" } })
Este control está deshabilitado si SETUP_TYPE es 1.
@Html.EditorFor(model => model.POLICY, new { htmlAttributes = new { @class = "form-control XXX" } })
Este control está deshabilitado si SETUP_TYPE es 2.
@Html.EditorFor(model => model.INSURED, new { htmlAttributes = new { @class = "form-control YYY" } })
EDIT: MVC 5
Controlador
ViewBag.Readonly=true;//false
Ver
@Html.EditorFor(model => model.Quantity, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" }} : new { htmlAttributes = new { @class = "form-control" } })