Updating ASP.NET label after button click, using UpdatePanel - asp.net

I'm trying to have two things happen when I click on a button in an ASP.NET page:
Change the text in an ASP:Label.
Disable the button.
I've done a lot of research on this, but I've had difficulties doing either.
For #1, I thought that this should work, but it doesn't:
<%# Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub BtnSubmit_Click(sender As Object, e As System.EventArgs)
Label1.Text = "Working..."
System.Threading.Thread.Sleep(5000)
Label1.Text = "Done."
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test Page</title>
</head>
<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager runat="server" />
<div>
<asp:ListBox runat="server" Height="100px" />
<br />
<asp:UpdatePanel runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="BtnSubmit" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Press the button" />
</ContentTemplate>
</asp:UpdatePanel>
<br />
<asp:Button runat="server" ID="BtnSubmit" OnClick="BtnSubmit_Click" Text="Submit Me!" />
</div>
</form>
</body>
</html>
The "Working..." message is never displayed.
As for #2, I added this to the button (I forget where I found it):
OnClientClick="this.disabled = true; this.value = 'Working...';"
UseSubmitBehavior="false"
That had the desired effect of disabling the button and changing its text (value), but it wasn't possible to change it back using Text and Enabled properties.

I just found a solution on msdn (http://msdn.microsoft.com/en-us/library/bb386518.aspx). Added some code and remove some unnecessary parts.
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void btnDoWork_Click(object sender, EventArgs e)
{
/// do something long lasting
System.Threading.Thread.Sleep(3000);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<script language="javascript" type="text/javascript">
<!--
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
var postBackElement;
function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id == 'btnDoWork') {
$get('btnDoWork').value = 'Working ...';
$get('btnDoWork').disabled = true;
}
}
function EndRequest(sender, args) {
if (postBackElement.id == 'btnDoWork') {
$get('btnDoWork').value = 'Done!';
$get('btnDoWork').disabled = false;
}
}
// -->
</script>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Hello World!"></asp:Label><br />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnDoWork" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="btnDoWork" runat="server" Text="Start!" OnClick="btnDoWork_Click" />
</div>
</form>
</body>
</html>
What you basically do, is you register some eventHandler for Initialize_ and End_Request - in those you disable and enable your button!
HTH

ASP will not flush the result to the browser while working even if you use an UpdatePanel. It will finish the jobb (including the sleep) before flushing.
You can use a UpdateProgress to show the "Working.." text.
<asp:UpdateProgress>
This will show its content while the UpdatePanel is working. Once the UpdatePanel is finished, the content will disappear.
What you need in you ClickEvent is:
Label1.Text = "Done."
btnSubmit.Enabled = false
This will show the Done text and disable the button. And tell the UpdateProgress to disappear.

The Working message is never displayed because you are executing the script on the server, which doesn't respond to the client until the method exits.
ASP.NET AJAX has a built in control for displaying messages like this while the UpdatePanel is waiting on the server.
Check out the UpdateProgress Control:
<asp:UpdateProgress runat="server" id="progress" ><ProgressTemplate>Working...</ProgressTemplate></asp:UpdateProgress>
You can disable the button by setting the Enabled property to false in your server-side method.
BtnSubmit.Enabled = false

#1: You will never see the message "Working" as you stopped the thread .... Every Message will be shown when your process has "ended".
#2: you coded clientSide to disable the button, there is no code to re-enable your button
hth

First off, "working" never appears because the final value of the label at the time of post-back is "Done." Think about what is happening here - you click the button which causes a post-back to the server. It processes the post-back which includes running the button click code, the result of which is then sent back to the browser. Your 'working' text never makes it back over the wire.
I am not clear on what you're trying to accomplish with the client-side code, but to do what you describe you're almsot there server-side:
Protected Sub BtnSubmit_Click(sender As Object, e As System.EventArgs)
Label1.Text = "Done."
btnSubmit.Enabled = false
End Sub
Also, but your button inside your update panel template tags so it participates in the ajax-postback.

Related

change text on button and enabled status after click button(asp.net)

I use ASP.NET to develop.
Here, I want the thing is that once I click button A (the text on the button A is "Start"), then the text on the button A will change to "processing...please wait" and button A will become not clickable. Then execute the stored procedure(the duration of stored procedure is 1 minute). After the stored procedure finishes, the text on the button A will change to "Start" and button A will become clickable.
I tried that before stored procedure, I added these codes:
ButtonA.Text = "processing...please wait";
ButtonA.Enabled = false;
And after stored procedure, I added these codes:
ButtonA.Text = "Start";
ButtonA.Enabled = true;
But the outcome is the text on the button A is not changed and button A is still clickable during the stored procedure is executing.
Can anyone tell me how to achieve what I want? Thanks.
Then I edit my aspx file to be below:
<asp:ScriptManager ID="MainScriptManager" runat="server"/>
<asp:UpdatePanel ID="pnlHelloWorld" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:Button ID="ButtonA" runat="server" OnClick="ButtonA_Click" Text="Start" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ButtonA" EventName="Click"/>
</Triggers>
</asp:UpdatePanel>
But the text of button still remains the same and the button is still clickable.
You can achieve your requirement by using Ajax. Using Ajax you can do partial page refresh.
Put ButtonA inside the UpdatePanel, and it should work as expected.
You can refer below sample code for reference.
webpage.aspx code
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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>Hello, world!</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="MainScriptManager" runat="server" />
<asp:UpdatePanel ID="pnlHelloWorld" runat="server">
<ContentTemplate>
<asp:Button runat="server" ID="ButtonA" OnClick="btnHelloWorld_Click" Text="Update label!" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
c# code
protected void btnHelloWorld_Click(object sender, EventArgs e)
{
//Before Procedure call
ButtonA.Text = "processing...please wait";
ButtonA.Enabled = false;
//Call Procedure
procedure ....
//After Prodedure call
ButtonA.Text = "Start";
ButtonA.Enabled = true;
}
Hope that helps, thanks.

Asp.net VB Webform. How to get li items from ul list at codebehind

i need help ;) i populate a ul with listitems from code behind trough Asp.net and htmlGenericControl.
The list items appear and these items are dropable and sortable into different uls trough jquery sortable and connectedSortable function. This works fine.
For example i have 3 lists. UnorderdLists(ul's) A, B and C.
List A is populated with a few items. Now i can drag and drop theses list items from list A to list B or C.
Now i need help how can i see or get (in/at codebehind) which item is in list B or C ?!
Info:
I dont use bulletlist because i think dropable/sortable would give me some trouble instead.
My ul's have added runat="server", do my li's have to had this aswell?
When I use a custom or not standard controls, I prefer to use hidden fields and store the data in a custom way (values with char separator for example).
You can populate via Javascript/Jquery your hidden fields at your specific events and then from codebehind you can read the hidden fields.
UPDATE with example
This is only one possiblity, but more simple probably is JQuery AJAX.
webform.aspx
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="webform.aspx.vb" Inherits="ajax_test.webform" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#send').click(function () {
$('#<%= HFTest.ClientID %>').val($('#theValue').val());
__doPostBack('<%= btn_force_async.ClientID %>','');
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args) {
// Fire before the AJAX request
}
function EndRequestHandler(sender, args) {
// Fire after the AJAX request
if ($('#<%=HFReturnMessage.ClientID %>').val() == 'ok') {
alert('ok!');
} else {
alert($('#<%=HFReturnMessage.ClientID %>').val());
}
}
</script>
<input id="theValue" type="text" value="ok" />
<input id="send" type="button" value="send value" />
<asp:UpdatePanel ID="UPDHiddenFields" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:HiddenField ID="HFTest" runat="server" />
<asp:HiddenField ID="HFReturnMessage" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btn_force_async" EventName="click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="btn_force_async" runat="server" style="display:none;"/>
</div>
</form>
</body>
</html>
webform.aspx.vb // The codebehind
Public Class webform
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then
If HFTest.Value = "ok" Then
HFTest.Value = ""
HFReturnMessage.Value = "ok"
Else
HFTest.Value = ""
HFReturnMessage.Value = "error, the HFTest is not ok ! "
End If
UPDHiddenFields.Update() 'Update hidden field panel on client side
End If
End Sub
End Class
Hope this help you.

Page_load fires twice for UpdatePanel refresh whilst having a jQuery bound change event on a drop down list

I've tried to wrap up my problem with a complete example below - the original problem is part of a jQuery plug-in that I'm writing to extend the behaviour of an ASP.NET ajax application I already have.
The aspx page below has one drop down list which is marked for auto post back. I've also bound a change event using jquery (which ultimately I will swap for a .live() event to maintain the binding after the update panel refresh.) The problem is, when the jQuery event is bound I see two ajax begin requests and page_loads fire but only one ddlTest_OnselectedIndexChanged event. One of the page loads is malformed too - the content-length states it's about 300 bytes long whilst the totalBytes is 0 and form data empty. This does not happen if I bind to the click event of a button.
Can someone explain why the erroneous page_load event is firing please??
<%# Page Language="C#" AutoEventWireup="true" %>
<%# Import Namespace="System.Diagnostics" %>
<!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">
<script runat="server">
private void Page_Load(object sender, EventArgs e)
{
Debug.WriteLine(Request.Headers["Content-Length"]);
Debug.WriteLine(Request.TotalBytes);
Debug.WriteLine(Request.Form.ToString());
Debugger.Break();
}
private void ddlTest_OnSelectedIndexChanged(object sender, EventArgs e)
{
Debugger.Break();
}
</script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandler);
$("#<%=ddlTest.ClientID%>").change(function() { alert('jQuery binding fired'); });
});
function beginRequestHandler() {
alert("Started ajax call");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="SciptManager" runat="server" />
<asp:UpdatePanel ID="updTest" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="ddlTest" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlTest_OnSelectedIndexChanged" >
<asp:ListItem>First</asp:ListItem>
<asp:ListItem>Second</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Update : I've narrowed the problem down even further. Firefox and Chrome both work as I would expect whilst IE is having a problem. I've also simplified the erroneous code to the example below. It's hard to believe it's this simple but the jQuery .change() method on the drop down list triggers the onchange event on the select element twice! I'll look for other people who've had this problem and report back my findings!
<%# Page Language="C#" AutoEventWireup="true"%>
<!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">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('#ddlTest').change(function() { alert('jQuery event fired'); });
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:DropDownList id="ddlTest" runat="server" onchange="alert('element event');">
<asp:ListItem Text="First" />
<asp:ListItem Text="Second" />
</asp:DropDownList>
</form>
</body>
</html>
The call of $("#<%=ddlTest.ClientID%>").change(... is probably trigger your drop down list and because of your autopostBack, you get an second refresh of your page.
It looks like I've uncovered a bug in the latest version of jQuery :(. If I change the test back to version 1.3.2 it works fine! I've also found a reference to a bug raised with jQuery.
Take out the autopostback=true = it is firing one postback and the change event is another.

asp.net dropdownlist - C#.NET and javascript

I have a drop down and a div right next to it. The text contained inside the div should be updated based on value selected in the dropdown.
I do NOT want to use AutoPostBack feature.
Use OnChange client side event of the dropdownlist control. Here is a sample that updates a div's inner text with the selected value of the dropdown list :
<asp:DropDownList runat="server" ID="myDDL"
OnChange="document.getElementById('myDiv').innerText=this.value;">
</asp:DropDownList>
<div id="myDiv"></div>
As people have said, you cannot access the C# codebehind code without performing a postback.
One way of accomplishing what you want is to use PageMethods. This is the Microsoft idiom for accomplishing this but there are lots of other Ajax libraries that will do it.
Provide a static method in your codebehind which will get called form your dropdownlist OnChange event.
[WebMethod]
public static string MyMethod()
{
// Your code goes here
return "The text for the div"
}
You then call this PageMethod from your .aspx page:
You need to add a scriptmanager (after the form tag)
<asp:ScriptManager ID="scriptmanager1" EnablePageMethods="true" EnablePartialRendering="true" runat="server" ></asp:ScriptManager>
Then in the OnChange event (or a function called from it) you have:
<asp:DropDownList id="ddl" runat="server" OnChange="PageMethods.MyMethod(OnComplete);" />
Where OnComplete is a javascript function that handlers the PageMethod response:
<script language="javascript">
function OnComplete(result, userContext, methodName) {
document.getElementById(yourDivId').innerText=result;
}
</script>
You can also have a paramaterised webmethod if needed:
[WebMethod]
public static string MyMethod(string myNeatParam)
{
// Your code goes here
return "The text for the div"
}
And call it with:
PageMethods.MyMethod('SomeValue', OnComplete)
Updated based on comments:
Here's a sample page on using an UpdatePanel to do what you need to do. Please keep in mind though that there is a full postback happening, even though it is transparent to the user.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="UpdatePanelMadness._Default" %>
<!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></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="ColorsDropDownList" runat="server" AutoPostBack="true"
onselectedindexchanged="ColorsDropDownList_SelectedIndexChanged">
<asp:ListItem Text="Red" Value="Red" />
<asp:ListItem Text="Green" Value="Green" />
<asp:ListItem Text="Blue" Value="Blue" />
</asp:DropDownList>
<div id="ColorDiv" runat="server">
<p>
Hello World!
</p>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
code behind:
namespace UpdatePanelMadness
{
using System;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ColorsDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
ColorDiv.InnerText = this.ColorsDropDownList.SelectedValue;
}
}
}

how to scroll asp.net textbox to bottom

I'm building a website with text box containing log messages. the log is getting updated using AJAX.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" >
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"
onload="textbox_load"
Height="110px"
TextMode="MultiLine"
Width="100%">
</asp:TextBox>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
I need to scroll the text box down every time it gets updated. How?
Handle the Sys.WebForms.PageRequestManager.endRequest event and scroll the textbox down:
var tbox = $get('<%= TextBox1.ClientID %>');
tbox.tbox.scrollTop = tbox.scrollHeight;
Why dont you try this simple example:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Page.ClientScript.RegisterStartupScript(this.GetType(),
"ScrollTextbox",
"<script type=\"text/javascript\">document.getElementById('" +
this.TextBox1.ClientID +
"').scrollTop = document.getElementById('" +
this.TextBox1.ClientID +
"').scrollHeight; " +
" </script>");
}
}
Just change TextBox1 parameter with your text box name. You can see that the content in the text box is scrolled to bottom.
You can call this java script after AJAX is refreshing the content of your text box.
Try some plain javascript. Here's a sample I think you can modify to work in your scenario:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
function scrollDown()
{
document.getElementById('<%=TextBox1.ClientID%>').scrollTop = document.getElementById('<%=TextBox1.ClientID%>').scrollHeight;
};
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</form>
</body>
</html>
You just have to figure out how to call the scrollDown method...

Resources