I want to show a loading indicator in my asp.net webpage while my gridview is being filled with data
This is part of my aspx page
<script type="text/javascript" src="Scripts/jsUpdateProgress.js"></script>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Panel ID="panelUpdateProgress" runat="server" CssClass="updateProgress">
<asp:UpdateProgress ID="UpdateProg1" DisplayAfter="0" runat="server">
<ProgressTemplate>
<div style="position: relative; top: 30%; text-align: center;">
<img src="Styles/images/loading.gif" style="vertical-align: middle" alt="Processing" />
Loading...
</div>
</ProgressTemplate>
</asp:UpdateProgress>
</asp:Panel>
<ajaxToolkit:ModalPopupExtender ID="ModalProgress" runat="server" TargetControlID="panelUpdateProgress"
BackgroundCssClass="modalBackground" PopupControlID="panelUpdateProgress" />
(My code is based on this sample weblogs.asp.net/blogs/guillermo/Code/modalExample.zip)
This is my button to call my method
<asp:UpdatePanel ID="updatePanel" runat="server">
<ContentTemplate>
<asp:Button ID="btMonth" runat="server" onclick="btMonth_Click" Text="Ver" />
</ContentTemplate>
</asp:UpdatePanel>
This is my c# code of my method btMonth_Click
protected void btMonth_Click(object sender, EventArgs e)
{
string query = "select * from table";
SqlDataSource1.SelectCommand = query;
gInd.DataSourceID = "SqlDataSource1";
}
As you can see while the "Loading" indicator appears I want to fill a GridView, but when I make click in my button the method btMonth_Click is invoked, the method is executed but my gridview doesn't get filled. If I remove the asp:UpdatePanel of my button my gridview is filled fine
Is there something I'm missing?
You need to place your GridVew inside of your UpdatePanel in order to be partial rendered
If for design reasons you cannot place your grid inside the first UpdatePanel, you can have several UpdatePanel
For more info:
How to work with two update panels on same .aspx page
Try to add:
gInd.DataBind();
in your btMonth_Click
(Btw. better naming convencion would be btnMonth_Click)
protected void btMonth_Click(object sender, EventArgs e)
{
string query = "select * from table";
SqlDataSource1.SelectCommand = query;
gInd.DataSourceID = "SqlDataSource1";
gInd.DataBind();
}
Related
I have two different forms that collapse and show either one or the other and there's a button to control them.
<div>
<button type="button"
data-toggle="collapse"
data-target=".multi-collapse"
aria-expanded="false"
aria-controls="form1 form2"> Change Form
</button>
<div class="collapse multi-collapse show" id="form1">
<asp:DropDownList AutoPostBack="true"
OnSelectedIndexChanged="SetDdl2ValuesBasedOnWhatIsSelectedOnDdl1"
ID="Ddl1"
runat="server">
</asp:DropDownList>
<asp:DropDownList ID="Ddl2"
runat="server">
</asp:DropDownList>
<asp:Button ID="Button1" OnClick="SubmitBtn"
<\div>
<div class="collapse multi-collapse" id="form2">
<asp:DropDownList AutoPostBack="true"
OnSelectedIndexChanged="SetDdl2ValuesBasedOnWhatIsSelectedOnDdl1"
ID="Ddl1"
runat="server">
</asp:DropDownList>
<asp:DropDownList ID="Ddl2"
runat="server">
</asp:DropDownList>
<asp:Button ID="Button1" OnClick="SubmitBtn"
<\div>
</div>
My problem is that whenever theres a post back I lose the collapse state of the forms and it goes back to the form1 showing and form2 hiding.
I want to save the state of the collapsables so they stay the same after a postback and I don't know how to do it.
I have done this through PageRequestManager, of course preserving the state of one or two divs, in your case there are two but if there are more, the solution I give is quite difficult but functional:
ASPX Code:
Add your controls in UpdatePanel
<div>
<button type="button"
data-toggle="collapse"
data-target=".multi-collapse"
aria-expanded="false"
aria-controls="form1 form2"> Change Form
</button>
<asp:UpdatePanel ID="up" runat="server">
<ContentTemplate>
<div class="collapse multi-collapse show" id="form1">
<asp:DropDownList AutoPostBack="true"
OnSelectedIndexChanged="Ddl1_SelectedIndexChanged"
ID="Ddl1"
runat="server">
</asp:DropDownList>
<asp:DropDownList ID="Ddl2"
runat="server">
</asp:DropDownList>
<asp:Button runat="server" ID="Button1" OnClick="Button1_Click" Text="btn1" />
</div>
<div class="collapse multi-collapse" id="form2">
<asp:DropDownList AutoPostBack="true"
OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"
ID="DropDownList1"
runat="server">
</asp:DropDownList>
<asp:DropDownList ID="DropDownList2"
runat="server">
</asp:DropDownList>
<asp:Button runat="server" ID="Button2" OnClick="Button1_Click1" Text="btn2" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
JavaScript Code:
The event add_beginRequest is an event that is fired when a Postback starts and it is possible to save the DOM state, while add_endRequest is the event that is fired when the panel is updated and the Postback ends, this is where the controls are arranged according to the conditions:
<script type="text/javascript">
var statusForm1 = false,
statusForm2 = false;
var prm = Sys.WebForms.PageRequestManager.getInstance();
function EndRequestHandler(sender, args) {
if (statusForm1) {
$('#form1').collapse('show');
}
if (statusForm2) {
$('#form2').collapse('show');
}
}
function BeginRequestHandler(sender, args) {
statusForm1 = $('#form1').is(":visible");
statusForm2 = $('#form2').is(":visible");
}
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
</script>
There is a simple and straight forward way of doing this which is, adding the class show to the div that you want to actually show. So, in order to do it, you must set both the divs to run at server. Here is my proposed idea for this problem:
<div class="collapse multi-collapse show" id="myform1" runat="server">
<!-- because in aspx, there is already a form1 form which is parent of all elements that runs at server -->
<!-- Other elements go here -->
</div>
<div class="collapse multi-collapse" id="myform2" runat="server">
<!-- Other elements go here -->
</div>
And on server events, you need to hide and show the respective divs by adding the classes to them.
protected void SubmitBtn1(object sender, EventArgs e)
{
// DoStuff();
ShowMyForm1();
}
protected void SubmitBtn2(object sender, EventArgs e)
{
// DoStuff();
ShowMyForm2();
}
protected void SetDdl2ValuesBasedOnWhatIsSelectedOnDdl1(object sender, EventArgs e)
{
// DoStuff();
// I assume this dropdown is in second form div.
ShowMyForm2();
}
private void ShowMyForm1()
{
myform1.Attributes["class"] = "collapse multi-collapse show"; // this will show the div
myform2.Attributes["class"] = "collapse multi-collapse"; // this will hide the div.
}
private void ShowMyForm2()
{
myform1.Attributes["class"] = "collapse multi-collapse"; // this will hide the div
myform2.Attributes["class"] = "collapse multi-collapse show"; // this will show the div
}
Notice, I have given two events for your submit button because it was appearing on both the forms and it had the same ID for it, which is not allowed for server controls. An ID must be unique. And your form2 has all the elements duplicated in it from the form1
So, to differentiate between those elements, You will have to give them different IDs.
Scenario: I have a modal-style div that will be shown when the user clicks a button. At the time the div is shown, I need to get some data from the back-end to fill in some fields. Additionally, I'd like to use the jQuery method I use for all my modal windows (fades in the modal div, displays a background div as well as enabling the use of ESC key or "click offs" to close the modal).
It looks something like this:
<asp:ScriptManager ID="sc" runat="server" />
<asp:UpdatePanel ID="updForm" runat="server">
<ContentTemplate>
<h4>Testing jQuery calls combined with code behind actions</h4>
<div class="pad-content">
<asp:LinkButton ID="lnkShowIt" runat="server" OnClick="lnkShowIt_Click" Text="Load Form" OnClientClick="showForm()" />
<asp:Panel ID="pnlPopup" ClientIDMode="Static" runat="server" CssClass="box-modal" style="width:500px;display:none;z-index:1001">
<div class="header">Edit Estimate X</div>
<div class="content">
<div class="window">
<h5>Test Form</h5>
<asp:TextBox ID="tbxTime" runat="server" />
<br />
<asp:TextBox ID="tbxText" runat="server" Width="150px" />
<br />
<asp:LinkButton ID="lnkValidate" runat="server" CssClass="link-button-blue" Text="Validate" OnClick="lnkValidate_Click" />
</div>
</div>
</asp:Panel>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div id="backgroundPopup"></div>
So ... lnkShowIt calls both the jQuery (which will show pnlPopup) as well as the C# (which will populate tbxTime).
jQuery method actually just calls another method from a common js library I have that does the modal window stuff - I don't think that actual code is the problem but here is the simple function used for this page:
<script type="text/javascript" language="javascript">
function showForm() {
loadPopup('#pnlPopup');
}
</script>
Code behind methods look like this:
protected void lnkShowIt_Click(object sender, EventArgs e)
{
tbxTime.Text = System.DateTime.Now.Second.ToString();
}
protected void lnkValidate_Click(object sender, EventArgs e)
{
if (tbxTime.Text == tbxText.Text)
{
Response.Redirect("DynamicBoxesWithJQuery.aspx?mode=success");
}
else
{
tbxText.Style["border"] = "1px solid red";
}
}
I'm able to generate some level of success by doing the following but it seems like just a major hack and I have to assume there's a better approach:
protected void lnkShowIt_Click(object sender, EventArgs e)
{
tbxTime.Text = System.DateTime.Now.Second.ToString();
ScriptManager.RegisterStartupScript(this, this.GetType(), "OpenEditor", "<script type='text/javascript'>loadPopup('#pnlPopup');</script>", false);
}
protected void lnkValidate_Click(object sender, EventArgs e)
{
if (tbxTime.Text == tbxText.Text)
{
Response.Redirect("DynamicBoxesWithJQuery.aspx?mode=success");
}
else
{
tbxText.Style["border"] = "1px solid red";
ScriptManager.RegisterStartupScript(this, this.GetType(), "OpenEditor", "<script type='text/javascript'>loadPopup('#pnlPopup');</script>", false);
}
}
It seems like it should be easier than this, but the way the UpdatePanel keeps redrawing (and thus resetting the display:none on pnlPopup) is really causing me fits.
Thanks in advance
Solution I just found: putting the LinkButton in its own UpdatePanel and then the form in its own UpdatePanel and making sure the div that is the actual popup box is not in an UpdatePanel at all.
<h4>Testing jQuery calls combined with code behind actions</h4>
<div class="pad-content">
<asp:UpdatePanel ID="updLink" runat="server">
<ContentTemplate>
<asp:LinkButton ID="lnkShowIt" runat="server" OnClick="lnkShowIt_Click" Text="Load Form" OnClientClick="showForm()" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="pnlPopup" ClientIDMode="Static" runat="server" CssClass="box-modal" style="width:500px;display:none;z-index:1001">
<div class="header">Edit Estimate X</div>
<div class="content">
<asp:UpdatePanel ID="updForm" runat="server">
<ContentTemplate>
<div class="window"style="min-width:500px;">
<h5>Here is a Test Form</h5>
<label>Time:</label>
<asp:TextBox ID="tbxTime" runat="server" />
<br />
<asp:Label ID="lblText" AssociatedControlID="tbxText" runat="server" ViewStateMode="Disabled">Text:</asp:Label>
<asp:TextBox ID="tbxText" runat="server" Width="150px" />
<br />
<asp:LinkButton ID="lnkValidate" runat="server" CssClass="link-button-blue" Text="Validate" OnClick="lnkValidate_Click" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</asp:Panel>
</div>
Seems to do the trick without any Script Registers from the codebehind
Here's the markup:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div class="well well-large">
<form class="navbar-form pull-left">
<asp:FileUpload ID="test" runat="server" CssClass="input-small" />
<br />
<asp:Button ID="btnUpload" runat="server" Text="Upload" CssClass="btn" OnClick="btnUpload_Click" />
</form>
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnUpload" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Panel runat="server" ID="panAlert" Visible="false">
<div class="alert alert-success" id="divAlert" runat="server">
<button id="Button1" runat="server" type="button" class="close" data-dismiss="alert">×</button>
You shouldn't see this message!
</div>
<asp:Panel runat="server" ID="panMarquee" Visible="true">
<div id="Div1" runat="server" class="progress progress-success progress-striped">
<div id="ProgressBar" runat="server" class="bar" style="width: 100%"></div>
</div>
</asp:Panel>
</asp:Panel>
When the btnUpload button is clicked, the server code is supposed to determine if the FileUpload control has a file. If it does, it will change the visibility of the Panel control to true. It works fine outside of the UpdatePanel.
Here's the server code:
protected void btnUpload_Click(object sender, EventArgs e)
{
this.SetMessage(Message.Success);
try
{
if (this.test.HasFile)
{
string filename = Path.GetFileName(GetUB04Doc.FileName);
//test.SaveAs(Server.MapPath("~/") + filename);
this.SetMessage(Message.Success);
}
}
catch (Exception ex)
{
//TODO: Do something with th exception
this.SetMessage(Message.Fail);
}
finally
{
//this.GetUB04Doc.Dispose();
}
}
private enum Message { Success, Fail }
private void SetMessage(Message msg)
{
if (msg == Message.Success)
{
this.divAlert.InnerText = "Well done! The document appears to have uploaded successfully. Please wait...";
this.divAlert.Attributes.Add("class", "alert alert-success");
}
else
{
this.divAlert.InnerText = "Oh snap! Something broke. Please contact IT right away.";
this.divAlert.Attributes.Add("class", "alert alert-error");
}
this.panAlert.Visible = true;
}
I tried putting the Panel in the ContentTemplate section as well, but the results were the same.
Any ideas on what I'm doing wrong here?
You should surround the area which you are modifying from an async postback in another UpdatePanel with UpdateMode is set to Conditional. Then update the other manually from codebehind:
<asp:UpdatePanel ID="panAlertUpdatePanel" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Panel runat="server" ID="panAlert" Visible="false">
<!-- ....
codebehind:
// ...
this.panAlert.Visible = true;
panAlertUpdatePanel.Update()
Side-note: As #Belogix has already commented, you should use an AsyncFileUpload control in an UpdatePanel since a regular FileUpload control it's not supported with an asynchronous postback.
MSDN:
Controls that Are Not Compatible with UpdatePanel Controls:
...
FileUpload and HtmlInputFile controls when they are used to upload files as part of an asynchronous postback.
...
To use a FileUpload or HtmlInputFile control inside an UpdatePanel
control, set the postback control that submits the file to be a
PostBackTrigger control for the panel. The FileUpload and
HtmlInputFile control can be used only in postback scenarios.
you need to put PostBackTrigger instead of AsyncPostBackTrigger like this. <asp:PostBackTrigger ControlID="btnUpload" />
I'm trying to update the source of an iFrame when a button is clicked on the page. However, nothing seems to be happening...
.ASPX:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
<ContentTemplate>
<div class="accountInfo">
<p class="submitButton">
<asp:Button ID="ValidateButton" runat="server" Text="Validate" OnClick="SubmitSponsor" />
</p>
</div>
<iframe runat="server" id="PayPalFrame" height="150px" width="100%" frameborder="0"></iframe>
</ContentTemplate>
</asp:UpdatePanel>
Code Behind:
protected void SubmitSponsor(object sender, EventArgs e)
{
var driver = new Driver();
var isvalid = driver.IsAppValid(URL.Text, APILINK, Connstring);
if (isvalid)
{
PayPalFrame.Attributes.Add("src", "http://www.google.com");
URLInvalid.Visible = false;
}
}
I've also tried:
PayPalFrame.Attributes["src"] = "http://www.google.com"; and still nothing.
I have tested your code, and it works in a sample project:
ASPX:
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
<ContentTemplate>
<div class="accountInfo">
<p class="submitButton">
<asp:Button ID="ValidateButton" runat="server" Text="Validate" OnClick="SubmitSponsor" />
</p>
</div>
<iframe runat="server" id="PayPalFrame" height="150px" width="100%" frameborder="0">
</iframe>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
Codebehind:
public partial class UpdatePanelIFrameTester : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SubmitSponsor(object sender, EventArgs e)
{
bool isvalid = true;
if (isvalid)
{
PayPalFrame.Attributes.Add("src", "http://www.ironworks.com");
}
}
}
I would inspect your code and ensure nothing is causing your page to refresh/perform a full postback (I changed the URL as google will not allow you to view it in an iframe under standard conditions).
I believe you have to remove the src attribute and then re-add it, for this to work. Not sure why this is, but I remember doing it the last time I worked with update panels. Perhaps it's because the src attribute always already exists?
Anyway, here's some sample code: how to change the src attribute in iframe.
Im having a .Master page with
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel runat="server" id="UpdatePanel" updatemode="Conditional">
<ContentTemplate>
<asp:ContentPlaceHolder ID="MasterIndhold_Member" runat="server">
</asp:ContentPlaceHolder>
And inside the ContentPlaceHolder I got an Panel with a FileUpload. The thing is that the FileUpload doesn't find the file. Here I want to add RegisterAsyncPostBackControl to the Scriptmanager, but how do I do this when the panel is on another page?
The nested page code looks like this
<asp:Content ID="Content3" ContentPlaceHolderID="MasterIndhold_Member" runat="server">
<asp:panel runat="server" ID="Panel_MyProfile_Member" Visible="false">
<asp:FileUpload ID="File1" runat="server" />
<asp:LinkButton ID="LinkUploadImageMember" runat="server" onclick="LinkUploadImageMember_Click">Upload</asp:LinkButton>
And the CodeBehind for the FileUpload Looks like this
protected void LinkUploadImageMember_Click(object sender, EventArgs e)
{
if (File1.HasFile == true)
{
if ((File1.PostedFile.FileName.EndsWith(".jpg")) || (File1.PostedFile.FileName.EndsWith(".jpeg")) || (File1.PostedFile.FileName.EndsWith(".png")))
{
byte[] input = File1.FileBytes;
Bruger.UploadImage(input, int.Parse(Request.QueryString["ID"]));
}
}
}
Please keep code examples to C# and ASP.NET as I'm new to this stuff ^^
Thanks
You could also use the ScriptManagerProxy class if you need a ScriptManager on your content page, but I'm not sure whether you need this at all. Do you really need an UpdatePanel on every content page? (because you declared it on the master page). I think it might be better to declare the UpdatePanel within the content page.
Try to define a trigger for your linkbutton, otherwise HasFiles is always false
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:PostBackTrigger ControlID="LinkUploadImageMember" />
</Triggers>
<ContentTemplate>
<asp:FileUpload ID="File1" runat="server" />
<asp:LinkButton ID="LinkUploadImageMember" runat="server" Text=" upload " />
</ContentTemplate>
</asp:UpdatePanel>
If you cannot remove the UpdatePanel from the Masterpage, you could expose a property on the masterpage that gives access the updatepanel, like this:
public UpdatePanel MyUpdatePanel
{
get { return UpdatePanel1; }
}
From the contentpage you can access the update panel and update the triggers programmatically:
protected void Page_Load(object sender, EventArgs e)
{
((Site)Master).MyUpdatePanel.Triggers.Add(new PostBackTrigger() {
ControlID = LinkUploadImageMember.UniqueID });
}