ProgressBar in UpdateProgress keeps expiring before the data is fetched - asp.net

I have a GridView which shows some data and has a Button in the last column that combines the value of the 3 other columns.
I was able to refresh the GridView easily just by calling this Function GridData in the rowCommand.
protected void GridviewProcess_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
if (e.CommandName == "More")
{
objENT = new ENT();
int index = Convert.ToInt32(e.CommandArgument.ToString());
Label locCode = (Label)GridviewProcess.Rows[index].FindControl("lbl0");
Label SurveyNo = (Label)GridviewProcess.Rows[index].FindControl("lbl2");
Button Combine = (Button)GridviewProcess.Rows[index].FindControl("btnCombine");
Combine.Enabled = false;
objENT.LocationCode = locCode.Text;
objENT.SurveyNumber = SurveyNo.Text;
objENT.ProcType = "CREATECUSTOMER";
DataSet ds = new DataSet();
ds = BLL.CdCustomer(objENT);
}
}
catch (Exception ex)
{
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alertMessage", "alert('Some Error occurred Please refresh the page')", true);
}
finally
{
Griddata();
}
private void Griddata()
{
objENT.ProcType = "PAGEGRIDDATA";
DataSet ds = BLL.ProcessGrid(objENT);
string check = ds.Tables[0].Rows[0]["TOTAL_CUSTOMER"].ToString();
GridviewProcess.DataSource = ds.Tables[0];
ViewState["Grid"] = ds.Tables[0];
GridviewProcess.DataBind();
}
After,I added this ProgressBar
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:UpdateProgress ID="UpdateProgress2" runat="server" AssociatedUpdatePanelID="UpdatePanel2">
<ProgressTemplate>
<img src="images/progress_bar.gif" style="max-width: 250px" />
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:GridView ID="GridviewProcess" AllowPaging="true" CssClass="GridHeader" PagerSettings-Mode="NextPreviousFirstLast" PagerSettings-PreviousPageText="<-Prev  " PagerSettings-Visible="true" PagerSettings-NextPageText="  Next->"
PagerSettings-FirstPageText="<=FirstPage  " PagerSettings-LastPageText="  LastPage=>" PagerStyle-Font-Bold="true"
OnPageIndexChanging="GridviewProcess_PageIndexChanging" PageSize="12" OnRowDataBound="GridviewProcess_RowDataBound" OnRowCommand="GridviewProcess_RowCommand" runat="server" Style="text-align: center" Width="99%"
AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Total Customers" HeaderStyle-BackColor="#99CCCC">
<ItemTemplate>
<asp:Label ID="lbl7" runat="server" Text='<%# Eval("TOTAL_CUSTOMER") %>'>
</asp:Label>
<asp:Button ID="btnCombine" CssClass="btn-primary btn" Text="Combine"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" CommandName="More"
Style="padding-top: 1%; padding-bottom: 1%; margin-top: 1px; margin-bottom: 1px" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAddi" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
The ProgressBar will show but after the function GridData(){} is called it wont refresh the GridView.
I can see the changes only after,I refresh the whole page.
I don't understand whats going wrong...
I don't have any JS or CSS used for this ProgressBar..(Is that the problem?)

Found the Solution to the Problem on SO questions
UpdateProgress Timed Out before data could be processed
Actual problem was :
I have a button on my ASP.NET page, which fetches some data from my database and displays it on a GridView.
This process takes a while, so I thought I'll add an updateprogress AJAX control. Now when I click the button, the UpdateProgress Image shows up and data is being fetched from my database successfully (I checked this from some logs that I have in my DB). But there are 2 issues:
The UpdateProgress image shows only for about 2 minutes. But my ButtonClick event takes about 5 minutes to complete. Basically the UpdateProgressstops showing up even before my task is complete, which defeats its purpose.
As I found this in one of the SO Answers
As per issue most likely it is ajax timing out. Default timeout is 90 seconds. To increase that use ScriptManager's AsyncPostBackTimeout property:
<asp:ScriptManager ID="ScriptManager1" runat="server" AsyncPostBackTimeout="400">
</asp:ScriptManager>
If AJAX call is timing out, controls on the page might not work correctly so increasing timeout might solve problem (2) as well.

Related

how to do not postback button click

I want to prevent this phenomenon ...
Postback when button is clicked
I want to perform the result when the button is clicked and prevent the screen refresh.
<asp:Button ID="DomainSeachButton" runat="server" Text="search"
OnClick="btnDomainSearch_Click" OnClientClick="onMySearch();" Width="69px" />
function onMySearch() {
// __doPostBack("DomainSeachButton", "client");
var r = confirm("Press a button!")
if (r==true)
{
alert("You pressed OK!")
return true;
}
protected void btnDomainSearch_Click(object sender, EventArgs e)
{
if (_cDBConnect.IsValidDBInfo() == true)
{
string sql = string.Format("select * from tb_licensekey_storages where cert_domain_name like '%{0}%';", txtSearchDomain.Text.Trim());
var da = new SQLiteDataAdapter(sql, _cDBConnect.GetConnectionString());
DataTable dt = new DataTable();
da.Fill(dt);
gridViewDBInfo.DataSource = dt;
gridViewDBInfo.DataBind();
}
}
You can easily achieve this with ASP Control UpdatePanel it will not actually refresh the whole page but the the selected content of the page, for example:
<asp:ScriptManager ID="MainScriptManager" runat="server" />
<asp:UpdatePanel ID="updtpnl" runat="server">
<ContentTemplate>
<asp:Button
ID="DomainSeachButton"
runat="server"
Text="search"
OnClick="btnDomainSearch_Click"
OnClientClick="onMySearch();"
Width="69px"
AutoPostBack="true"
/>
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DomainSeachButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Try changing your btnDomainSearch_Click to
$("#btnDomainSearch_Click").click( function(e){
e.preventDefault();
//Whatever
})
You can use AutoPostBack="false" in the particular button.
if AutoPostBack set false it will not send request to server otherwise it will send request to server.
<asp:Button ID="DomainSeachButton" runat="server" Text="search" AutoPostBack="false" OnClick="btnDomainSearch_Click" OnClientClick="onMySearch();" Width="69px" />
Please read this article for more information More Details

asp:UpdatePanel work only when other inputs are valid

I have this UpdatePanel:
<asp:ScriptManager ID="CheckManager" runat="server" />
<asp:UpdatePanel ID="checkUsername" runat="server" UpdateMode="Conditional" >
<ContentTemplate>
<asp:Label ID="canUse" runat="server" Text=""/>
<asp:Button ID="check" runat="server" Text="Usable?" onclick="check_Click" />
<asp:TextBox ID="username" runat="server" ></asp:TextBox>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger controlid="check" eventname="Click" />
</Triggers>
</asp:UpdatePanel>
update code:
protected void check_Click(object sender, EventArgs e)
{
using (HotelEntities h = new HotelEntities())
{
UserHandle u = new UserHandle();
if (u.FindUserByUsername(h, username.Text.ToString()).Any())
{
canUse.ForeColor = Color.Magenta;
canUse.Text = "You cannot use this username";
username.Text = "";
}
else
{
canUse.ForeColor = Color.Green;
canUse.Text = "you can use this username";
}
}
}
but works only when other inputs in form (that have validations e.g. RequiredFieldValidator) are valid .
How can I fix this?
Set CausesValidation="false" for the button for which you do not want validation to be performed when the Button control is clicked.
<asp:Button ID="check" CausesValidation="false" runat="server"
Text="Usable?" onclick="check_Click" />
Button.CausesValidation Property: Gets or sets a value indicating whether validation is performed when the Button control is clicked.
You need to set the ValidationGroup property same with the button and your textbox validations etc. For example you have required field validator near the textBox1. And you have two buttons. If you dont use ValidationGroup, you wont be able to click any of them without validating your inputs.
You may
Check here to see an example

How to set the target control id of ajax modelpop up extender to a run time button created id?

I am creating a button at run time and on it's click i want to open a ajax model pop up.
But i am unable to set model pop up's target control id to this run time created button id.
Could some body suggest me how to achieve this? or any alternate way exist?
My code is as following.
This is how i am creaing a run time button.
protected void grdSurveyMaster_ItemCreated(object sender, GridItemEventArgs e)
{
if (e.Item is GridFooterItem)
{
GridFooterItem footerItem = (GridFooterItem)e.Item;
// RadScriptManager1.RegisterAsyncPostBackControl(btn);
Button btn = new Button();
btn.Text = "Take a new survey";
btn.CommandName = "newAssess";
btn.Click += new System.EventHandler(grdMasterbtnClick);
footerItem.Cells[2].Controls.Add(btn);
//ModalPopupExtender1.TargetControlID = "btn";// Convert.ToString(Page.FindControl(Convert.ToString(btn.ClientID)));
}
}
And following is my HTMl
<asp:UpdatePanel ID="updatepanel1" runat="server">
<ContentTemplate>
<cc1:ModalPopupExtender CancelControlID="btnCancel" PopupControlID="modelPopUp" ID="ModalPopupExtender1"
runat="server" TargetControlID="btnDefault">
</cc1:ModalPopupExtender>
<asp:Button ID="btnDefault" runat="server" Visible="false" />
<asp:Panel ID="modelPopUp" runat="server" Visible="false" BackColor="AliceBlue">
<p>
These items will be permanently deleted and cannot be recovered. Are you sure?
</p>
<asp:Button ID="btnOk" Text="OK" runat="server" />
<asp:Button ID="btnCancel" Text="Cancel" runat="server" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Well you're doing right setting the Popup's TargetControl an invisible unused button. Now the best way to show/hide your popup is from Javascript. For this you have to set the behaviorid="someString" of your ModalPopupExtender and create a javascript function like this:
function ShowModalPopup(behaviourId) {
$find(behaviourId).show();
}
Then you can assign the javascript function to a button:
btn.OnClientClick = String.Format("ShowModalPopup('{0}')",
ModalPopupExtender1.behaviorid);

ASP.NET - lazy loading dynamic tabs

I'm stumped on this one and hope someone out there's done something similar.
I have an ASP.NET application that has a number of AJAX toolkit tabs. The number of tabs varies page to page, since they're dynamically generated based on settings in a config file.
That being said, some of the tabs are database-driven. The load time when a number of these tabs are on the page can be significant, so I want to implement lazy loading.
I'm following Matt Berseth's pattern, but it seems to break down when the number of tabs is dynamic (each tab needs its own method on the page).
If anyone has a suggestion on how to tackle this, it'd be much appreciated.
I've started working with a small app to get the lazy loading to work. This lazy loads the second tab (which is hard coded), but the third tab is what I'm struggling with (it's dynamically added).
Edited to add code: ASPX page
<script language="javascript" type="text/javascript">
function clientActiveTabChanged(sender, args) {
// see if the table elements for the grids exist yet
var isTab2Loaded = $get('<%= this.lbl2.ClientID %>');
// if the tab does not exist and it is the active tab,
// trigger the async-postback
if (!isTab2Loaded && sender.get_activeTabIndex() == 1) {
// load tab1
__doPostBack('btnTrigger', '');
}
// else if (!isTab2Loaded && sender.get_activeTabIndex() == 2)
// load tab2
// __doPostBack('btnEmployeesTrigger', '');
}
</script>
<asp:scriptmanager ID="Scriptmanager1" runat="server"></asp:scriptmanager>
<div>
<cc1:TabContainer ID="tc1" runat="server" OnClientActiveTabChanged="clientActiveTabChanged">
<cc1:TabPanel TabIndex="0" runat="server" HeaderText="Tab1" ID="Tab1">
<ContentTemplate>
<asp:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Label ID="lbl1" text="I am here" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel runat="server" HeaderText="Tab2" ID="Tab2">
<ContentTemplate>
<asp:UpdatePanel ID="up2" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Label ID="lbl2" Text="Load when called" Visible="false" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnTrigger" />
</Triggers>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
</cc1:TabContainer>
</div>
<input ID="btnTrigger" style="display:none;" runat="server" type="button" onserverclick="btnTrigger_Click" />
<input id="btnTrigger2" style="display:none;" runat="server" type="button" onserverclick="btnTrigger2_Click" />
Codebehind:
protected void Page_Init(object sender, EventArgs e)
{
//TabPanel tp = new TabPanel();
//tp.Controls.Add(new LiteralControl("Load first"));
//tp.HeaderText = "Tab1";
//tc1.Tabs.Add(tp);
//tc1.ActiveTabIndex = 0;
//TabPanel tp2 = new TabPanel();
//UpdatePanel up1 = new UpdatePanel();
//up1.Controls.Add(new LiteralControl("Load me when called"));
////up1.Triggers.Add(new AsyncPostBackTrigger());
//AsyncPostBackTrigger trg = new AsyncPostBackTrigger();
//tp2.Controls.Add(up1);
//tp2.Controls.Add(new LiteralControl("Load when called"));
//tp2.HeaderText = "Tab2";
//tc1.Tabs.Add(tp2);
TabPanel tp3 = new TabPanel();
tp3.HeaderText = "Tab3";
UpdatePanel up3 = new UpdatePanel();
LiteralControl lc = new LiteralControl("Load me when needed");
lc.ID = "lit3";
lc.Visible = false;
up3.ContentTemplateContainer.Controls.Add(lc);
tp3.Controls.Add(up3);
tc1.Controls.Add(tp3);
}
protected void btnTrigger_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2500);
this.lbl2.Visible = true;
}
Is the content of the Tabs also database-driven like a CMS?
You could use UserControls as Content and let all implement the same interface f.e. IDataBindable with a function BindData. On this way you can lazyload these UserControl independently of its content.
On ActiveTabChanged you only have to call this function and thenUpdate on the TabContainer's UpdatePanel.
The quick way to do this might be to not load any tabs (i.e. don't actually give them any content) besides the default until that tab is clicked (detected during OnActiveTabChanged or OnClientActiveTabChanged).
However, Tim's method allows the OnActiveTabChanged method to be as simple as databinding the UserControl relative to that tab - that's probably the best method, though it is more effort.

How do I maintain user entered text in a TextBox nested in an UpdatePanel between updates?

I have an ASP.Net UpdatePanel that updates on a timer. Within the UpdatePanel and nested in a GridView, I have a TextBox that the user enters a value in with a submit button. Everything works fine, except if the user does not submit the value before the timed interval, the text is removed from the TextBox.
Is there a way to persist the user entry into the TextBox between updates? Is there a better way of doing this?
All suggestions welcome.
Respectfully,
Ray K. Ragan
Code Postscript:
aspx:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest() {
prm._scrollPosition = null;
}
</script>
<asp:Timer ID="Timer1" runat="server" Interval="900" OnTick="Timer1_Tick"></asp:Timer>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:DataList RepeatColumns="5" RepeatDirection="Horizontal" ID="dlMine" runat="server" OnItemCommand="Item_Command">
<ItemTemplate>
<div style="border:1px solid black;margin:3px;height:300px;text-align:center;padding:5px;">
<div style="width:150px;">
<asp:Label ID="lblTitle" runat="server" Text='<%# left(DataBinder.Eval(Container.DataItem,"title").ToString(), 75) %>'></asp:Label>
</div>
<asp:Label ID="Label1" runat="server" Text='<%# (DateTime)DataBinder.Eval(Container.DataItem,"end_date") %>'></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text='<%# String.Format("{0:C}",DataBinder.Eval(Container.DataItem,"current_value")) %>'></asp:Label>
<br />
<asp:TextBox ID="txtNewValue" runat="server"></asp:TextBox>
<asp:Button Visible='<%# (isInThePast((DateTime)DataBinder.Eval(Container.DataItem,"end_date"))) ? false : true %>' CssClass="bid_button" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Revalue" ID="btnBid" Text="Submit New Valuation" />
</div>
</ItemTemplate>
</asp:DataList>
</ContentTemplate>
</asp:UpdatePanel>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
Timer1.Tick += new EventHandler<EventArgs>(Timer1_Tick);
if (!IsPostBack)
{
dataBindList();
}
}
protected void dataBindList()
{
if (Request.QueryString["GroupID"] != null)//Are they coming here with a URL var? If so, build content object
{
List<Item> itemList = ItemManager.getItemsByGroupID(Request.QueryString["GroupID"].ToString());
dlMine.DataSource = itemList.Take(15);
dlMine.DataBind();
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
dataBindList();
UpdatePanel1.Update();
}
protected void Item_Command(Object sender, DataListCommandEventArgs e)
{
if (e.CommandName == "Revalue")
{
Person p = (Person)Session["Person"];
foreach (DataListItem item in dlMine.Items)
{
string textBoxText = ((TextBox)item.FindControl("txtNewValue")).Text;
Utilities.writeLog("txtNewValue: " + textBoxText, 1);
}
dataBindList();
UpdatePanel1.Update();
}
}
You're rebinding the DataList every time the Timer ticks. All changes in the ItemTemplates of the DataList will be lost on postback.
Why not use Javascript to "pause" the timer whenver one of the textboxes gains focus. This will prevent the Timer from firing and let users finish entering text. Once they leave the textbox of "onblur" then you can restart the timer.
Update
The following will take a bit of effort to make it happen but you can do something like:
When the Timer posts back, before rebinding, iterate over the DataList while searching for textboxes with text in them. Something like:
foreach (DataListItem item in dlMine.Items)
{
//find the textbox control and check for text
}
At this point, you'll know which rows need there textboxes repopulated. Store this information in a hashtable.
In the DataList ItemDataBound event, check each rowID against the hashtable to see if its corresponding textbox exists. If so, repopulate the textbox in the DataList row.
Are you initializing the TextBbox value in your code-behind, perhaps in Page_Load or another page method?
TextBox1.Text = "";
If so, that code is executing on every timer event. You can prevent that like this:
if (! IsPostback) {
TextBox1.Text = "";
}
The first request that hits an ASP.NET page is usually an HTTP GET request, while ASP.NET buttons and update panel events issue HTTP POST requests. So the code above will clear TextBox1 the first time you access the page, but leave the value alone when receiving requests from itself. (If you really are setting the text box's value to its default - empty - you could just remove the initialization code.)

Resources