簡體   English   中英

在一個列表框中選擇多個術語asp c#

[英]Select multiple terms within one listbox asp c#

我想從下拉列表中選擇一個術語,然后從同一個術語中選擇一個顏色或值。 例如,我想選擇“帳戶執行”,然后選擇“紅色”。 那里有jquery庫嗎? 可能嗎? 它也可以是下拉菜而不是顏色。

在此輸入圖像描述

這就是我填充下拉列表的方法c#

  DataSet dsRoles = obj.ds("Role");
  ddlRole.DataSource = dsRoles ;
  ddlRole.DataTextField = "Term";
  ddlRole.DataValueField = "Term";
  ddlRole.DataBind();
  ddlRole.Items.Insert(0, new ListItem("== Select 1 Term ==", ""));

天冬氨酸

<asp:ListBox ID="ddlRole" AutoPostBack="false" runat="server" SelectionMode="Multiple"> 

不幸的是,我不知道任何開箱即用的控件。 其中一個比較受歡迎的多選jquery庫是select2。 您可以覆蓋js事件,使其以您希望完成的方式運行。 我不確定如果沒有一些重構,這將是多么可擴展,但這里是如何在單個選擇上進行的。

鏈接到CDN for select2: https ://select2.org/getting-started/installation

首先設置基本選擇元素

<select id="tag" style="width: 50%" multiple="multiple"></select>

樂趣從js開始

我們需要跟蹤我們選擇的值

    var collectionArray = [];

接下來是輸出到我們的select2控件的初始數組,而id是位置的唯一標識符,簡單文本是您在選擇時要顯示的值,text是下拉列表中的html值

text元素有一個顏色塊,每個顏色塊都有一個on click元素,用於將id和顏色的數字表示傳遞給js函數。 這應該是進一步的,但保持簡單的演示

    var data = [
        { id: 0, simpleText:'Account Executive',  text: '<div style="display:block; min-height:30px; cursor:default;"><div style="float:left;">Account Executive</div><div style="float:right;"><table><tr><td class="tableSelect tableSelectRed" onclick="select2Override(0,0)"></td><td class="tableSelect tableSelectOrange" onclick="select2Override(0,1)"></td><td class="tableSelect tableSelectGreen"onclick="select2Override(0,2)"></td></tr></table></div></div>' },
        { id: 1,simpleText:'Account Management',  text: '<div style="display:block; min-height:30px; cursor:default;"><div style="float:left;">Account Management</div><div style="float:right;"><table><tr><td class="tableSelect tableSelectRed" onclick="select2Override(1,0)"></td><td class="tableSelect tableSelectOrange"onclick="select2Override(1,1)"></td><td class="tableSelect tableSelectGreen" onclick="select2Override(1,2)"></td></tr></table></div></div>' }];

接下來,我們使用數據數組初始化我們的select2對象。 我們需要覆蓋選擇和取消選擇的功能並自行處理

$("#tag").select2({
        data: data,
        //these options are telling it to use html from the text element. They are required or else it will just generate your html as text
        templateResult: function (d) { return $(d.text); },
        templateSelection: function (d) { return $(d.text); },
        tags: true

    }).on("select2:selecting", function (e) {
        // make sure we are on the list and not within input box
        //this is overriding the default selection event of select2, we will hadle that in our own onclick function based upon the color box they selected
        if (e.params.args.originalEvent.currentTarget.nodeName === 'LI') {
            e.preventDefault();
        }
    }
    ).on('select2:unselecting', function (e) {
        //we are injecting another method here when the object is unselected. We want to remove it from our master list to prevent duplicate inputs on our add function
        removeFromList(e.params.args.data.id);
    });

我們需要從選擇列表中手動處理刪除,並確保我們的主集合保持最新

    function removeFromList(id) {
        //actual remove from the selected list
        $('#tag option[value=' + id + ']').remove();
        //actual remove from the master collection to prevent dups
        collectionArray = collectionArray.filter(entry => entry.tagID != id)
    }

我們的主要推動功能是下一步。 我們首先需要檢查項目是否已經存在於我們的主要集合中(我們不想要重復)。 如果沒有,那么我們需要給它一個唯一的ID,以便以后在我們的主列表中引用。 我們將從當前選擇列表中找到最大值,以確保不重復,然后將新值注入我們的選擇列表,確保將其標記為已選擇並進入我們的主集合數組:

    function select2Override(id, color) {
        //our override function for when anyone selects one of the color boxes

        //first check if it is already in our master list, if so then dont add a dup, remove it!
        var doesExistsAlready = collectionArray.filter(entry => entry.type === id && entry.color === color);
        if (doesExistsAlready.length != 0) {
            for (var i = 0; i < doesExistsAlready.length; i++) {
                removeFromList(doesExistsAlready[i].tagID);
            }

        } else {
            //its not found in our master list 
            //we need to get a unique if to accompy this entry, fund the highest existing value in the current list and add 1
            var lastID = findMaxValue($('#tag')) + 1;

            //push it to our master list
            collectionArray.push({ "type": id, "color": color, "tagID": lastID });

            //get the selected value from our initial list so we can pull out the "simple text" to display
            var check = $.grep(data, function (obj) { return obj.id === id; })[0];

            //decorate our selection with a color depending on what they selected
            var colorDisplay;
            switch(color) {
              case 0:
                    colorDisplay = "red";
                break;
              case 1:
                colorDisplay =  "orange"
                break;
              case 2:
                    colorDisplay =  "green";
                break;
            }
            //prep our new select option with our new color, simple text and unique id and set to selected
            var newOption = new Option('<div style="color:' + colorDisplay + ';display:inline;">' + check.simpleText + '</div>', lastID, true, true);

            //append it to our list and call our change method so js reacts to the change
            $('#tag').append(newOption).trigger('change');
        }
    }

這是我們的JS函數,以確保我們從已存在的選擇列表項中獲得唯一的ID。

    //function to find the max value from our already existing list
    function findMaxValue(element) {
        var maxValue = undefined;
        $('option', element).each(function() {
            var val = $(this).attr('value');
            val = parseInt(val, 10);
            if (maxValue === undefined || maxValue < val) {
                maxValue = val;
            }
        });
        return maxValue;
    }

最后,我們需要覆蓋一些css,以便我們注入到列表中的項目不會顯示以供進一步選擇。 幸運的是,當選擇一個項目時,我們可以獲取select2用於默認行為的禁用屬性:

    .select2-container--default .select2-results__option[aria-selected=true] {
        display: none;
    }

此外,一些CSS使我在選擇元素上的黑客一起html看起來半可呈現:

    .tableSelect {
        min-width: 20px;
        height: 20px;
        border: 1px solid #fff;
        cursor: pointer;
        margin-bottom: 10px;
    }

    .tableSelectGreen {
        background-color: green;
    }

    .tableSelectRed {
        background-color: red;
    }

    .tableSelectOrange {
        background-color: orange;
    }

    blockMe{
        min-height:20px;
        min-width:20px;
    }

把它們放在一起:

  //this is where we will keep track of our selected values var collectionArray = []; //this is out initial array to feed into our select2 control //whereas id is the unique identifier of the position, simple text is the value you want to dispaly when selected, text is the html value in the dropdown //the text element has a your color blocks and each one has a on click element to pass the id and a numeric representation of the color into a js function. This blwon out further but keeping it simple for demo var data = [ { id: 0, simpleText:'Account Executive', text: '<div style="display:block; min-height:30px; cursor:default;"><div style="float:left;">Account Executive</div><div style="float:right;"><table><tr><td class="tableSelect tableSelectRed" onclick="select2Override(0,0)"></td><td class="tableSelect tableSelectOrange" onclick="select2Override(0,1)"></td><td class="tableSelect tableSelectGreen"onclick="select2Override(0,2)"></td></tr></table></div></div>' }, { id: 1,simpleText:'Account Management', text: '<div style="display:block; min-height:30px; cursor:default;"><div style="float:left;">Account Management</div><div style="float:right;"><table><tr><td class="tableSelect tableSelectRed" onclick="select2Override(1,0)"></td><td class="tableSelect tableSelectOrange"onclick="select2Override(1,1)"></td><td class="tableSelect tableSelectGreen" onclick="select2Override(1,2)"></td></tr></table></div></div>' }]; //here we initialize our select2 object with our data array. $("#tag").select2({ data: data, //these options are telling it to use html from the text element. They are required or else it will just generate your html as text templateResult: function (d) { return $(d.text); }, templateSelection: function (d) { return $(d.text); }, tags: true }).on("select2:selecting", function (e) { // make sure we are on the list and not within input box //this is overriding the default selection event of select2, we will hadle that in our own onclick function based upon the color box they selected if (e.params.args.originalEvent.currentTarget.nodeName === 'LI') { e.preventDefault(); } } ).on('select2:unselecting', function (e) { //we are injecting another method here when the object is unselected. We want to remove it from our master list to prevent duplicate inputs on our add function removeFromList(e.params.args.data.id); }); function removeFromList(id) { //actual remove from the selected list $('#tag option[value=' + id + ']').remove(); //actual remove from the master collection to prevent dups collectionArray = collectionArray.filter(entry => entry.tagID != id) } function select2Override(id, color) { //our override function for when anyone selects one of the color boxes //first check if it is already in our master list, if so then dont add a dup, remove it! var doesExistsAlready = collectionArray.filter(entry => entry.type === id && entry.color === color); if (doesExistsAlready.length != 0) { for (var i = 0; i < doesExistsAlready.length; i++) { removeFromList(doesExistsAlready[i].tagID); } } else { //its not found in our master list //we need to get a unique if to accompy this entry, fund the highest existing value in the current list and add 1 var lastID = findMaxValue($('#tag')) + 1; //push it to our master list collectionArray.push({ "type": id, "color": color, "tagID": lastID }); //get the selected value from our initial list so we can pull out the "simple text" to display var check = $.grep(data, function (obj) { return obj.id === id; })[0]; //decorate our selection with a color depending on what they selected var colorDisplay; switch(color) { case 0: colorDisplay = "red"; break; case 1: colorDisplay = "orange" break; case 2: colorDisplay = "green"; break; } //prep our new select option with our new color, simple text and unique id and set to selected var newOption = new Option('<div style="color:' + colorDisplay + ';display:inline;">' + check.simpleText + '</div>', lastID, true, true); //append it to our list and call our change method so js reacts to the change $('#tag').append(newOption).trigger('change'); } } //function to find the max value from our already existing list function findMaxValue(element) { var maxValue = undefined; $('option', element).each(function() { var val = $(this).attr('value'); val = parseInt(val, 10); if (maxValue === undefined || maxValue < val) { maxValue = val; } }); return maxValue; } 
  .tableSelect { min-width: 20px; height: 20px; border: 1px solid #fff; cursor: pointer; margin-bottom: 10px; } .tableSelectGreen { background-color: green; } .tableSelectRed { background-color: red; } .tableSelectOrange { background-color: orange; } blockMe{ min-height:20px; min-width:20px; } .select2-container--default .select2-results__option[aria-selected=true] { display: none; } 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.9/css/select2.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.9/js/select2.min.js"></script> <select id="tag" style="width: 50%" multiple="multiple"></select> 

據我所知,最好的解決方案之一是分組選項。 我已經像下面那樣實現了它,但我不是CSS,所以你應該添加一些類來改變位置和顏色(我認為這並不難)。

示例類

public class Role
{
    public Role(string name, int value)
    {
        Name = name;
        Value = value;
        SubRoles = new List<SubRole>();
    }

    public string Name { get; set; }
    public int Value { get; set; }
    public List<SubRole> SubRoles { get; set; }


    public enum SubRoleType
    {
        Red = 1,
        Orange = 2,
        Green = 3
    }
}

public class SubRole
{
    public string Name { get; set; }
    public int Value { get; set; }

    public SubRole(string name, int value)
    {
        Name = name;
        Value = value;
    }
}

代碼背后

    protected void Page_Load(object sender, EventArgs e)
    {
        List<Role> roles = new List<Role>();
        Role accountantRole = new Role("Accountant", 1);
        accountantRole.SubRoles.Add(new SubRole(SubRoleType.Red.ToString(), (int)SubRoleType.Red));
        accountantRole.SubRoles.Add(new SubRole(SubRoleType.Orange.ToString(), (int)SubRoleType.Green));
        accountantRole.SubRoles.Add(new SubRole(SubRoleType.Green.ToString(), (int)SubRoleType.Orange));
        roles.Add(accountantRole);

        Role managmentRole = new Role("Accountant Managment", 2);
        managmentRole.SubRoles.Add(new SubRole(SubRoleType.Red.ToString(), (int)SubRoleType.Red));
        managmentRole.SubRoles.Add(new SubRole(SubRoleType.Orange.ToString(), (int)SubRoleType.Green));
        managmentRole.SubRoles.Add(new SubRole(SubRoleType.Green.ToString(), (int)SubRoleType.Orange));
        roles.Add(managmentRole);

        foreach (var role in roles)
            AddRoleToDropDownList(ddlRole, role);          
    }

    private void AddRoleToDropDownList(DropDownList list, Role role)
    {
        foreach (var subRole in role.SubRoles)
        {
            ListItem item = new ListItem(subRole.Name, subRole.Name);
            item.Attributes["data-category"] = role.Name;
            list.Items.Add(item);
        }
    }    

標記

<asp:DropDownList runat="server" ID="ddlRole" />

<script>
    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 + '">');
    });
</script>

是的,有一些java和css魔術可以幫助你做到這一點。 MDBTelerik看一下這個

但是,你需要的並不難

  1. 你用自己的選擇填充的Div,只要你點擊它就可以使用任何html標簽。 單擊它將CSS更改為特定類並注冊單擊(並在列表/表單中取消單擊以便稍后回復)

  2. 將div放在應該是下拉的項目上並取消隱藏它

  3. 單擊“確定”,“取消”,“退出鍵”,“輸入鍵”時彈出/摻雜消失

  4. 躲在后面,你可以選擇處理變化

看看jquery,我會想到每個都有樣品

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM