4

I have a form with a dropdownlist, two buttons, and two Listboxes inside an UpdatePanel. The Dropdownlist, and listboxes are all bound to SqlDatasources. The dropdownlist allows you to choose your department.

The first listbox shows a list of Jobs associated with what you've selected from the department.

The second listbox shows an inverse list of those items. (Jobs in the database that are not associated with your department)

When an item is removed from the 1st listbox, it should show up in the 2nd listbox. When an item is removed from the 2nd listbox, it should show up in the 1st listbox.

This functionality allows you to add and remove jobs from your department

The are two buttons on the page function as Add and Remove buttons. Everything is working except the Listboxes will not reliably update. The Data itself is updated in the database, and if I refresh (F5) it will show correctly.

<asp:ScriptManager ID="smgrDeptsJobs" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="uPanelDeptsJobs" runat="server">
    <ContentTemplate>
        <asp:DropDownList ID="ddlDepartments" runat="server" 
            DataSourceID="sqldsDepartments" DataTextField="Department" 
            DataValueField="DeptID" Width="150px" AutoPostBack="True">
        </asp:DropDownList>

        <asp:ListBox ID="lstJobsIn" runat="server" DataSourceID="sqldsJobsIn" 
            DataTextField="JobName" DataValueField="JobID" height="156px" 
            width="220px">
        </asp:ListBox>

        <asp:Button ID="btnAddJob" runat="server" Text="&lt;&lt;" Width="70px" 
            CausesValidation="False" />

        <asp:Button ID="btnRemoveJob" runat="server" Text="&gt;&gt;" Width="70px" 
            CausesValidation="False" />

        <asp:ListBox ID="lstJobsOut" runat="server" DataSourceID="sqldsJobsOut" 
            DataTextField="JobName" DataValueField="JobID" height="156px" 
            width="220px">
        </asp:ListBox>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="ddlDepartments" 
            EventName="SelectedIndexChanged" />
        <asp:AsyncPostBackTrigger ControlID="btnAddJob" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="btnRemoveJob" EventName="Click" />
    </Triggers>
</asp:UpdatePanel>

The code for the two button click events is below:

Protected Sub btnAddJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddJob.Click

    Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    Dim sqlCmdInsert As SqlCommand = sqlJobsDB.CreateCommand()

    sqlJobsDB.Open()
    sqlCmdInsert.CommandText = _
        "INSERT INTO tblDeptsJobs (DeptID, JobID) VALUES " + _
        "(@DeptID, @JobID)"

    ' Declare the data types for the parameters
    sqlCmdInsert.Parameters.Add("@DeptID", SqlDbType.TinyInt)
    sqlCmdInsert.Parameters.Add("@JobID", SqlDbType.TinyInt)

    ' Assign the parameters values from the form
    sqlCmdInsert.Parameters("@DeptID").Value = ddlDepartments.SelectedValue
    sqlCmdInsert.Parameters("@JobID").Value = lstJobsOut.SelectedValue

    ' Execute the insert Statement
    sqlCmdInsert.ExecuteNonQuery()

    sqlJobsDB.Close()

End Sub

Protected Sub btnRemoveJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRemoveJob.Click

    Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    Dim sqlCmdDelete As SqlCommand = sqlJobsDB.CreateCommand()

    sqlJobsDB.Open()
    sqlCmdDelete.CommandText = _
        "DELETE FROM tblDeptsJobs WHERE tblDeptsJobs.DeptID = @DeptID AND tblDeptsJobs.JobID = @JobID"

    ' Declare the data types for the parameters
    sqlCmdDelete.Parameters.Add("@DeptID", SqlDbType.TinyInt)
    sqlCmdDelete.Parameters.Add("@JobID", SqlDbType.TinyInt)

    ' Assign the parameters values from the form
    sqlCmdDelete.Parameters("@DeptID").Value = ddlDepartments.SelectedValue
    sqlCmdDelete.Parameters("@JobID").Value = lstJobsIn.SelectedValue

    ' Execute the insert Statement
    sqlCmdDelete.ExecuteNonQuery()

    sqlJobsDB.Close()

End Sub

It feels like when I add or remove a job, the listbox that I last selected an item in, is the one that doesn't update.

I also can't get the dropdownlist to update the listboxes without setting autopostback on the dropdownlist to True.

The ugly Band-Aid fix I've come up with is using the listbox.items.clear() method and then rebinding the data for each listbox.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Lucretius
  • 1,053
  • 1
  • 13
  • 26
  • Can you add the server side code for the async postbacks? – Becuzz Jul 29 '11 at 16:32
  • If you're not married to the UpdatePanel I'd suggest just doing it with javascript / jQuery and web methods. I've always had headaches with the ASP Update panels. – Dan Jul 29 '11 at 16:38
  • @Becuzz The server side handler for Async Postbacks is the ScriptManager from my understanding. – Lucretius Jul 29 '11 at 16:41
  • @Lucretius I mean the functions that get called on the server. For example, what function / code gets executed when I click on btnAddJob? btnAddJob_Click? (This is where I'm assuming you make the changes to your database.) Having that will be helpful. – Becuzz Jul 29 '11 at 17:39
  • @Becuzz I see, I'll add that now. One is an insert statement, one is a delete statement. Note: I haven't coded any exception handling yet, like if someone were to try and add the same record twice (simply by double clicking) it would break it. – Lucretius Jul 29 '11 at 17:54
  • I see that the list boxes are databound to SQL Data sources (I assume). Where are those located on your page? It doesn't look like they are in the update panel. – Becuzz Jul 29 '11 at 19:11
  • They're not in the update panel, they're at the bottom of the page. – Lucretius Jul 30 '11 at 02:43

2 Answers2

2

Basically what is happening is that you update your database but never rebind your controls. I'm not sure exactly what you will have to put into your click handlers to make this work (because I have never used the SQL datasource controls before), but it should look something like this:

Protected Sub btnAddJob_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddJob.Click

    Dim sqlJobsDB As New SqlConnection(ConfigurationManager.ConnectionStrings("JobsDB").ConnectionString)
    Dim sqlCmdInsert As SqlCommand = sqlJobsDB.CreateCommand()

    sqlJobsDB.Open()
    sqlCmdInsert.CommandText = _
        "INSERT INTO tblDeptsJobs (DeptID, JobID) VALUES " + _
        "(@DeptID, @JobID)"

    ' Declare the data types for the parameters
    sqlCmdInsert.Parameters.Add("@DeptID", SqlDbType.TinyInt)
    sqlCmdInsert.Parameters.Add("@JobID", SqlDbType.TinyInt)

    ' Assign the parameters values from the form
    sqlCmdInsert.Parameters("@DeptID").Value = ddlDepartments.SelectedValue
    sqlCmdInsert.Parameters("@JobID").Value = lstJobsOut.SelectedValue

    ' Execute the insert Statement
    sqlCmdInsert.ExecuteNonQuery()

    sqlJobsDB.Close()

    //may need to do explicit call to DB to get data here
    //after you have the data, rebind
    lstJobsIn.DataBind();
    lstJobsOut.DataBind();
End Sub

That's roughly what it will look like. I would be interested to see what exactly you do to solve your problem.

Becuzz
  • 6,846
  • 26
  • 39
  • This is what I ended up doing, (edited my first post). I don't know if it was necessary or not but I did a `.clear()` on both of those listboxes prior to the `.DataBind()` and they work correctly now. The listboxes probably only need the `.clear()` if you have the "amend databound items" property set to true. – Lucretius Aug 03 '11 at 19:35
1

Just set dropdownlist autopostback to true, remove all triggers and set ChildrenAsTriggers="true" on the updatepanel.

Yuriy Rozhovetskiy
  • 22,270
  • 4
  • 37
  • 68
  • In the screenshot, I've selected "Maintenance" from the departments dropdownlist. I've attempted to move a "Mixer" job from the listbox on the right, to the listbox on the left. It shows up on the left, but is not removed from the listbox on the right. http://i53.tinypic.com/35i4srb.png If I then manually refresh the page (F5) it is removed from the list on the right. – Lucretius Jul 29 '11 at 17:03
  • Can you put your DataSource controls into the same UpdatePanel? – Yuriy Rozhovetskiy Jul 30 '11 at 06:07
  • Tried it, didn't work. The data itself is changing in the database, so updating those won't help the listboxes update. – Lucretius Jul 31 '11 at 15:20