How to update asp:DropDownList items between user opening the DDL and the list rendering on the page?

24 Views Asked by At

I have a DropDownList (DDL) on an asp.net Component page for changing sub-components of said compoment's instance of Component page. The DDL is (together with other elements) in an UpdatePanel and DDL has AutoPostBack disabled since we do not push changes until "Submit" button is clicked on the bottom of the page, which triggers said UpdatePanel's update. The items for the DDL are fetched from DB on page load.

<asp:UpdatePanel runat="server">
    <ContentTemplate>
        <div runat="server" id="ComponentsDiv">
            <div runat="server" class="row">
                <div class="col-md-6">
                    <div class="form-group">
                        <asp:Label runat="server" AssociatedControlID="subcomponentDDL">subcomponent</asp:Label>
                        <asp:DropDownList runat="server" ID="subcomponentDDL" DataTextField="Name" DataValueField="subcomponentPK" CssClass="form-control SubmitEnabler"/>
                        <small class="form-text text-muted">
                            Description of subcomponent.
                        </small>
                    </div>
                </div>
                
                ... Other page elements ...

        </div>
    </ContentTemplate>
</asp:UpdatePanel>

However, if it so happens that DB get's updated after user loads said page, the page shows list of items that is no longer up to date, thereby allowing user to select and push item that might not be available anymore, or not show all available items at the moment.

I am trying to make the DDL update it's list of items when user opens the DDL but before it is rendered, in theory effectively making the DDL make DB query on each open event of the DDL.

There however lies the problem; I wasn't able to find any native way to detect such event or way to detect opening of the DDL, let alone triggering a function for DB query update.

I have experimented with custom javascript functions to implement such event detection, but the most I was able to achieve was OnFocus update, but that triggers (as name suggests) on basically any interaction with the DDL.

Does anyone here please have any suggestion or advice? I have spent many hours researching this but didn't find any relevant or similar question/debate to this.

1

There are 1 best solutions below

0
Albert D. Kallal On

Well, since the ddl is inside of a update panel, then why not use a auto-post back, and when user makes a selection, then you can check if the selection exists, and at the same time re-load the dll.

And since the dll is inside of a update panel, then no full page post back will have occurred, or appear to have occurred.

So you can at point of selecting the combo box check if the selection exists, and if it does not, then you can take action, not allow the seleciton, and re-load the ddl.

So, say this markup:

        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>

                <h3>Select Hotel</h3>
                <asp:DropDownList ID="cboHotels" runat="server"
                    DataValueField="ID"
                    DataTextField="HotelName"
                    AutoPostBack="true"
                    OnSelectedIndexChanged="cboHotels_SelectedIndexChanged"
                    >
                </asp:DropDownList>
                <br />
                <asp:Label ID="lblError" runat="server" Text="" ForeColor="Red"></asp:Label>

            </ContentTemplate>
        </asp:UpdatePanel>

And code behind can be this:

    protected void Page_Load(object sender, EventArgs e)
    {

        if (!IsPostBack)
            LoadData();
    }

    void LoadData()
    {
        String strSQL =
            @"SELECT ID, HotelName FROM tblHotelsA
            WHERE Active = 1
            ORDER BY HotelName";
        cboHotels.DataSource = General.MyRst(strSQL);
        cboHotels.DataBind();
        cboHotels.Items.Insert(0, new ListItem("Please Select Hotel", ""));

    }

    protected void cboHotels_SelectedIndexChanged(object sender, EventArgs e)
    {

        int HotelPK  = 0;

        if (cboHotels.SelectedIndex > 0)
        {
            HotelPK = int.Parse(cboHotels.SelectedItem.Value);

            // make sure this selection exists
            string strSQL =
                @"SELECT ID, HotelName FROM tblHotelsA 
                WHERE ID = @ID AND Active = 1";

            SqlCommand cmdSQL = new SqlCommand(strSQL);
            cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = HotelPK;
            DataTable dtCheck = General.MyRstP(cmdSQL);

            if (dtCheck.Rows.Count == 0)
            {
                // selection no longer exists, zero out HotelPK
                HotelPK = 0;
                cboHotels.Items.Clear();
                lblError.Text = "Selection no longer available, please select again";
            }
            else
            {
                lblError.Text = "";
            }
            LoadData();  // re-load and refresh cbo box
            if (HotelPK != 0)
            {
                // cbo was re-loaded, so set cbo to user selection,
                // along with any new items, and deleted items removed
                cboHotels.Text = HotelPK.ToString();
            }
        }
    }

So, if the user attempts to select an item in the list that does not exist?

Then they will get/see this effect:

So, I let the page load, and then I marked the one of the items as Active = false.

This occurs:

enter image description here

However, what happens if the user selects a valid value, goes for coffee, and then comes back and hits submit?

Well, that means your submit button will also have to check for a valid seleciton, and the code will be quite much the same as what I have in the SelectedIndexChanged event.

As noted, the other approach is to adopt a "web socket" and real time updates of the combo box. These so called "push" notificaitons are based on using a web socket. This is also how say a on-line "chat" system works, in that as each user types, then the web page is updated in real time. However, it can be quite a bit of work to setup a web socket, so most people adopt a "pre made" framework such as SignalR.

You can read about SignalR here:

https://dotnet.microsoft.com/en-us/apps/aspnet/signalr

However, I think that adopting SignalR for this type of issue is overkill, and a simple check of the ddl at selection time, and that of when you submit will cover such scenarios rather well anyway.