ASP.NET MVC में EditorFor () के लिए Html विशेषताएँ


129

मैं html विशेषताओं में पास क्यों नहीं कर सकता EditorFor()? जैसे;

<%= Html.EditorFor(model => model.Control.PeriodType, 
    new { disabled = "disabled", readonly = "readonly" }) %>

मैं मेटाडेटा का उपयोग नहीं करना चाहता

अद्यतन : समाधान यह देखने के लिए कॉल करने के लिए था:

 <%=Html.EditorFor( model => model.Control.PeriodEndDate, new {Modifiable=model.Control.PeriodEndDateModifiable})%>

और ViewData["Modifiable"]मेरे कस्टम EditorTemplates / String.ascx में उपयोग करें जहां मेरे पास कुछ दृश्य तर्क हैं जो निर्धारित करते हैं कि इनपुट में आसानी से और / या अक्षम विशेषताओं को जोड़ना है जो अनाम ऑब्जेक्ट पास किया गया है EditorFor()वह एक पैरामीटर है जिसे कहा जाता है additionalViewDataऔर इसके गुणों को संपादक टेम्पलेट में पास किया जाता है ViewDataसंग्रह।


19
गंभीरता से, अभी भी MVC3 में इस सीमा का कोई मतलब नहीं है और यह वास्तव में कष्टप्रद है। दुनिया भर के लोग समय व्यतीत कर रहे हैं और इस बकवास के साथ अपने बालों को बाहर खींच रहे हैं। मैं इसे Microsoft Connect को भेज रहा हूं।
बजे जूनियर मेहे सेप


3
क्या यह सिर्फ मुझे है, या ऐसा लगता है कि कुछ के लिए बहुत सारे बी एस की तरह लगता है जो सरल होना चाहिए?
एरिक के

हो सकता है कि यह आपकी सहायता करेगा: [CSSFor-HTML विशेषताओं के साथ EditorFor-Implementation] [1] [१]: stackoverflow.com/questions/12675708/…
FunThom

जवाबों:


96

EditorForमेटाडेटा के साथ काम करता है, इसलिए यदि आप HTML विशेषताओं को जोड़ना चाहते हैं तो आप हमेशा ऐसा कर सकते हैं । एक अन्य विकल्प केवल एक कस्टम टेम्पलेट लिखना और उपयोग करना है TextBoxFor:

<%= Html.TextBoxFor(model => model.Control.PeriodType, 
    new { disabled = "disabled", @readonly = "readonly" }) %>    

मेटाडेटा काम नहीं करेगा क्योंकि HTML विशेषताएँ मॉडल के अन्य गुणों के आधार पर भिन्न हो सकती हैं, दूसरे शब्दों में डोमेन या viemodel तर्क को HTML विशेषताओं को स्थिर मेटाडेटा नहीं निर्धारित करना चाहिए। या मैं इस बिंदु को याद कर रहा हूं, क्या मैं मेटाडेटा को गतिशील रूप से सेट कर सकता हूं?
टाइपो जॉनसन

क्या है PeriodType? क्या यह एक साधारण संपत्ति नहीं है? यदि यह एक जटिल वस्तु है आप एक आंशिक में रखकर पूरे टेम्पलेट को अनुकूलित कर सकती ~/Views/ControllerName/EditorTemplates/SomeType.ascxहै, जहां SomeTypeके प्रकार के नाम है PeriodTypeसंपत्ति।
डारिन दिमित्रोव

इसके अलावा आपके सुझाए गए कोड का मतलब पूरे मॉडल को एक आंशिक टेम्पलेट में बदलना होगा जो एक विशिष्ट संपत्ति तक पहुंचता है, इसका मतलब है कि मेरे पास प्रत्येक संपत्ति के लिए एक आंशिक होगा?
टाइपो जॉनसन

2
मैं तुम्हें अभी ले आता हूं। मैं <% = Html.EditorFor (मॉडल => model.Control.PeriodEndDate, नए {Modifiable = model.Control.PeriodEndDateModifiable}% 1 का उपयोग कर सकता हूं और ViewData ["PeriodEndDateModifiable"] का उपयोग अपने कस्टम EditorTememon / स्ट्रिंग में कर सकता हूं। धन्यवाद
टाइपो जॉनसन

1
@ JuniorMayhé, मैं इसे एक उबाऊ सीमा नहीं कहूंगा। यदि आप अधिक ध्यान से सोचते हैं तो आप समझेंगे कि यह समझ में आता है। वास्तव में EditorFor हेल्पर की पूरी बात यह है कि आपके पास एक समान टेम्पलेट हो सकता है। इस टेम्पलेट में कोई भी मार्कअप हो सकता है। जरूरी नहीं कि एक ही तत्व हो। यह @classएक संपादक टेम्पलेट के लिए परिभाषित करने के लिए बिल्कुल कोई मतलब नहीं होगा जिसमें उदाहरण के लिए 3 div होते हैं। Html.TextBoxFor हेल्पर आपको इसे परिभाषित करने की अनुमति देता है क्योंकि आप जानते हैं कि यह सहायक क्या उत्पन्न करता है - एक टेक्स्टबॉक्स तो यह एक वर्ग को एक इनपुट तत्व को परिभाषित करने के लिए समझ में आता है।
डारिन दिमित्रोव

115

अपडेट एमवीसी 5.1 अब सीधे नीचे के दृष्टिकोण का समर्थन करता है, इसलिए यह निर्मित संपादक के लिए भी काम करता है। http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features (यह या तो एक जैसे महान दिमाग का मामला है या वे मेरा जवाब पढ़ते हैं :)

अंत अद्यतन

यदि आपका अपना स्वयं का संपादक टेम्प्लेट या MVC 5.1 का उपयोग कर रहा है जो अब संपादकों में निर्मित के लिए सीधे नीचे दिए गए दृष्टिकोण का समर्थन करता है।

@Html.EditorFor(modelItem => item.YourProperty, 
  new { htmlAttributes = new { @class="verificationStatusSelect", style = "Width:50px"  } })

तब आपके टेम्पलेट में (MVC 5.1 में सरल प्रकारों के लिए आवश्यक नहीं)

@Html.TextBoxFor(m => m, ViewData["htmlAttributes"])

5
यह नई सुविधा चार साल पहले पूछी गई मूल समस्या को पूरी तरह हल करती है।
कोडरसेव

1
यदि इसके बजाय TextBoxFor और हेल्पर्स की तरह मैं कस्टम संपादक टेम्प्लेट के टन का उपयोग करता हूं, तो मैं नहीं कहूंगा कि उनमें से प्रत्येक में ViewData [...] को जोड़ना एक शानदार विचार है ...:
अलेक्जेंडर

42

MVC 5.1 के अनुसार, अब आप निम्नलिखित कार्य कर सकते हैं:

@Html.EditorFor(model => model, new { htmlAttributes = new { @class = "form-control" }, })

http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features


उपरोक्त लिंक मृत है। यह MVC 5.1 में उपलब्ध है, अधिक जानकारी यहाँ: asp.net/mvc/overview/releases/mvc51-release-notes#new-features
Alaa Masoud

1
धन्यवाद, मैंने लिंक को भी ठीक कर दिया।
vtforester

2
htmlAttributes को कैसे मर्ज करें?
बार्ट कैलिक्सो

यह केवल अंतर्निहित / डिफ़ॉल्ट EditorForटेम्प्लेट के साथ काम करता है । यदि आप अपना स्वयं का कार्यान्वयन करते हैं, तो आपको एंटोन के उत्तर का पालन करना होगा।
mxmissile

6

अब ASP.Net MVC 5.1 को इसके लिए समर्थन में एक बिल्ट मिला।

रिलीज नोट्स से

अब हम एक गुमनाम वस्तु के रूप में EditorFor में HTML विशेषताओं को पारित करने की अनुमति देते हैं।

उदाहरण के लिए:

@Html.EditorFor(model => model, 
              new { htmlAttributes = new { @class = "form-control" }, })

4

यहाँ MVC 5.1 EditorFor में HTML विशेषताओं के लिए VB.Net कोड सिंटैक्स है

@Html.EditorFor(Function(x) x.myStringProp, New With {.htmlAttributes = New With {.class = "myCssClass", .maxlength="30"}}))

3

सिर्फ उपयोग क्यों नहीं

@Html.DisplayFor(model => model.Control.PeriodType)

30
एक कारण यह है कि DisplayFor एक इनपुट प्रदान नहीं करता है, इसलिए मूल्य पोस्टबैक पर खो जाता है।
प्रोफ।

2
एक अन्य कारण विशिष्ट परिदृश्य है जहां संपादक वर्तमान में-लेकिन-हमेशा-लॉक नहीं है, और आप संवाद करना चाहते हैं कि डेटा संभावित रूप से संपादन योग्य है - अभी नहीं।
मीर

2

यदि आप मेटाडेटा का उपयोग नहीं करना चाहते हैं, तो आप [UIHint("PeriodType")]संपत्ति को सजाने के लिए एक विशेषता का उपयोग कर सकते हैं या यदि इसका जटिल प्रकार आपको कुछ भी सजाने की ज़रूरत नहीं है। EditorFor तब EditorTemplates फ़ोल्डर में एक PeriodType.aspx या ascx फ़ाइल की तलाश करेगा और इसके बजाय उसका उपयोग करेगा।


धन्यवाद, मैं यह करना समाप्त कर सकता हूं कि यदि मेरे संपादक टेम्पलेट में कुछ अन्य क्षेत्रों के लिए केवल आवश्यक है तो
टाइपो जॉनसन

हालांकि मैंने कहा था कि आप मॉडल को नहीं बदल सकते (आपका कोड नहीं), इसलिए UIHint के साथ सीधे सजावट एक विकल्प नहीं होगा।
डैरेल ली

2

मैं आज एक चेकबॉक्स के लिए उसी मुद्दे के साथ कुश्ती कर रहा हूं जो एक अशक्त बूल को बांधता है, और जब से मैं अपना मॉडल नहीं बदल सकता (मेरा कोड नहीं) मुझे इसे संभालने का एक बेहतर तरीका आना था। यह थोड़ा क्रूर बल है, लेकिन मेरे द्वारा सामना किए जाने वाले 99% मामलों में काम करना चाहिए। आपको स्पष्ट रूप से प्रत्येक इनपुट प्रकार के लिए वैध विशेषताओं की कुछ मैन्युअल आबादी करनी होगी, लेकिन मुझे लगता है कि मैंने उन सभी को चेकबॉक्स के लिए प्राप्त कर लिया है।

मेरे Boolean.cshtml संपादक टेम्पलेट में:

@model bool?

@{
    var attribs = new Dictionary<string, object>();
    var validAttribs = new string[] {"style", "class", "checked", "@class",
        "classname","id", "required", "value", "disabled", "readonly", 
        "accesskey", "lang", "tabindex", "title", "onblur", "onfocus", 
        "onclick", "onchange", "ondblclick", "onmousedown", "onmousemove", 
        "onmouseout", "onmouseover", "onmouseup", "onselect"};
    foreach (var item in ViewData) 
    {
        if (item.Key.ToLower().IndexOf("data_") == 0 || item.Key.ToLower().IndexOf("aria_") == 0) 
        {
            attribs.Add(item.Key.Replace('_', '-'), item.Value);
        } 
        else 
        {
            if (validAttribs.Contains(item.Key.ToLower()))
            {
                attribs.Add(item.Key, item.Value);
            }
        }
    }
}

@Html.CheckBox("", Model.GetValueOrDefault(), attribs)

मैंने अपने पृष्ठ के शीर्ष पर उन ब्लॉकों में से एक को जोड़ा Dictionary<string,string> attribs = new Dictionary<string,string>();और बनाया । तब मैंने अपने पेज पर किया था और यह मुझे एक त्रुटि देता है: "'System.Web.Mvc.HtmlHelper <MyProject.Models.MyObject>' में 'चेकबॉक्स' के लिए परिभाषा नहीं है और सबसे अच्छा विस्तार विधि" अधिभार "है। Mvc.InputExtensions.CheckBox (System.Web.Mvc.HtmlHelper, string.bool, object) 'में कुछ अमान्य तर्क हैं "। attribs.Add("tabindex","16");@( )@Html.CheckBox("IsActive", Model.IsActive.HasValue ? Model.IsActive : false, attribs)
vapcguy

2

आप अभी भी EditorFor का उपयोग कर सकते हैं। बस ViewData के रूप में शैली / जो भी HTML विशेषता से गुजारें।

@Html.EditorFor(model => model.YourProperty, new { style = "Width:50px" })

क्योंकि EditorFor रेंडर करने के लिए टेम्प्लेट का उपयोग करता है, आप अपनी संपत्ति के लिए डिफ़ॉल्ट टेम्प्लेट को ओवरराइड कर सकते हैं और स्टाइल विशेषता को ViewData के रूप में पास कर सकते हैं।

तो आपका EditorTemplate निम्नलिखित चाहेगा:

@inherits System.Web.Mvc.WebViewPage<object>

@Html.TextBoxFor(m => m, new { @class = "text ui-widget-content", style=ViewData["style"] })

1
Html.TextBoxFor(model => model.Control.PeriodType, 
    new { @class="text-box single-line"})

आप इस तरह का उपयोग कर सकते हैं; के साथ एक ही उत्पादन Html.EditorFor, और आप अपने HTML विशेषताओं को जोड़ सकते हैं


सिवाय TextBoxForध्यान न दी किसी भी प्रकार DisplayFormatआप लागू करने का प्रयास किया जा सकता है।
एरिक के

1

बस दृश्य / साझा / EditorTemplates / MyTypeEditor.vbhtml में टाइप के लिए अपना स्वयं का टेम्पलेट बनाएं

@ModelType MyType

@ModelType MyType
@Code
    Dim name As String = ViewData("ControlId")
    If String.IsNullOrEmpty(name) Then
        name = "MyTypeEditor"
    End If
End Code

' Mark-up for MyType Editor
@Html.TextBox(name, Model, New With {.style = "width:65px;background-color:yellow"})

मॉडल संपत्ति के साथ अपने विचार से संपादक को आमंत्रित करें:

@Html.EditorFor(Function(m) m.MyTypeProperty, "MyTypeEditor", New {.ControlId = "uniqueId"})

VB सिंटैक्स को क्षमा करें। बस यही हम रोल करते हैं।


1

मेरे मामले में मैं एक HTML5 नंबर इनपुट एडिटर टेम्पलेट बनाने की कोशिश कर रहा था जो अतिरिक्त विशेषताओं को प्राप्त कर सके। अपने स्वयं के एचटीएमएल हेल्पर को लिखने के लिए एक neater दृष्टिकोण होगा, लेकिन चूंकि मेरे पास पहले से ही मेरा .ascx टेम्पलेट था, इसलिए मैं इस दृष्टिकोण के साथ गया:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<input id="<%= Regex.Replace(ViewData.TemplateInfo.GetFullHtmlFieldId(""), @"[\[\]]", "_") %>" name="<%= ViewData.TemplateInfo.HtmlFieldPrefix %>" type="number" value="<%= ViewData.TemplateInfo.FormattedModelValue %>"
<% if (ViewData["attributes"] != null)
   {
       Dictionary<string, string> attributes = (Dictionary<string, string>)ViewData["attributes"];
       foreach (string attributeName in attributes.Keys){%>
        <%= String.Format(" {0}=\"{1}\"", attributeName, attributes[attributeName])%>
       <% }
   } %> />

यह बदसूरत सा एक प्रकार का इनपुट बनाता है और कुंजी "विशेषताओं" के साथ एक ViewData शब्दकोश की तलाश करता है। यह गुण के रूप में अपनी कुंजी / मूल्य जोड़े को जोड़ने के माध्यम से पुनरावृति करेगा। ID विशेषता में Regex असंबंधित है और वहाँ है क्योंकि जब एक संग्रह में उपयोग किया जाता है, तो GetFullHtmlFieldId()वर्ग कोष्ठक युक्त एक आईडी देता है[] जो सामान्य रूप से अंडरस्कोर के रूप में बच जाएगा।

यह टेम्प्लेट तब इस तरह कहा जाता है:

Html.EditorFor(m => m.Quantity, "NumberField", new { attributes = new Dictionary<string, string>() { { "class", "txtQuantity" } } }

क्रिया, लेकिन यह काम करता है। आप शायद प्रॉपर्टी नामों का उपयोग करने के लिए टेम्पलेट में प्रतिबिंब का उपयोग कर सकते हैं जैसे कि एक शब्दकोश का उपयोग करने के बजाय विशेषता नाम।


1

ViewDataनियंत्रक में उपयोग कर स्थिति निर्धारित करें

ViewData["Modifiable"] = model.recProcessed;

फिर नियंत्रण की HTML विशेषता सेट करने के लिए संपादक टेम्पलेट में इस दृश्य का उपयोग करें

@Html.RadioButton(prefix, li.Value, li.Selected, @ViewData["Modifiable"].ToString().ToLower() == "true" ? (object)new  { @id = li.Value, @disabled = "disabled" } : new { @id = li.Value })

0

MVC 5.1 और उच्चतर समाधान (स्थानीय HtmlAttributes विलय करेगा और EditorTemplates में परिभाषित किया जाएगा):

साझा \ EditorTemplates \ String.cshtml:

@Html.TextBoxFor(model => model, new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark }.ToExpando().MergeHtmlAttributes(ViewData["htmlAttributes"].ToExpando()))

एक्सटेंशन:

public static IDictionary<string, object> MergeHtmlAttributes(this ExpandoObject source1, dynamic source2)
{
    Condition.Requires(source1, "source1").IsNotNull().IsLongerThan(0);

    IDictionary<string, object> result = source2 == null
        ? new Dictionary<string, object>()
        : (IDictionary<string, object>) source2;

    var dictionary1 = (IDictionary<string, object>) source1;

    string[] commonKeys = result.Keys.Where(dictionary1.ContainsKey).ToArray();
    foreach (var key in commonKeys)
    {
        result[key] = string.Format("{0} {1}", dictionary1[key], result[key]);
    }

    foreach (var item in dictionary1.Where(pair => !result.ContainsKey(pair.Key)))
    {
        result.Add(item);
    }

    return result;
}

public static ExpandoObject ToExpando(this object anonymousObject)
{
    IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(anonymousObject);
    IDictionary<string, object> expando = new ExpandoObject();
    foreach (var item in anonymousDictionary)
        expando.Add(item);
    return (ExpandoObject)expando;
}

public static bool HasProperty(this ExpandoObject expando, string key)
{
    return ((IDictionary<string, object>)expando).ContainsKey(key);
}

उपयोग:

@Html.EditorFor(m => m.PromotionalCode, new { htmlAttributes = new { ng_model = "roomCtrl.searchRoomModel().promoCode" }})

1
धन्यवाद, वह काम करता है। सभी डेटा_एक्सएक्सएक्स विशेषताओं को छोड़कर, जहां मुझे _ को प्रतिस्थापित करना था - जब कास्टिंग source1और source2जैसा कि IDictionary<string, object>। मैंने यह कार्य किया: private static IDictionary<string, object> ToHtmlAttributesDictionary(this IEnumerable<KeyValuePair<string, object>> dico) { return dico.ToDictionary(s => s.Key.Replace('_', '-'), s => s.Value); }
मेरियन मोनियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.