2011-09-24 10 views
34

मैं अपने html.dropdownlist पर एक HTML क्लास टैग जोड़ने के तरीके के बारे में उत्तर देख रहा हूं।एचटीएमएल में <option> के तहत एचटीएमएल क्लास टैग जोड़ना .DropDownList

<select id="category"> 
    <option value="1">One</option> 
    <option value="2">Two</option> 
</select> 
<select id="package"> 
    <option value="1" class="1">One - package1</option> 
    <option value="2" class="1">One - package2</option> 
    <option value="3" class="2">Two - package1</option> 
    <option value="4" class="2">Two - package2</option> 
</select> 

$("#series").chained("#mark"); 
+1

क्या है त्रुटि? –

उत्तर

2

पहली बात यह है कि मेरे दिमाग में आता है JQuery यहाँ है: यहाँ कोड

<%: Html.DropDownList("PackageId", new SelectList(ViewData["Packages"] as IEnumerable, "PackageId", "Name", Model.PackageId))%> 

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

$("#bla").find("option").addClass("poo"); 
+2

मैं ऐसा नहीं कर सकता। मुझे अपने जंजीर चयन के लिए मूल्य बदलने के लिए कक्षा की आवश्यकता है। – paul

+0

@paul ठीक है, लेकिन इसका मतलब यह नहीं है कि यह काम नहीं करेगा। उपरोक्त कोड को अपने आवश्यक JQuery कोड से पहले रखें, फिर कक्षाओं को आपको उनकी आवश्यकता से पहले सेट कर दिया जाएगा। – tugberk

+1

+1 जोड़ने के लिए +1 ... lol –

5

यह DropDownList सहायक कि ASP.NET MVC में बनाया गया है के साथ संभव नहीं है। नतीजतन यदि आपको ऐसा करने की ज़रूरत है तो आपको अपना खुद का सहायक लिखना होगा। आप ASP.NET MVC के स्रोत कोड पर एक नज़र डाल सकते हैं जो विकल्पों को उत्पन्न करने के लिए टैगबिल्डर का उपयोग करता है और आप अपने कस्टम कार्यान्वयन में किसी भी विशेषता को जोड़ सकते हैं। दृश्य में डेटासेट के माध्यम से मैन्युअल रूप से लूप करना और व्यक्तिगत विकल्प तत्व उत्पन्न करना एक और कम सुरुचिपूर्ण समाधान है।

+1

कोई विचार अगर यह ढांचे के नए संस्करण (5.2.3) में शामिल किया गया है? यह लंगड़ा है कि आपको बहुत आम उपयोग व्यवहार प्राप्त करने के लिए कस्टम कोड लिखना है :( –

47

मैंने ड्रॉपडाउनलिस्ट के लिए यह किया है, विस्तार विधि के लिए, ड्रॉपडाउनलिस्ट का उपयोग न करें, लेकिन आप शायद इसे स्वयं समझ सकते हैं। यह सामान ज्यादातर एमवीसी स्रोतों से प्रतिलिपि/पेस्ट है। आप स्रोत here पा सकते हैं।

public class ExtendedSelectListItem : SelectListItem 
{ 
    public object htmlAttributes { get; set; } 
} 

public static partial class HtmlHelperExtensions 
{ 
    public static MvcHtmlString ExtendedDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<ExtendedSelectListItem> selectList, string optionLabel, object htmlAttributes) 
    { 
     return SelectInternal(htmlHelper, optionLabel, ExpressionHelper.GetExpressionText(expression), selectList, false /* allowMultiple */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 
    } 

    private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<ExtendedSelectListItem> selectList, bool allowMultiple, IDictionary<string, object> htmlAttributes) 
    { 
     string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); 
     if (String.IsNullOrEmpty(fullName)) 
      throw new ArgumentException("No name"); 

     if (selectList == null) 
      throw new ArgumentException("No selectlist"); 

     object defaultValue = (allowMultiple) ? GetModelStateValue(htmlHelper, fullName, typeof(string[])) : GetModelStateValue(htmlHelper, fullName, typeof(string)); 

     // If we haven't already used ViewData to get the entire list of items then we need to 
     // use the ViewData-supplied value before using the parameter-supplied value. 
     if (defaultValue == null) 
      defaultValue = htmlHelper.ViewData.Eval(fullName); 

     if (defaultValue != null) 
     { 
      IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue }; 
      IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture); 
      HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase); 
      List<ExtendedSelectListItem> newSelectList = new List<ExtendedSelectListItem>(); 

      foreach (ExtendedSelectListItem item in selectList) 
      { 
       item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text); 
       newSelectList.Add(item); 
      } 
      selectList = newSelectList; 
     } 

     // Convert each ListItem to an <option> tag 
     StringBuilder listItemBuilder = new StringBuilder(); 

     // Make optionLabel the first item that gets rendered. 
     if (optionLabel != null) 
      listItemBuilder.Append(ListItemToOption(new ExtendedSelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false })); 

     foreach (ExtendedSelectListItem item in selectList) 
     { 
      listItemBuilder.Append(ListItemToOption(item)); 
     } 

     TagBuilder tagBuilder = new TagBuilder("select") 
     { 
      InnerHtml = listItemBuilder.ToString() 
     }; 
     tagBuilder.MergeAttributes(htmlAttributes); 
     tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */); 
     tagBuilder.GenerateId(fullName); 
     if (allowMultiple) 
      tagBuilder.MergeAttribute("multiple", "multiple"); 

     // If there are any errors for a named field, we add the css attribute. 
     ModelState modelState; 
     if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState)) 
     { 
      if (modelState.Errors.Count > 0) 
      { 
       tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); 
      } 
     } 

     tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name)); 

     return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal)); 
    } 

    internal static string ListItemToOption(ExtendedSelectListItem item) 
    { 
     TagBuilder builder = new TagBuilder("option") 
     { 
      InnerHtml = HttpUtility.HtmlEncode(item.Text) 
     }; 
     if (item.Value != null) 
     { 
      builder.Attributes["value"] = item.Value; 
     } 
     if (item.Selected) 
     { 
      builder.Attributes["selected"] = "selected"; 
     } 
     builder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(item.htmlAttributes)); 
     return builder.ToString(TagRenderMode.Normal); 
    } 
} 
+10

यह वास्तव में अच्छा था, इसके अलावा GetModelStateValue() विधि अनुपलब्ध है (अब?) आंतरिक है। यह इस प्रश्न से ढंका है: http: //stackoverflow.com/questions/6967148/not-able-to-access-getmodelstatevalue-in-custom-control-in-asp-net-mvc2 – Dann

+2

यहां सही पंक्ति है: 'ऑब्जेक्ट डिफ़ॉल्ट वैल्यू = (अनुमति दें एकाधिक)? htmlHelper.GetModelStateValue (fullName, typeof (string [])): htmlHelper.GetModelStateValue (fullName, typeof (string)); ' –

+0

मैं एक ही दृष्टिकोण ले रहा हूं ताकि मुझे HTML चयन सेट का" शीर्षक "विशेषता मिल सके। यह अनुमति देता है आप होवर पर अधिक जानकारी दिखाने के लिए (संभवतः मोबाइल में उपयोगी नहीं है) –

0

मैं एक आवरण कि बस एचटीएमएल को संशोधित करता है लिखा है:

public static MvcHtmlString DisableFirstItem(MvcHtmlString htmlString) 
    { 
     return new MvcHtmlString(
      htmlString.ToString() 
      .Replace("<option value=\"Unknown\">", 
        "<option disabled value=\"Unknown\">") 
     ); 
    } 

और उसके बाद मैं इस सहायक समारोह के साथ अपने DropDownListFor लिपटे:

 @Html.Raw(MyHtmlHelpers.DisableFirstItem(

      Html.DropDownListFor(m => m.Instrument, 
      new SelectList(ReflectionHelpers.GenerateEnumDictionary<OrderInstrument>(true), "Key", "Value", Model.Instrument), 
      new { @class = "form-control" }) 

     )) 

आप स्पष्ट रूप से सहायक समारोह अधिक कर सकता है यदि आप चाहते हैं तो परिष्कृत।

9

यहां @ जॉन-लैंडहियर के समाधान का एक छोटा सुधार संस्करण है।

हालात में सुधार हुआ: तय

  • DropDownList() विस्तार विधि

    • समस्या GetModelStateValue() के साथ जोड़ा
    • विनीत सत्यापन विशेषताओं रेंडर किया जाएगा जैसे वे चाहिए

      using System; 
      using System.Collections; 
      using System.Collections.Generic; 
      using System.Globalization; 
      using System.Linq; 
      using System.Linq.Expressions; 
      using System.Text; 
      using System.Web; 
      using System.Web.Mvc; 
      
      namespace App.Infrastructure.Helpers 
      { 
          public class ExtendedSelectListItem : SelectListItem 
          { 
           public object HtmlAttributes { get; set; } 
          } 
      
          public static class ExtendedSelectExtensions 
          { 
           internal static object GetModelStateValue(this HtmlHelper htmlHelper, string key, Type destinationType) 
           { 
            System.Web.Mvc.ModelState modelState; 
            if (htmlHelper.ViewData.ModelState.TryGetValue(key, out modelState)) 
            { 
             if (modelState.Value != null) 
             { 
              return modelState.Value.ConvertTo(destinationType, null /* culture */); 
             } 
            } 
            return null; 
           } 
      
           public static MvcHtmlString ExtendedDropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<ExtendedSelectListItem> selectList) 
           { 
            return ExtendedDropDownList(htmlHelper, name, selectList, (string)null, (IDictionary<string, object>)null); 
           } 
      
           public static MvcHtmlString ExtendedDropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<ExtendedSelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) 
           { 
            return ExtendedDropDownListHelper(htmlHelper, null, name, selectList, optionLabel, htmlAttributes); 
           } 
      
           public static MvcHtmlString ExtendedDropDownListHelper(this HtmlHelper htmlHelper, ModelMetadata metadata, string expression, IEnumerable<ExtendedSelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) 
           { 
            return SelectInternal(htmlHelper, metadata, optionLabel, expression, selectList, false, htmlAttributes); 
           } 
      
           public static MvcHtmlString ExtendedDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression, IEnumerable<ExtendedSelectListItem> selectList, 
            string optionLabel, object htmlAttributes) 
           { 
            if (expression == null) 
             throw new ArgumentNullException("expression"); 
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData); 
            return SelectInternal(htmlHelper, metadata, optionLabel, ExpressionHelper.GetExpressionText(expression), selectList, 
             false /* allowMultiple */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 
           } 
      
           private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata, string optionLabel, string name, 
            IEnumerable<ExtendedSelectListItem> selectList, bool allowMultiple, 
            IDictionary<string, object> htmlAttributes) 
           { 
            string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); 
            if (String.IsNullOrEmpty(fullName)) 
             throw new ArgumentException("No name"); 
      
            if (selectList == null) 
             throw new ArgumentException("No selectlist"); 
      
            object defaultValue = (allowMultiple) 
             ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) 
             : htmlHelper.GetModelStateValue(fullName, typeof(string)); 
      
            // If we haven't already used ViewData to get the entire list of items then we need to 
            // use the ViewData-supplied value before using the parameter-supplied value. 
            if (defaultValue == null) 
             defaultValue = htmlHelper.ViewData.Eval(fullName); 
      
            if (defaultValue != null) 
            { 
             IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue }; 
             IEnumerable<string> values = from object value in defaultValues 
                    select Convert.ToString(value, CultureInfo.CurrentCulture); 
             HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase); 
             List<ExtendedSelectListItem> newSelectList = new List<ExtendedSelectListItem>(); 
      
             foreach (ExtendedSelectListItem item in selectList) 
             { 
              item.Selected = (item.Value != null) 
               ? selectedValues.Contains(item.Value) 
               : selectedValues.Contains(item.Text); 
              newSelectList.Add(item); 
             } 
             selectList = newSelectList; 
            } 
      
            // Convert each ListItem to an <option> tag 
            StringBuilder listItemBuilder = new StringBuilder(); 
      
            // Make optionLabel the first item that gets rendered. 
            if (optionLabel != null) 
             listItemBuilder.Append(
              ListItemToOption(new ExtendedSelectListItem() 
              { 
               Text = optionLabel, 
               Value = String.Empty, 
               Selected = false 
              })); 
      
            foreach (ExtendedSelectListItem item in selectList) 
            { 
             listItemBuilder.Append(ListItemToOption(item)); 
            } 
      
            TagBuilder tagBuilder = new TagBuilder("select") 
            { 
             InnerHtml = listItemBuilder.ToString() 
            }; 
            tagBuilder.MergeAttributes(htmlAttributes); 
            tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */); 
            tagBuilder.GenerateId(fullName); 
            if (allowMultiple) 
             tagBuilder.MergeAttribute("multiple", "multiple"); 
      
            // If there are any errors for a named field, we add the css attribute. 
            System.Web.Mvc.ModelState modelState; 
            if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState)) 
            { 
             if (modelState.Errors.Count > 0) 
             { 
              tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); 
             } 
            } 
      
            tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(fullName, metadata)); 
      
            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal)); 
           } 
      
           internal static string ListItemToOption(ExtendedSelectListItem item) 
           { 
            TagBuilder builder = new TagBuilder("option") 
            { 
             InnerHtml = HttpUtility.HtmlEncode(item.Text) 
            }; 
            if (item.Value != null) 
            { 
             builder.Attributes["value"] = item.Value; 
            } 
            if (item.Selected) 
            { 
             builder.Attributes["selected"] = "selected"; 
            } 
            builder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(item.HtmlAttributes)); 
            return builder.ToString(TagRenderMode.Normal); 
           } 
      
          } 
      } 
      
  • +0

    ग्रेट की तरह देखना बहुत दिलचस्प है! मैंने vb.net में अनुवाद करने की कोशिश की है और एक चेतावनी है: 'वैरिएबल 'मॉडलस्टेट' को संदर्भ द्वारा पारित करने से पहले संदर्भ द्वारा पारित किया जाता है। एक शून्य संदर्भ अपवाद रनटाइम पर परिणाम हो सकता है। क्या इसका कोई प्रभाव पड़ता है? – roland

    संबंधित मुद्दे