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).ToStrin g, reader.GetDateTime(1).ToSt ring))
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(c onnStr, 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
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,
Dim reader As SqlDataReader = myCommand.ExecuteReader()
If reader.HasRows Then
Do While reader.Read()
lbGetDateDue.Items.Add(New
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
ds = SqlHelper.ExecuteDataset(c
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.
myCurModuleID = ds.Tables("Modules").Rows(
' 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
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
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)?
ASKER
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:dropdown list>
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.
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:dropdown
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("checkTabl e1") != nothing Then
Me.Controls.Remove(Me.Find Control("c heckTable1 "))
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
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("checkTabl
Me.Controls.Remove(Me.Find
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
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
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
Rejo
Please checkout http://aspnet.4guysfromrolla.com/articles/092904-1.aspx which explains how to maintain the viewstate across postback.
Raj