Link to home
Start Free TrialLog in
Avatar of mainrotor
mainrotor

asked on

I need help dealing with a postback issue on a button click event in my ASP.Net app

Hi experts,
I have an ASP.net application with VB.Net codebehind.  In my app I use HTML radiobuttons in my GridView's TemplateField, and also a button control on the form.  Users can click on a radiobutton to select a row from my GridView.  Once the user has selected a row the user clicks on the button and the value in my GridView's Amount Column is placed in a variable to perform a calculation.   This works fine but on the postback my radio button gets deselected.  What can I do to keep my radio button from deselecting?  I have posted my code in this post.


Thanks in advance,
mrotor
HTML SOURCE CODE:
 
 <asp:TemplateField>
          <ItemTemplate>
                 <input id="Radio1" type="radio" name="myRadio"  value="<%#Eval("Amount")%>"/>
           </ItemTemplate>
</asp:TemplateField>
 
VB.NET Codebehind:
 
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim dblCost As Double = 0
       Dim dblTotal as Double = 0
 
       dblCost = CDbl(Request.Form("myRadio"))
       dblTotal = dblCost * .15 
      lblTotal.Text = dblTotal.ToString
End Sub

Open in new window

Avatar of Member_2_4913559
Member_2_4913559
Flag of United States of America image

One simple solution is to add viewstate to your input element.

<input id="Radio1" type="radio" name="myRadio"  value="<%#Eval("Amount")%>" runat="server" enableviewstate="true" />

Luckily I built a sample of your project yesterday so I was able to test it and it works fine.

:)
Avatar of mainrotor
mainrotor

ASKER

ddayx10
Thanks for the quick reply.  I added your code but it still didn't work.  The radio button still gets deselected.  Do I also have to make changes to my button control?

Thanks
mrotor
Because your radio buttons are simply html controls, their state is not maintained and will be lost on postback.

I think the easiest way to deal with this is to add some javascript to your page that goes and selects the right radiobutton based on the last posted back value. Adding the following code to your Button1_Click should do it


C#
 
ClientScript.RegisterStartupScript(this.GetType(), "RadioSelect", "var radios = document.getElementsByName('myRadio'); " + 
                                "var radioLength = radios.length; " +
                                "for(var i = 0; i < radioLength; i++) {" +
                        	"radios[i].checked = false;" +
		                "if(radios[i].value == '" + Request.Form["myRadio"] + "') " + 
			        "radios[i].checked = true;" +
		                "}", true);
 
VB.Net
 
ClientScript.RegisterStartupScript(Me.GetType(), "RadioSelect", "var radios = document.getElementsByName('myRadio'); " & _
                                "var radioLength = radios.length; " & _
                                "for(var i = 0; i < radioLength; i++) {" & _
                                "radios[i].checked = false;" & _
                                "if(radios[i].value == '" + Request.Form("myRadio") + "') " & _
                                "radios[i].checked = true;" & _
                                "}", True)

Open in new window

Solar flare,
Thank you for your response.  Your solution almost works.  After I click my button control it always has the bottom (i.e. last) radio button selected, not the radio button that was selected prior to the button click event.  What could be causing this?

mrotor
Dude that works. The only reason it wouldn't work is the likely culprit, you are rebinding to the gridview on your postback. The JavaScript solution can be made to work, but you will have to track the radiobuttons more carefully because after you rebind if the data that comes back is different, or lays out differently it will fail the way it is written. This will require a bit more complicated script than that.

I think I would adjust my thinking a bit. Add a column in your db for selected. Update the db after posting back, but before you re-bind**. Then set whether the input is selected or not during the row_databound process.

**Various ways you could update your data (AJAX, loop through the gridview pulling out the control and evaluating it's state), etc.

Maybe there's something I'm not seeing here. I gotta go for tonight anyway... good luck.
If you still don't have this figured out I'll take a look at it again tommorrow and see what can be done.
Ok so it's tommorrow somewhere...

I haven't seen a reply from you on your thoughts so I will start here:

After thinking about it, and re-checking, and looking at your code the first and easiest solution that comes to mind goes like this.

It looks like the button_click event is what you are using to cause the postback (since that's what you showed for the sample code).

I don't see any databinding happening there. Although I am convinced that databinding is the only thing that would stop viewstate from working for you here. That means the databinding is probably happening in the page_load (which always fires before the button_click event). You likely don't need to be re-binding the data every time you post back, and in this case it is killing you. It is very common to setup databinding in a subroutine and call that in page_load, but not every time. Only call it when you need to (like after an update/insert/delete etc).

So:

1) enable viewstate on your radiobutton
2) restrict your databinding in the page_load event
EX.
If not IsPostBack Then
   bindToGrid()
End If

If you require rebinding of the data every time you postback then you have a bit of work to do. If you do not require databinding on each postback (most applications dont) then this will fix you up.
ddayx10,
Thanks for your suggestions.  I will try them and post my results tomorrow.

mrotor
ddayx10,
on a previous response you mentioned you had built a sample of my project.  Maybe you can post the code so i can compare it to my code.  I'm including some code that shows how I'm binding my gridview.  I don't think I am doing anything that would cause the radiobuttons to be deselected.

Thanks,
mrotor
        Dim dtX As New DataTable()
        dtX.Columns.Add("Code")
        dtX.Columns.Add("Name")
        dtX.Columns.Add("Amount")
        GridViewPup.DataSource = Nothing
 
        For intRow = 0 To x
            row = tableX.NewRow()
            row("Code") = PUList(intRow).AgentCode.ToString
            row("Name") = PUList(intRow).AgentName.ToString
            Dim dblAmountPU As Double = PUList(intRow).AgentRate.ToString
            row("Amount") = dblAmountPU.ToString("N2")
            tableX.Rows.Add(row)
        Next
 
        Dim columnX As DataColumn
        For Each columnX In tableX.Columns
            Console.WriteLine(columnX.ColumnName)
        Next
 
        GridViewPup.DataSource = tableX
        GridViewPup.DataBind()

Open in new window

The sample I built is over there in your last post :)
https://www.experts-exchange.com/questions/24530824/I-need-help-with-a-Javascript-function.html

But I see you are building in VB so I'll update it for ya and post below.

I appreciate you posting the above code sample, but I don't know what context that runs in (page_load, subroutine, subroutine called from page_load)...

The key in your sample code that I'm trying to point out is here:
        GridViewPup.DataSource = tableX
        GridViewPup.DataBind()

Lets say that is running in page load (my personal guess). Now you call your click your button and call your button event after some radio buttons have been selected. The 1st thing that happens is page_load fires. The gridview is rebound. All items in the gridview are re-created. 2nd your button_click event fires and does what it does. Now the page is loaded back up. It remembers nothing about your previous gridview in viewstate because it was destroyed and rebuilt from scratch. When it was destroyed and re-built from scratch if any data changed, then it may build in a slightly different way and this is going to make tracking it with JavaScript a difficult task at best.

So in the sample note in the page_load I've built is so you can bind on every postback or you can switch it around and bind only once. If you toggle between these you will see that even though you used the button to cause the postback in one situation the radio buttons remember their previous state and in the other situation they dont.

You can use either the button or the dropdownlist to cause a postback for testing.
****SAMPLE ASPX*****
****I added some stuff when I was answering other questions,****
****but it doesnt affect what we are talking about****
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>MainRotor Sample</title>
	<script type="text/javascript">
	function unClear(rbElem)
	{
		var lbl1 = document.getElementById('lbl1');
		lbl1.innerHTML = rbElem.value;
	}
 
	</script>
	<style type="text/css">
		.rowClass:hover{background:#c0c0c0;}
	</style>
</head>
<body>
    <form id="form1" runat="server">
	<asp:GridView ID="GridView1" runat="server" 
		EditRowStyle-CssClass="rowClass" 
		RowStyle-CssClass="rowClass" 
		AlternatingRowStyle-CssClass="rowClass" 
		SelectedRowStyle-CssClass="rowClass">
		<Columns>
			<asp:TemplateField>
			<HeaderTemplate>Header Here</HeaderTemplate>
				<ItemTemplate>
					<div>
					<input id="Radio1" type="radio" onclick="unClear(this);"
						value=<%# Container.DataItem %> runat="server" enableviewstate="true" />
						
					<asp:DropDownList ID="ddl1" runat="server" AutoPostBack="true">
						<asp:ListItem Text="aa" Value="aa"></asp:ListItem>
						<asp:ListItem Text="bb" Value="bb"></asp:ListItem>
					</asp:DropDownList>
					</div>
				</ItemTemplate>
			</asp:TemplateField>
		</Columns>
	</asp:GridView>
	
	<span>Label1</span><asp:Label ID="lbl1" runat="server" />
	<asp:Button ID="btn1" runat="server" Text="ClickMe" />
    </form>
</body>
</html>
 
 
 
****CODE BEHIND****
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'Comment out option 1 or option 2 to see the effects they create
 
        'Option 1
        If Not IsPostBack Then
            bindGrid()
        End If
 
        'Option 2 (not usually a good idea)
        'bindGrid()
 
    End Sub
 
    Private Sub bindGrid()
        Dim dataSource As New List(Of String)
        dataSource.Add("Item1")
        dataSource.Add("Item2")
        dataSource.Add("Item3")
        dataSource.Add("Item4")
        GridView1.DataSource = dataSource
        GridView1.DataBind()
 
    End Sub

Open in new window

ddayx10-
Thanks for posting your code.  After comparing your code with mine, I figured out why my radiobuttons were being deselected after a button click event. In the Radio control this works:   value=<%# Container.DataItem %>
This doesn't work:   value="<%#Eval("Amount")%>"

but replacing my code with your code causes my buttons not to be grouped (i.e. I can select multiple radio buttons), even if I add the name="PickUpX" attribute.  Why??????  This is killing me.  Please help.

YOUR CODE:
<input id="Radio1" type="radio" name="PickUpX" value=<%# Container.DataItem %> runat="server" enableviewstate="true" />

MY CODE:
<input id="Radio1" type="radio" name="PickUpX" value="<%#Eval("Amount")%>"  runat="server" enableviewstate ="true"  />

Thanks in advance,
Ricardo Rubio
ASKER CERTIFIED SOLUTION
Avatar of Member_2_4913559
Member_2_4913559
Flag of United States of America 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
I typo'd this part:

***
When using a sql as datasource then any of the following will produce the same result:
(Insert your own column name)
<input id="Radio1" type="radio" value=<%# DataBinder.Eval(Container.DataItem,"testID") %> />
<input id="Radio2" type="radio" value=<%# Container.DataItem %> />
<input id="Radio3" type="radio" value=<%# Eval("testID") %> />
***

Should have been:
value=<%# Container.DataItem("testID") %> as the 2nd choice in that list.

So much for proof-reading before I submit :)
Last thing...gone for long weekend so I'm not abandoning you I'm just having more fun than this till next Tues!
Hi ddayx10,
Sorry it's taken me so long to reply to your posts, but a few people in my department have been on vacation an I've had to cover for them. Anyhow, I finally got a chance to try your code.
Your code works in the sense that the radio button doesn't deselect on a post back. The problem now is that the value in the gridview's 'Amount' column for the selected row doesn't evaluate to anything. The thing that is causing the are the double quotes (" ") around the value attribute. For example:

USING YOUR CODE (keeps radiobutton selected but the 'Amount' column doesn't evaluate to anything):

<input id="Radio1" type="radio" name="PickUpX" value=<%# Eval("Amount") %>  runat="server" enableviewstate ="true"  onclick="manageGrouping(this.value);" />

USING MY CODE (Doesn't keep radiobutton selected but the value in the 'Amount' column is grabbed):

<input id="Radio1" type="radio" name="PickUpX" value="<%#Eval("Amount")%>"  runat="server" enableviewstate ="true"  onclick="manageGrouping(this.value);" />

Once again, notice the difference in the use of the double quotes in the VALUE attribute.  Why would that affect this.

View the code snippet to see how I get the value in the 'Amount' column.

Thanks ddayx10 for all your help it is really appreciated.  What is causing this?

mrotor :-)







Dim dblPU as Double = 0
Dim dblTotal as Double = 0
dblPU = CDbl(Request.Form("PickUpX"))
 
dblTotal = dblPU * 1.35

Open in new window

...pretty confused over here!

I have the gridview databound to a sqldatareader. The table I am pulling from has a column named [amount]. Both of these fill the inputs value field identically for me:
value=<%# Eval("Amount") %>
value="<%#Eval("Amount")%>"

I don't think we are doing apples to apples here, and the difference is why you are getting a value with one and not the other although I don't know why.

...ah I hate that I accidentally pressed ENTER and it posted (sorry).
<<--Continued from above>>
The code you posted for the origin of "Amount":
******************************
Dim dblPU as Double = 0
Dim dblTotal as Double = 0
dblPU = CDbl(Request.Form("PickUpX"))
dblTotal = dblPU * 1.35
******************************

I'm having a real hard time putting that into meaningful context... when I try that code:
Dim dblPU As Double = 0
dblPU = CDbl(Request.Form("groupX")) 'mines groupX yours is PickUpX (same diff)

I always get 0 because Request.Form("groupX") evaluated to nothing. It isn't there.

So what do you mean by "the value in the amount column is grabbed" using your code? Are you saying that the gridview is not binding anything to the value of the input (radiobutton)? Are you saying that you manipulate something else with that value, and you can't get a value out of it anymore with that code sample? It seems like you might be saying that you have an OnSelectedIndexChanged server side event that is being detrimentally affected somehow?

In all of these scenarios I would think you need to be getting at the value differently than you are, but without the context of that code sample I can't advise. Show me if you can, try to explain more too.

I can tell you that when binding a gridview to table data that those eval statements work in a variety of ways I have tried. When you use your binding method, the JavaScript I wrote should always work, the only reason it wouldn't is if there is not a good value being attached so I am suspicious of what is happening when you bind it with your syntax. Run it with your syntax and take a look at the view source from the browser...see what the control looks like there (post it if you can).

I'll keep trying to help, but I think we have to re-connect on communication at this stage.



ddayx10 thank you for hanging tough with me.  You are an excellent programmer.
Your kind comments brought me back, and after looking at the code again I'm guessing that when you bind amount to the radiobutton that it is not a unique value...in other words in value=amount sometimes you have the same value for multiple radiobuttons....this would break my JavaScript code. If that turns out to be the case though I can probably fix it :)


<input id="Radio3" type="radio" name="groupX" value="<%#Eval("Amount")%>" runat="server" enableviewstate="true" onclick="manageGrouping(this);" />


function manageGrouping(elementSelected)
{
      var radios = document.getElementsByTagName('input');
      
      for(i=0;i<radios.length;i++)
      {
            if(radios[i].type == 'radio')
            {
                  if(radios[i] == elementSelected)
                  { radios[i].checked = true; }
                  else
                  { radios[i].checked = false; }
            }
      }
}
Ok I think I see you have moved on:

https://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q__24570729.html

You are using the old javascript in that new thread...might want to change to the new JavaScript I posted just above...

I'll leave ya to it through...fresh ideas are good. I wish you had given me as much of your code to see in this thread as you did in the new one though...would have made it easier.