Ich möchte das Deaktivierungsattribut basierend auf einer Bedingung für Html.TextBoxFor in asp.net MVC wie unten festlegen
@Html.TextBoxFor(model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" disabled = (Model.ExpireDate == null ? "disable" : "") })
Dieser Helfer hat zwei Ausgänge deaktiviert = "deaktiviert" oder deaktiviert = "". Bei beiden Themen wird das Textfeld deaktiviert.
Ich möchte das Textfeld deaktivieren, wenn Model.ExpireDate == null ist. Andernfalls möchte ich es aktivieren
asp.net-mvc
asp.net-mvc-3
razor
html-helper
Ghooti Farangi
quelle
quelle
Antworten:
Der gültige Weg ist:
disabled="disabled"
Browser könnten auch akzeptieren,
disabled=""
aber ich würde Ihnen den ersten Ansatz empfehlen.Vor diesem Hintergrund würde ich empfehlen, einen benutzerdefinierten HTML-Helfer zu schreiben, um diese Deaktivierungsfunktion in einem wiederverwendbaren Code zu kapseln :
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); } }
was Sie so verwenden könnten:
@Html.MyTextBoxFor( model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" }, Model.ExpireDate == null )
und Sie könnten noch mehr Intelligenz in diesen Helfer bringen:
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); } }
Damit Sie jetzt die deaktivierte Bedingung nicht mehr angeben müssen:
@Html.MyTextBoxFor( model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" } )
quelle
Tatsächlich übersetzt das interne Verhalten das anonyme Objekt in ein Wörterbuch. Was ich in diesen Szenarien mache, ist ein Wörterbuch:
@{ 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 })
Oder, wie Stephen hier kommentierte :
@Html.EditorFor(m => m.Description, Model.IsDisabled ? (object)new { disabled = "disabled" } : (object)new { })
quelle
Ich mag die Darin-Methode. Aber schneller Weg, um dies zu lösen,
Html.TextBox("Expiry", null, new { style = "width: 70px;", maxlength = "10", id = "expire-date", disabled = "disabled" }).ToString().Replace("disabled=\"disabled\"", (1 == 2 ? "" : "disabled=\"disabled\""))
quelle
Ein einfacher Ansatz, den ich verwendet habe, ist das bedingte Rendern:
@(Model.ExpireDate == null ? @Html.TextBoxFor(m => m.ExpireDate, new { @disabled = "disabled" }) : @Html.TextBoxFor(m => m.ExpireDate) )
quelle
Wenn Sie keine HTML-Helfer verwenden, können Sie einen einfachen ternären Ausdruck wie diesen verwenden:
<input name="Field" value="@Model.Field" tabindex="0" @(Model.IsDisabledField ? "disabled=\"disabled\"" : "")>
quelle
Ich habe es mit einigen Erweiterungsmethoden erreicht
private const string endFieldPattern = "^(.*?)>"; public static MvcHtmlString IsDisabled(this MvcHtmlString htmlString, bool disabled) { string rawString = htmlString.ToString(); if (disabled) { rawString = Regex.Replace(rawString, endFieldPattern, "$1 disabled=\"disabled\">"); } return new MvcHtmlString(rawString); } public static MvcHtmlString IsReadonly(this MvcHtmlString htmlString, bool @readonly) { string rawString = htmlString.ToString(); if (@readonly) { rawString = Regex.Replace(rawString, endFieldPattern, "$1 readonly=\"readonly\">"); } return new MvcHtmlString(rawString); }
und dann....
@Html.TextBoxFor(model => model.Name, new { @class= "someclass"}).IsDisabled(Model.ExpireDate == null)
quelle
Dies ist spät, kann aber für manche Menschen hilfreich sein.
Ich habe die Antwort von @ DarinDimitrov erweitert, um die Übergabe eines zweiten Objekts zu ermöglichen, das eine beliebige Anzahl von booleschen HTML-Attributen wie
disabled="disabled" checked="checked", selected="selected"
usw. akzeptiert .Das Attribut wird nur gerendert, wenn der Eigenschaftswert true ist, alles andere und das Attribut wird überhaupt nicht gerendert.
Der benutzerdefinierte wiederverwendbare 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; } }
Was Sie so verwenden können:
@Html.MyTextBoxFor(m => Model.Employee.Name , new { @class = "x-large" , placeholder = "Type something…" } , new { disabled = true})
quelle
Wird dies mit RouteValueDictionary (funktioniert gut als htmlAttributes, da es auf IDictionary basiert) und einer Erweiterungsmethode gelöst:
public static RouteValueDictionary AddIf(this RouteValueDictionary dict, bool condition, string name, object value) { if (condition) dict.Add(name, value); return dict; }
Verwendung:
@Html.TextBoxFor(m => m.GovId, new RouteValueDictionary(new { @class = "form-control" }) .AddIf(Model.IsEntityFieldsLocked, "disabled", "disabled"))
Das Guthaben geht an https://stackoverflow.com/a/3481969/40939
quelle
Wenn Sie keine HTML-Helfer verwenden möchten, schauen Sie sich meine Lösung an
disabled="@(your Expression that returns true or false")"
dass es
@{ bool isManager = (Session["User"] as User).IsManager; } <textarea rows="4" name="LetterManagerNotes" disabled="@(!isManager)"></textarea>
und ich denke, der bessere Weg, dies zu tun, besteht darin, diesen Check in der Steuerung durchzuführen und ihn in einer Variablen zu speichern, auf die in der Ansicht zugegriffen werden kann (Razor Engine), um dies zu tun
the view free from business logic
quelle
Eine weitere Lösung wäre,
Dictionary<string, object>
vor dem AufrufenTextBoxFor
ein Wörterbuch zu erstellen und dieses weiterzugeben."disabled"
Fügen Sie im Wörterbuch nur Schlüssel hinzu, wenn das Textfeld deaktiviert werden soll. Nicht die sauberste Lösung, aber einfach und unkompliziert.quelle
Ein anderer Ansatz besteht darin, das Textfeld auf der Clientseite zu deaktivieren.
In Ihrem Fall haben Sie nur ein Textfeld, das Sie deaktivieren müssen. Berücksichtigen Sie jedoch den Fall, dass Sie mehrere Eingabe-, Auswahl- und Textfelder haben, die Sie deaktivieren müssen.
Es ist viel einfacher, dies über jquery + zu tun (da wir uns nicht auf Daten verlassen können, die vom Client stammen). Fügen Sie dem Controller eine Logik hinzu, um zu verhindern, dass diese Felder gespeichert werden.
Hier ist ein Beispiel:
<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); } }
quelle
Ich mag den Ansatz der Erweiterungsmethode, damit Sie nicht alle möglichen Parameter durchlaufen müssen.
Die Verwendung von regulären Ausdrücken kann jedoch ziemlich schwierig (und etwas langsamer) sein, daher habe ich
XDocument
stattdessen Folgendes verwendet :public static MvcHtmlString SetDisabled(this MvcHtmlString html, bool isDisabled) { var xDocument = XDocument.Parse(html.ToHtmlString()); if (!(xDocument.FirstNode is XElement element)) { return html; } element.SetAttributeValue("disabled", isDisabled ? "disabled" : null); return MvcHtmlString.Create(element.ToString()); }
Verwenden Sie die Erweiterungsmethode wie folgt:
@Html.EditorFor(m => m.MyProperty).SetDisabled(Model.ExpireDate == null)
quelle