.NET MVC 3 रेजर एडिटर एक्सटेंशन के साथ Html5 प्लेसहोल्डर?


92

क्या @ Html.EditorFor का उपयोग करके Html5 प्लेसहोल्डर को लिखने का एक तरीका है , या मुझे सिर्फ TextBoxFor एक्सटेंशन का उपयोग करना चाहिए

@Html.TextBoxFor(model => model.Title, new { @placeholder = "Enter title here"})

या यह हमारे अपने कस्टम एक्सटेंशन को लिखने के लिए समझ में आता है जो शायद DataAnnotations ( इस के समान ) के माध्यम से 'विवरण' प्रदर्शन विशेषता का उपयोग कर सकते हैं ?

बेशक, फिर यही सवाल 'ऑटोफोकस' पर भी लागू होता है।

जवाबों:


68

कस्टम लिखने के लिए आप निम्नलिखित लेख पर एक नज़र डाल सकते हैं DataAnnotationsModelMetadataProvider

और यहां एक और, ASP.NET MVC 3ish तरीका है जो नए शुरू किए गए IMetadataAware इंटरफ़ेस को आगे बढ़ाता है।

इस इंटरफ़ेस को लागू करने वाली एक कस्टम विशेषता बनाकर शुरू करें:

public class PlaceHolderAttribute : Attribute, IMetadataAware
{
    private readonly string _placeholder;
    public PlaceHolderAttribute(string placeholder)
    {
        _placeholder = placeholder;
    }

    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues["placeholder"] = _placeholder;
    }
}

और फिर इसके साथ अपने मॉडल को सजाएं:

public class MyViewModel
{
    [PlaceHolder("Enter title here")]
    public string Title { get; set; }
}

अगला एक नियंत्रक परिभाषित करें:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }
}

एक संगत दृश्य:

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.Title)
    <input type="submit" value="OK" />
}

और अंत में संपादक टेम्पलेट ( ~/Views/Shared/EditorTemplates/string.cshtml):

@{
    var placeholder = string.Empty;
    if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("placeholder"))
    {
        placeholder = ViewData.ModelMetadata.AdditionalValues["placeholder"] as string;
    }
}
<span>
    @Html.Label(ViewData.ModelMetadata.PropertyName)
    @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { placeholder = placeholder })
</span>

IMetadataAware इंटरफ़ेस की जानकारी (और एक महान उदाहरण) के लिए धन्यवाद!
21

4
क्या यह अभी भी MVC3 के लिए मान्य है? मैंने MVC3 में एक नया [डिस्प्ले (प्रॉम्प्ट = "टाइप वॉटरमार्क यहाँ") देखा] लेकिन यह काम नहीं कर सका। कोई उपाय?
स्मार्ब्स

2
@smnbs आप सही हैं। Promptकाम करने का तरीका देखने के लिए मेरा जवाब देखें ।
डैनियल लियुजी जूल

6
वाह क्या एक प्लेसहोल्डर करने के लिए इतना काम? कुछ सरल होना चाहिए: S
krilovich

वहाँ है, कुछ जवाब bellow को देखो। पैक्स में एक अच्छा है।
20

121

डारिन दिमित्रोव के जवाब में स्मार्ब्स की टिप्पणी, Promptइस उद्देश्य के लिए मौजूद है, इसलिए कस्टम विशेषता बनाने की कोई आवश्यकता नहीं है । प्रलेखन से:

यूआई में संकेतों के लिए वॉटरमार्क सेट करने के लिए उपयोग किया जाने वाला मान हो जाता है या सेट किया जाता है।

इसका उपयोग करने के लिए, बस अपने विचार मॉडल की संपत्ति को इस तरह से सजाएं:

[Display(Prompt = "numbers only")]
public int Age { get; set; }

इस पाठ को तब आसानी से रखा गया है ModelMetadata.Watermark। बॉक्स से बाहर, MVC 3 में डिफ़ॉल्ट टेम्पलेट Watermarkसंपत्ति की उपेक्षा करता है, लेकिन इसे काम करना वास्तव में सरल है। MVC को इसे कैसे प्रस्तुत करना है, यह बताने के लिए आपको बस डिफ़ॉल्ट स्ट्रिंग टेम्पलेट को ट्विक करना होगा। बस String.cshtml संपादित करें, जैसे डारिन करता है, सिवाय इसके कि वॉटरमार्क प्राप्त करने के बजाय ModelMetadata.AdditionalValues, आप इसे सीधे से प्राप्त करते हैं ModelMetadata.Watermark:

~ / दृश्य / साझा / EditorTemplates / String.cshtml:

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = "text-box single-line", placeholder = ViewData.ModelMetadata.Watermark })

और वह यह है।

जैसा कि आप देख सकते हैं, सब कुछ बनाने की कुंजी placeholder = ViewData.ModelMetadata.Watermarkबिट है।

यदि आप मल्टी-लाइन टेक्स्टबॉक्स (टेक्स्टारस) के लिए वॉटरमार्किंग को सक्षम करना चाहते हैं, तो आप मल्टीलाइनटेक्स्ट.कैशटीएमएल के लिए भी ऐसा ही करें:

~ / दृश्य / साझा / EditorTemplates / MultilineText.cshtml:

@Html.TextArea("", ViewData.TemplateInfo.FormattedModelValue.ToString(), 0, 0, new { @class = "text-box multi-line", placeholder = ViewData.ModelMetadata.Watermark })

6
@ ब्रेट वास्तव में है। EditorFor () MVC 2 में पेश किया गया एक टेम्प्लेटेड हेल्पर है। पहली नज़र में यह टेक्स्टबॉक्स () के समान काम करने के लिए लग सकता है, लेकिन यह आपको अपने एचटीएमएल जेनरेट करने के तरीके को नियंत्रित करने की अनुमति देता है। मेरा उत्तर इस विशेषता पर आधारित है कि एमवीसी को "सिखाने" के लिए Promptविशेषता के साथ क्या करना है । इन टेम्पलेट्स के बारे में अधिक जानकारी के लिए, आप ब्रैड विल्सन द्वारा इस महान पोस्ट का उल्लेख कर सकते हैं: bradwilson.typepad.com/blog/2009/10/…
डैनियल

2
@ डोटनेटवाइज़ मुझे यकीन नहीं है कि आप ऐसा क्यों कहते हैं; DisplayAttribute(प्रॉम्प्ट सहित) के सभी स्ट्रिंग पैरामीटर स्थानीय हैं। आपको बस अपने एनोटेशन में रिसोर्स टाइप को निर्दिष्ट करने की आवश्यकता है [Display(ResourceType = typeof(PeopleResources), Prompt = "AgePrompt")]:। और बस। वॉटरमार्क पाठ अब संसाधन PeopleResource में प्रमुख आयु समूह से आता है ।
डेनियल लिउज़ी

1
यदि आप .resx संसाधनों का उपयोग नहीं कर रहे हैं, लेकिन i18N .po स्थानीयकरण प्रणाली?
अष्टपत्ती

3
@FrancisRodgers EditorTemplatesफ़ोल्डर डिफ़ॉल्ट रूप से नहीं है; आप बस अपने Views\Sharedफ़ोल्डर में बनाते हैं (या Views\{ControllerName}यदि आप चाहते हैं कि यह एक निश्चित नियंत्रक के लिए विशिष्ट हो)। फिर आप अपने .cshtml टेम्प्लेट को इस फ़ोल्डर के अंदर रखते हैं और आपको जाने के लिए अच्छा होना चाहिए।
डैनियल लियुज़ी

2
@RobertIvanc मैंने जवाब संपादित किया है और रैले बकनर द्वारा किए गए संपादन को वापस कर दिया है जो आपके और टेड की समस्याओं का कारण बनता है। धन्यवाद।
डैनियल लियुज़ी

22

मैं वास्तव में समय के प्लेसहोल्डर पाठ बहुमत के लिए प्रदर्शन नाम का उपयोग करना पसंद करता हूं। यहाँ DisplayName का उपयोग करने का एक उदाहरण दिया गया है:

  @Html.TextBoxFor(x => x.FirstName, true, null, new { @class = "form-control", placeholder = Html.DisplayNameFor(x => x.FirstName) })

1
वॉटरमार्क के लिए एक विशेष डेटा एनोटेशन प्रॉम्प्ट है। और DisplayName फ़ील्ड लेबल के लिए है। उन्हें मिलाना एक बुरा विचार है। सही कार्यों के लिए सही चीजों का उपयोग करें। मेरे उत्तर को देखो।
माइक एशवा

1
धन्यवाद, यही वह चीज है जिसकी मैं तलाश कर रहा था, सरल और उस बिंदु पर जब हम प्रदर्शन नाम प्राप्त कर सकते हैं तो अधिक कक्षाएं क्यों जोड़ें
saqibahmad

यह DisplayName द्वारा प्रदान किए गए पाठ से दोहरा-बच जाएगा - उदाहरण के लिए फ्रेंच जैसे लहजे वाली भाषाओं के लिए एक अच्छा समाधान नहीं।
14

3

मैंने इतनी सरल कक्षा लिखी है:

public static class WatermarkExtension
{
    public static MvcHtmlString WatermarkFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        var watermark = ModelMetadata.FromLambdaExpression(expression, html.ViewData).Watermark;
        var htmlEncoded = HttpUtility.HtmlEncode(watermark);
        return new MvcHtmlString(htmlEncoded);
    }
}

उपयोग के रूप में इस तरह:

@Html.TextBoxFor(model => model.AddressSuffix, new {placeholder = Html.WatermarkFor(model => model.AddressSuffix)})

और एक नजर में संपत्ति:

[Display(ResourceType = typeof (Resources), Name = "AddressSuffixLabel", Prompt = "AddressSuffixPlaceholder")]
public string AddressSuffix
{
    get { return _album.AddressSuffix; }
    set { _album.AddressSuffix = value; }
}

नोटिस प्रॉम्प्ट पैरामीटर। इस स्थिति में मैं स्थानीयकरण के लिए संसाधनों से तार का उपयोग करता हूं, लेकिन आप केवल स्ट्रिंग का उपयोग कर सकते हैं, बस संसाधन टाइप पैरामीटर से बचें।


बस DisplayNameFor विधि को विघटित किया और वॉटरमार्क के लिए एक एनालॉग बनाया।
माइक एशवा

नमस्ते, क्या आप अपनी विधि MvcHtmlString WatermarkFor () DisplayName विशेषता मान का उपयोग करने के लिए बदल सकते हैं यदि प्रदर्शन -> शीघ्र मान निर्दिष्ट नहीं है?
सास तानसेव

आप अपने वॉटरमार्कएक्स्टेंशन क्लास को कहाँ बचाते हैं ताकि इसका उपयोग तब किया जा सके जैसा कि आपने वर्णित किया है? Html.WatermarkFor (मॉडल => model.AddressSuffix)
क्रेग Gjerdingen

3

मैं संसाधन फ़ाइल के साथ इस तरह का उपयोग करता हूं (अब और प्रॉम्प्ट की आवश्यकता नहीं है!)

@Html.TextBoxFor(m => m.Name, new 
{
     @class = "form-control",
     placeholder = @Html.DisplayName(@Resource.PleaseTypeName),
     autofocus = "autofocus",
     required = "required"
})

1

यहां एक उपाय है जो मैंने उपरोक्त विचारों का उपयोग करके बनाया है जो टेक्स्टबॉक्स और पासवर्ड के लिए उपयोग किया जा सकता है:

public static class HtmlHelperEx
{
    public static MvcHtmlString TextBoxWithPlaceholderFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        return htmlHelper.TextBoxFor(expression, htmlAttributes.AddAttribute("placeholder", metadata.Watermark));

    }

    public static MvcHtmlString PasswordWithPlaceholderFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        return htmlHelper.PasswordFor(expression, htmlAttributes.AddAttribute("placeholder", metadata.Watermark));

    }
}

public static class HtmlAttributesHelper
{
    public static IDictionary<string, object> AddAttribute(this object htmlAttributes, string name, object value)
    {
        var dictionary = htmlAttributes == null ? new Dictionary<string, object>() : htmlAttributes.ToDictionary();
        if (!String.IsNullOrWhiteSpace(name) && value != null && !String.IsNullOrWhiteSpace(value.ToString()))
            dictionary.Add(name, value);
        return dictionary;
    }

    public static IDictionary<string, object> ToDictionary(this object obj)
    {
        return TypeDescriptor.GetProperties(obj)
            .Cast<PropertyDescriptor>()
            .ToDictionary(property => property.Name, property => property.GetValue(obj));
    }
}

0

मुझे लगता है कि एक कस्टम एडिटर बनाएं टेमप्लेट अच्छा समाधान नहीं है, बीज़ करें कि आपको विभिन्न मामलों के लिए कई संभावित टेंपलेट्स की देखभाल करने की आवश्यकता है: स्ट्रिंग्स, न्यूमर्स, कॉम्बोबॉक्स और इसी तरह। अन्य समाधान HtmlHelper के लिए कस्टम एक्सटेंशन है।

नमूना:

public class MyViewModel
{
    [PlaceHolder("Enter title here")]
    public string Title { get; set; }
}

Html सहायक एक्सटेंशन:

   public static MvcHtmlString BsEditorFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TValue>> expression, string htmlClass = "")
{
    var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var metadata = modelMetadata;

    var viewData = new
    {
        HtmlAttributes = new
            {
                @class = htmlClass,
                placeholder = metadata.Watermark,
            }
    };
    return htmlHelper.EditorFor(expression, viewData);

}

एक संगत दृश्य:

@Html.BsEditorFor(x => x.Title)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.