azi
azi

Reputation: 1

To remove last selected item from hidden field listbox ASP.NET

I'm trying to make limitation in listbox so that user only can pick 5 item in listbox. Currently I got to remove last selected item in the listbox, but in the hiddenfield its not updated.

listbox name = ddl_tags hiddenfield name = ddl_tags_selected

eg: user choose : item1, item2, item3, item4, item5, item 6 after they select item6, that index of item6 is remove but in the hiddenfield it still contain the item 6.

    protected void ddl_tag_SelectedIndexChanged(object sender, EventArgs e)
    {
        int count = 0;
        int limit = 0;
        string lastSelectedIndex;
        string tagSelected = ddl_tags_selected.Value;
        tagSelected = string.Join(",", tagSelected.Split(',').Select(x => string.Format("{0}", x)).ToList());

        for (int i = 0; i < ddl_tags.Items.Count; i++)
        {
            if (ddl_tags.Items[i].Selected)
            {
                if (ViewState["CountLimit"] != null)
                {
                    count++;
                    ViewState["CountLimit"] = count;
                    limit = (int)ViewState["CountLimit"];
                }
                else
                {
                    count++;
                    ViewState["CountLimit"] = count;
                }
                if (limit > 5)
                {
                    ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "Swal.fire({position: 'center',type: 'error',title: 'Only 5 tags are allowed.',showConfirmButton: false,timer: 2750});", true);
                    //Get the last selected items when the items selected exceeds in 5
                    lastSelectedIndex = tagSelected;
                    //Unselect the 6th items selected
                    ddl_tags.Items[5].Selected = false;
                }
            }
        }
    }

`

<div class="form-group col-md-4" id="tagsDiv" runat="server"visible="false"><label for="Tags">Tags :</label>
<asp:ListBox ID="ddl_tags" runat="server" class="form-control" SelectionMode="Multiple" CssClass="pm form-control select2" Width="100%" Height="100%" AutoPostBack="true" OnSelectedIndexChanged="ddl_tag_SelectedIndexChanged"></asp:ListBox>
<asp:HiddenField ID="ddl_tags_selected" runat="server" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" InitialValue="" runat="server" Style="color: red;" ControlToValidate="ddl_tags" ErrorMessage="This field is required" ToolTip="This field is required" ValidationGroup="DeviationValidate"></asp:RequiredFieldValidator></div>

`

Upvotes: 0

Views: 147

Answers (1)

Albert D. Kallal
Albert D. Kallal

Reputation: 49159

You actually don't need a hidden field.

There is a "count" of the items, and there is a selected array. HOWEVER these collections are SORTED by id order, and as a result, you can't know what the last item selected was.

You could for example do this:

            <h2>Please select up to 5 cities</h2>
            <asp:ListBox ID="ListBox1" runat="server"
                    DataValueField="ID"
                    DataTextField="City" OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"
                Width="260px" Height="330px" 
                SelectionMode="Multiple" AutoPostBack="true" >  
            </asp:ListBox>

And then just build a list of items, say like this:

    List<int> MyIDList = new List<int>();
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
           LoadList();
            ViewState["MyIDList"] = MyIDList;
        }
        MyIDList = ViewState["MyIDList"] as List<int>;
    }

    void LoadList()
    {
        DataTable rstData = MyRst("SELECT ID, City FROM City ORDER BY City");
        ListBox1.DataSource = rstData;
        ListBox1.DataBind();
    }

    protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        // add any selected (using index ref) to list
        int i = 0;
        for (i=0;i < ListBox1.Items.Count;i++) {

            if (ListBox1.Items[i].Selected)
            {
                if (!MyIDList.Contains(i))
                    MyIDList.Add(i);
            }
            else
                if (MyIDList.Count > 0)
                    if (MyIDList.Contains(i))
                        MyIDList.Remove(i);
        }
        // check for count > 5
        if (MyIDList.Count > 5)
        {
            int r = MyIDList[MyIDList.Count - 1];
            ListBox1.Items[r].Selected = false;
            MyIDList.RemoveAt(MyIDList.Count - 1);
        }
    }
    public DataTable MyRst(string strSQL)
    {
        var rst = new DataTable();
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
            {
                cmdSQL.Connection.Open();
                // fill items table
                rst.Load(cmdSQL.ExecuteReader());
            }
        }
        return rst;
    }

So, if > 5, then we un-select the last one.

To be fair, I would try and write this code 100% client side.

Upvotes: 0

Related Questions