繁体   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