Link to home
Start Free TrialLog in
Avatar of juststeve
juststeve

asked on

Checkbox state persisting thru postback when it shouldn't

As covered at question https://www.experts-exchange.com/questions/21782448/Initialize-Checkboxes-based-on-multi-DataTable-conditions.html

I have the following code that generates a table and a grid of checkboxes at runtime. The code correctly initializes checkbox on the 1st pass but persits changes after postback. Since it's generating everything at runtime and i haven't yet implemented 'save to db' code the post back should re-initialize everything back to original state. Here's th code....note that I've explicitly turned off viewstate for both the table and the checkboxes. The function's called at each Page_Load.

    Function CreateCheckBoxGrid()
        Dim GetTimePeriods = "select distinct datename(m,dateDue) + '-' + datename(day,dateDue) + '-' + datename(year,dateDue) , dateDue from RequiredModules order by dateDue"
        Dim myConnection As New SqlConnection(connStr)
        myConnection.Open()

        Dim myCommand As SqlCommand = New SqlCommand(GetTimePeriods, myConnection)

        Dim reader As SqlDataReader = myCommand.ExecuteReader()

        If reader.HasRows Then
            Do While reader.Read()
                lbGetDateDue.Items.Add(New ListItem(reader.GetString(0).ToString, reader.GetDateTime(1).ToString))
            Loop
        Else
            Console.WriteLine("No rows returned.")
        End If
        myConnection.Close()

        Dim ds As New DataSet

        Dim GetTitles = "select distinct strTitle, idTitle from FacilityTitles where FacilityID = 10159 order by strTitle;"
        GetTitles = GetTitles & "select ModuleName, moduleID from modules where moduleID > 0 order by ModuleID; "
        GetTitles = GetTitles & "select moduleID, idTitle, ReqModID from RequiredModules where dateDue = '" & lbGetDateDue.SelectedValue & "'  order by Moduleid "

        ds = SqlHelper.ExecuteDataset(connStr, CommandType.Text, GetTitles)

        ds.Tables(0).TableName = "Titles"
        ds.Tables(1).TableName = "Modules"
        ds.Tables(2).TableName = "FKey"

        'build table
        Dim tb As New HtmlTable
        tb.EnableViewState = False
        tb.CellSpacing = 1
        tb.Border = 1

        Dim tbr As New HtmlTableRow
        Dim tbc As New HtmlTableCell

        ' empty cell in the corner
        tbr.Cells.Add(tbc)

        'build first row as
        Dim myCurModuleID As Integer
        For Each myModule As DataRow In ds.Tables("Modules").Rows
            tbc = New HtmlTableCell
            Dim lbl As New Label
            lbl.Text = myModule(0)
            tbc.Controls.Add(lbl)
            tbr.Cells.Add(tbc)
        Next

        tb.Rows.Add(tbr) ' Add the row to table

        Dim intRow As Integer = 0
        For Each myTitle As DataRow In ds.Tables("Titles").Rows

            Dim myCurTitleID = myTitle(1)
            tbr = New HtmlTableRow
            tbc = New HtmlTableCell
            Dim lbl As New Label
            lbl.Text = myTitle(0)
            tbc.Controls.Add(lbl)
            tbr.Cells.Add(tbc)   ' Add Title A - Z to first cell of each row

            Dim i As Integer
            For i = 0 To ds.Tables("Modules").Rows.Count - 1
                myCurModuleID = ds.Tables("Modules").Rows(i).Item(1)
                ' each iteration adds row
                ' with an unchecked checkbox
                tbc = New HtmlTableCell
                Dim cb = New CheckBox
                cb.Checked = False
                cb.EnableViewState = False

                'iterate thru all records in FKeys table
                'to identify which rows have a idTitle field
                'that matches the current idTitle (myTitle(1))
                Dim blnChecked As Boolean = False
                For Each keyMapRow As DataRow In ds.Tables("FKey").Rows
                    If keyMapRow(1) = myCurTitleID And keyMapRow(0) = myCurModuleID Then
                        blnChecked = True
                        Exit For
                    End If
                Next

                cb.Checked = blnChecked
                tbc.Controls.Add(cb)
                tbr.Cells.Add(tbc)
            Next

            ' add this row to table
            tb.Rows.Add(tbr)

        Next

        Me.Panel1.Controls.Add(tb)
    End Function
Avatar of cnagaraj25
cnagaraj25

To persist the viewstate of dynamic webcontrols across the postback you need to create the control in onInit() procedure.

Please checkout http://aspnet.4guysfromrolla.com/articles/092904-1.aspx which explains how to maintain the viewstate across postback.

Raj
Avatar of juststeve

ASKER

I'm not trying to maintain state...i've disabled it in the above code in an attempt to make sure the controls are properly initialized.
Could you, temporarily, disable the checkboxes using myCheckBox.Enabled?

Your problem is that you need ViewState in order to keep the original checked/nonchecked state of the checkboxes (as they are not defined in the aspx markup). So you either need to reset the user's changes (rebuild the table each time), or better still - prevent the user being able to make any changes.

Does that work? Or did I misinterpret the question ?

Andy
By the way, you said "The function's called at each Page_Load". Are you only calling it for the first call, or on every postback (using IsPostBack)?
http://www.ttstrain.com/reports4_1/pagethree.aspx

It should be more clear now...the checked/unchecked state should change depending on which quarter is select in the dropdown box. The fact that no changes occur (and I'm registering hits to the db so I know the query is re-running) is strange but not as strange as the fact that unchecking a box that's currently checked and re-posting the page (fired off a dropdown state change) will leave that box _unchecked. Even tho as each checkbox is explicitly set to unchecked when it's instantiated. I've put a breakpoint on that line .... it fire both at initial page load and after postback.

This is probably an important clue...

Originally I had the dropdown list box construction inside the same function as is generating the checkbox table.  So it would re-generate each time the page posted back. I noticed that entries would accumulate - on the first postback there would be a duplicate set of quarters in the dropdown list...after another postback there were 2 duplicate sets - 12 lines instead of 4. i've since move it to a separate function that only fires if NotPostBack and things work correctly.

The dropdown is defined as:
<asp:dropdownlist id="lbGetDateDue" runat="server" AutoPostBack="true" Height="12"></asp:dropdownlist>

Refreshing the page will correctly re-initialize any unchecked boxes....the problem only exhibits on a postback and at this point, changing the dropdown is the only way to fire postback.


I'm still not to the point of working on saving user changes but that's the next task so, yes, users should be able to change values.
This is tough. I think you have the right event handler bound to the DropDownList's SelectedIndexChanged event because you say that the breakpoint in CreateCheckBoxGrid fires on postback. Have you stepped through the entire method with a watch on the table being created? Does it complete, or does it throw any errors? I'm (again) guessing it completes.

Its possible that you need to first clear the table, or even delete it, from the control hierarchy. Could you do me a favour and post:
-your aspx file
-remind me what your .NET version (1.1/2.0?) and development program (Visual Studio 2003/2005?) is.

I think you might want to try declaring the table in the aspx, if it isn't already there, as a server-side control. Then at the top of CreateCheckBoxGrid method, remove all the rows and columns before refilling it. ALternatively, when you create the table, set it's id:

    Dim tb As New HtmlTable
    tb.EnableViewState = False
    tb.CellSpacing = 1
    tb.Border = 1
    tb.Id = "checkTable1"

and then when you start each time on the postback, try:
If Me.FindControls("checkTable1") != nothing Then
Me.Controls.Remove(Me.FindControl("checkTable1"))
End If

That last one is a long shot, could you post your aspx and confirm that CreateCheckBoxGrid completes without any errors? I think it probably does as
ASKER CERTIFIED SOLUTION
Avatar of AGBrown
AGBrown
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
enabling/disabling viewstate does not affect controls like textbox,checkbox etc .. it always maintains the state .. u will explicity have to uncheck the checkbox ..

Rejo