it-swarm.com.de

Wie kann ich Optionsgruppen in der ASP.NET-Dropdown-Liste hinzufügen?

Ich habe eine Anforderung zum Gruppieren der Dropdown-Listenoptionen in der ASP.NET-Dropdown-Serversteuerung. Haben Sie eine Idee, wie Sie das Problem angehen sollen? Ich bin neu bei ASP.NET.

My requirement.

29
Arun Chandran C

Schauen Sie sich diesen Artikel an, ich brauchte auch eine DropDown-Liste. . .

ASP.NET DropDownList mit Unterstützung für OptionGroup

Verwendungszweck : 

protected void Page_Load(object sender, EventArgs e) 
{

              ListItem item1 = new ListItem("Camel", "1");
              item1.Attributes["OptionGroup"] = "Mammals";

              ListItem item2 = new ListItem("Lion", "2");
              item2.Attributes["OptionGroup"] = "Mammals";

              ListItem item3 = new ListItem("Whale", "3");
              item3.Attributes["OptionGroup"] = "Mammals";

              ListItem item4 = new ListItem("Walrus", "4");
              item4.Attributes["OptionGroup"] = "Mammals";

              ListItem item5 = new ListItem("Velociraptor", "5");
              item5.Attributes["OptionGroup"] = "Dinosaurs";

              ListItem item6 = new ListItem("Allosaurus", "6");
              item6.Attributes["OptionGroup"] = "Dinosaurs";

              ListItem item7 = new ListItem("Triceratops", "7");
              item7.Attributes["OptionGroup"] = "Dinosaurs";

              ListItem item8 = new ListItem("Stegosaurus", "8");
              item8.Attributes["OptionGroup"] = "Dinosaurs";

              ListItem item9 = new ListItem("Tyrannosaurus", "9");
              item9.Attributes["OptionGroup"] = "Dinosaurs";


              ddlItems.Items.Add(item1);
              ddlItems.Items.Add(item2);
              ddlItems.Items.Add(item3);
              ddlItems.Items.Add(item4);
              ddlItems.Items.Add(item5);
              ddlItems.Items.Add(item6);
              ddlItems.Items.Add(item7);
              ddlItems.Items.Add(item8);
              ddlItems.Items.Add(item9);

          }
36
PaRiMaL RaJ

Ich mag diese clientseitige Lösung wirklich (keine benutzerdefinierte DropDownList, sondern jQuery)

Backend

private void _addSelectItem(DropDownList list, string title, string value, string group = null) {
   ListItem item = new ListItem(title, value);
   if (!String.IsNullOrEmpty(group))
   {
       item.Attributes["data-category"] = group;
   }
   list.Items.Add(item);
}

...
_addSelectItem(dropDown, "Option 1", "1");
_addSelectItem(dropDown, "Option 2", "2", "Category");
_addSelectItem(dropDown, "Option 3", "3", "Category");
...

Klient

var groups = {};
$("select option[data-category]").each(function () {
     groups[$.trim($(this).attr("data-category"))] = true;
});
$.each(groups, function (c) {
     $("select option[data-category='"+c+"']").wrapAll('<optgroup label="' + c + '">');
});
34
mhu

Dies ist alt, aber da ich kürzlich die akzeptierte Antwort verwendet hatte, wollte ich meine Erfahrungen damit teilen. Es liefert zwar das richtige Markup, aber es verursachte Probleme für mich. Insbesondere wenn ich versuchte, ein Formular mit einer Dropdown-Liste zu senden, würde ich den gefürchteten Fehler "Ungültiges Postback- oder Rückrufargument" erhalten. Nachdem ich wie ein Verrückter gegoogelt habe, bin ich auf diesen Artikel gestoßen, der dann auf diesen Blogbeitrag verweist . Der Code, den ich am Ende verwendet habe, war folgender:

    public class DropDownListAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter {
    protected override void RenderContents(HtmlTextWriter writer) {

        var dropDownList = (DropDownList)Control;
        var items = dropDownList.Items;

        var groups = (from p in items.OfType<ListItem>()
                      group p by p.Attributes["Group"] into g
                      select new { Label = g.Key, Items = g.ToList() });

        foreach (var group in groups)
        {
            if (!String.IsNullOrEmpty(group.Label))
            {
                writer.WriteBeginTag("optgroup");
                writer.WriteAttribute("label", group.Label);
                writer.Write(">");
            }

            var count = group.Items.Count();
            if (count > 0)
            {
                var flag = false;
                for (var i = 0; i < count; i++)
                {
                    var item = group.Items[i];

                    writer.WriteBeginTag("option");
                    if (item.Selected)
                    {
                        if (flag)
                        {
                            throw new HttpException("Multiple selected items not allowed");
                        }
                        flag = true;

                        writer.WriteAttribute("selected", "selected");
                    }

                    if (!item.Enabled)
                    {
                        writer.WriteAttribute("disabled", "true");
                    }

                    writer.WriteAttribute("value", item.Value, true);

                    if (Page != null)
                    {
                        Page.ClientScript.RegisterForEventValidation(dropDownList.UniqueID, item.Value);
                    }
                    writer.Write('>');
                    HttpUtility.HtmlEncode(item.Text, writer);
                    writer.WriteEndTag("option");
                    writer.WriteLine();
                }
            }
            if (!String.IsNullOrEmpty(group.Label))
            {
                writer.WriteEndTag("optgroup");
            }
        }
    }
}

Die hier verwendeten Listenelemente werden auf der Gestaltungsseite und nicht wie in der Code-Behind-Seite erstellt:

<asp:ListItem Value="Apple" Text="Apple" Group="Fruit"></asp:ListItem>
<asp:ListItem Value="banana" Text="Banana" Group="Fruit"></asp:ListItem>
<asp:ListItem Value="asparagus" Text="Asparagus" Group="Vegetable"></asp:ListItem>
<asp:ListItem Value="eggs" Text="Eggs" Group="Dairy"></asp:ListItem>

Dies erzeugte den gleichen Markup wie die akzeptierte Antwort hier, aber dies gab mir nicht den Postback-Fehler. Ich hoffe, das erspart jemandem etwas Leid.

5
Doug F

1) Fügen Sie die Dropdownlisten-Adapterklasse von here zu Ihrem Projekt hinzu

2) Fügen Sie Ihrem Projekt den Ordner App_Browsers hinzu (klicken Sie mit der rechten Maustaste auf Projekt => Hinzufügen => ASP.NET-Ordner hinzufügen => App_Browsers).

3) Fügen Sie eine Browser-Datei in die App_Browsers-Seite ein und fügen Sie den folgenden Code in den Browser-Tag ein.

<browser refID="WebKit"> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.DropDownList" adapterType="YourAdapterClasse'sNameSPace.DropDownListAdapter" /> </controlAdapters> </browser>

refId = WebKit unterstützt Chrome- und Safari-Browser

4) Dann können Sie Ihrer Dropdown-Liste Elemente hinzufügen ListItem item1 = neues ListItem ("Smith Street", "1"); item1.Attributes ["OptionGroup"] = "Darwin";

            ListItem item2 = new ListItem("Mitchel Street", "1");
            item2.Attributes["OptionGroup"] = "Darwin";

            ListItem item3 = new ListItem("Hunter Street", "2");
            item3.Attributes["OptionGroup"] = "Sydney";

            ListItem item4 = new ListItem("BroadwaY", "4");
            item4.Attributes["OptionGroup"] = "Sydney";

            venuedropdown.Items.Add(item1);
            venuedropdown.Items.Add(item2);
            venuedropdown.Items.Add(item3);
            venuedropdown.Items.Add(item4);
2
Hrishikesh T T
----- in .cs  -----

List<SelectListItem> sl = new List<SelectListItem>();

sl.Add(new SelectListItem() { Text = "My text", Value = "1", Group = new SelectListGroup() { Name = "First Group" } });

sl.Add(new SelectListItem() { Text = "My text 2", Value = "2", Group = new SelectListGroup() { Name = "First Group" } });

var sl1 = new SelectList(sl,"Value","Text","Group.Name",-1);

ViewData["MyList"] = sl1;


----- in .cshtml    -----
Html.DropDownList("My List", ViewData["MyList"] as SelectList,
                        "-- No Preference --",
                        new {
                            @class = "ui-widget ui-corner-all square_corners searchPageDropdown"
                        }))
2
Nathan Woodruff

Folgendes habe ich gemacht, nur mit jquery, ohne Änderungen auf der Serverseite:

/* Add Option Groups to Note Dropdown */
var $select = $('#<%= DropDownListIDHere.ClientID %>');
var optGroup;
$('#<%= DropDownListIDHere.ClientID %> option').each(function () {
    if ($(this).val() == '<') {
        /* Opener */
        optGroup = $('<optGroup>').attr('label', $(this).text());
    } else if ($(this).val() == '>') {
        /* Closer */
        $('</optGroup>').appendTo(optGroup);
        optGroup.appendTo($select);
        optGroup = null;
    } else {
        /* Normal Item */
        if (optGroup) {
            $('<option>' + $(this).text() + '</option>').attr('value', $(this).val()).appendTo(optGroup);
        } else {
            $('<option>' + $(this).text() + '</option>').attr('value', $(this).val()).appendTo($select);
        }
    }
    $(this).remove();
});

Dann fügen Sie bestimmte Elemente als Öffner und Schließer mit dem Wert <und> hinzu:

<asp:ListItem Text="Group 1" Value="<" />
<asp:ListItem Text="Thing 1" Value="1111" />
<asp:ListItem Text="Thing 2" Value="2222" />
<asp:ListItem Text="Thing 3" Value="3333" />
<asp:ListItem Text="Group 1" Value=">" />

Super einfach, keine neuen Steuerelemente erforderlich, nur für die Auswahl, die Sie ändern möchten, und es muss nicht jedes Element in einer Optgroup sein.

1
ScottRFrost

Ich habe eine Client-Script-Lösung vorgezogen, um die Komplikationen beim Postback zu vermeiden, also habe ich es so gelöst. Hier verwende ich eine gewöhnliche HTML-Auswahl, um sie nur in der Funktion anzuzeigen, aber sie funktioniert auch mit DropDownList ASP:

<script>
function addOptGrp() {
  var t, p
  for (var i = 0; i < arguments.length; i=i+2) {
    t=arguments[i];
    p=arguments[i+1]-i/2;
    var scripts = document.getElementsByTagName('script');
/* On the next line scripts[scripts.length - 1] is the last script 
   in the page, which by definition will always be the calling script, 
   no matter how many such scripts you have */
    var ddl = scripts[scripts.length - 1].previousElementSibling;
    var og = document.createElement("optgroup");
    og.label = t;
    ddl.add(og,p);
    ddl.selectedIndex = ddl.selectedIndex // needed for UI;
  }
}
</script>

<select style="width:100px;">
  <option>Apple</option>
  <option>Pear</option>
  <option>Banana</option>
  <option>Orange</option>
</select>
<!-- here I just add the option groups in a script that immediately executes. 
     Notice that the script must follow immediately after the select (or DropDownList) -->
<script>addOptGrp(
  'Simple fruits', 0,
  'Very exotic fruits', 3
)</script>
<br><br>

<!-- Here comes another one -->
<select style="width:100px;">
  <option>Red</option>
  <option>Blue</option>
  <option>Yellow</option>
  <option>Green</option>
  <option>Magenta</option>
  <option>White</option>
</select>
<script>addOptGrp(
  'Some colors', 0,
  'Some more colors', 4
)</script>

Diese Funktion erfüllte die Bedürfnisse, die ich heute hatte. An einem anderen Tag muss möglicherweise eine modifizierte Version verwendet werden, z. B., bei der normale Optionen je nach Präfix in optgroups konvertiert werden.

0
Magnus

diese kleine Verbesserung auf der Client-Seite von mhus exzellenter Lösung funktioniert auch, wenn es mehr als einen Select-Tag gibt.

Bei seiner Version wird jedes Select-Tag tatsächlich mit einer Kopie jedes Options-Tags jedes Select-Tags gefüllt

(In diesem Beispiel ist .select2 die gemeinsame Klasse für alle select-Tags.) 

function filterUserGroups()
{

    var groups = {};
    $("select option[data-category]").each(function () {
        var sGroup = $.trim($(this).attr("data-category"));
        groups[sGroup] = true;
    });
    $.each(groups, function (c) {

        $(".select2").each(function () {

            $(this).find("option[data-category='" + c + "']").wrapAll('<optgroup label="' + c + '">');

        })

    });

}
0
Fabio Napodano

Ich verwende diese Methode, die ViewBag und ViewData vermeidet:

Modell anzeigen:

public class PageViewModel
{
    public int SelectedDropdownItem { get; set; }
    public IEnumerable<SelectListItem> DropdownList { get; set; }
}

Beispiel eines Entitätsmodells (für dieses Beispiel):

public class Users
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsAdministrator { get; set; }
    public bool IsDefault { get; set; }
}

Controller:

// Get list for the dropdown (this uses db values)
var userList = db.Users.ToList();

// Define the Groups
var group1 = new SelectListGroup { Name = "Administrators" };
var group2 = new SelectListGroup { Name = "Users" };

// Note - the -1 is needed at the end of this - pre-selected value is determined further down
// Note .OrderBy() determines the order in which the groups are displayed in the dropdown
var dropdownList = new SelectList(userList.Select(item => new SelectListItem
{
    Text = item.Name,
    Value = item.Id,
    // Assign the Group to the item by some appropriate selection method
    Group = item.IsAdministrator ? group1 : group2
}).OrderBy(a => a.Group.Name).ToList(), "Value", "Text", "Group.Name", -1);

// Assign values to ViewModel
var viewModel = new PageViewModel
{
    // Assign the pre-selected dropdown value by appropriate selction method (if needed)
    SelectedDropdownItem = userList.FirstOrDefault(a => a.IsDefault).Id,
    DropdownList =  dropdownList
};

Aussicht:

<!-- If needed, change 'null' to "Please select item" -->
@Html.DropDownListFor(a => a.SelectedDropdownItem, Model.DropdownList, null, new { @class = "some-class" })

Ich hoffe, dies hilft jemandem zu vermeiden, was mir passiert ist - viel zu viel Zeit, um eine stark typisierte Methode zu finden.

0
RickL

@ ScottRFrost's Antwort hat mir sehr gut gefallen. Aber es waren zwei Steine ​​hinter meiner Last zum Zeitpunkt des Schreibens:

  1. Die Gruppierungen in Postbacks in meinem UpdatePanel und wurden nicht beibehalten
  2. Der ausgewählte Wert wurde nicht für alle Postbacks beibehalten.

Hier sind meine Erweiterungen auf der Kundenseite seiner Antwort:

$(document).ready(function () {

    ddlOptionGrouping();

    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(ddlOptionGrouping);

    function ddlOptionGrouping() {
        /* Add Option Groups to asp:DropdownList */
        var $select = $('#<%= aspDropDownList.ClientID %>');
        var optGroup;
        $('#<%= aspDropDownList.ClientID %> option').each(function () {
            if ($(this).val() == '<') {
                /* Opener */
                optGroup = $('<optGroup>').attr('label', $(this).text());
            } else if ($(this).val() == '>') {
                /* Closer */
                $('</optGroup>').appendTo(optGroup);
                optGroup.appendTo($select);
                optGroup = null;
            } else {
                /* Normal Item */
                let $option = $('<option>' + $(this).text() + '</option>').attr('value', $(this).val());
                if (this.hasAttribute('selected')) {
                    $option.attr('selected', $(this).attr('selected'));
                }
                if (optGroup) {
                    $option.appendTo(optGroup);
                } else {
                    $option.appendTo($select);
                }
            }
            $(this).remove();
        });
    }
});
0
CAK2