AJAX.NET __doPostBack changes other content - asp.net

I have an application where a javascript reads the GPS location of the device and sends it to serverside script like this:
f()
{
var initialLocation= Someshit();
document.getElementById('<% = text.ClientID %>').value=initialLocation;
var button = document.getElementById('<% = Button4.ClientID %>');
button.click();
}
And i have some AJAX.NET code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button4" runat="server" Text="PlaceHolder" onclick="Button4_Click"/>
<asp:TextBox ID="text" runat="server"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
And a bit further down
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<div>
<some divs and asp:gridviews and god knows what >
</div>
<ContentTemplate>
</asp:UpdatePanel>
The problem is that the the last divs inner content changes when the event of UpdatePanel1 has finished. Why is that? I don't want the content outside of UpdatePanel1 to be changed whenever UpdatePanel1 is doing its thing. Please help.

The default UpdateMode is Always, in this case you want Conditional, like this:
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div>
Yadda yadda
</div>
<ContentTemplate>
</asp:UpdatePanel>
From MSDN, here's the difference:
Always - The content of the UpdatePanel control is updated for all postbacks that originate from the page. This includes asynchronous postbacks.
Conditional - The content of the UpdatePanel control is updated under the following conditions:
If the Update method of the UpdatePanel control is called explicitly.
If a control is defined as a trigger by using the Triggers property of the UpdatePanel control and causes a postback. In this scenario, the control is an explicit trigger for updating the panel content. The trigger control can be either inside or outside the UpdatePanel control that defines the trigger.
If the ChildrenAsTriggers property is set to true and a child control of the UpdatePanel control causes a postback. In this scenario, child controls of the UpdatePanel control are implicit triggers for updating the panel. Child controls of nested UpdatePanel controls do not cause the outer UpdatePanel control to be updated unless they are explicitly defined as triggers.

Related

Partial update doesn't work with master pages

I am working on a C# asp.net web forms project. It has two master pages. I
have an user control which reads data from database,
creates an un-ordered list in html string and populates a placeholder with
it. This user control has to be automatically
refreshed every 2 minutes. I have included this usercontrol on the parent
master page. I have the following code to refresh the
user control, which I have obtained through another stackoverflow answer.
The problem is that the entire master page refreshes, and I am not sure why.
Is there a way to make that only the user control which has the UpdatePanel
refreshes?
Outer Master Page:
<body>
<form id="frmMain" role="form" method="post" runat="server">
<div>
<uc2:PendingOrders runat="server" ID="PendingOrders" />
</div>
<asp:ContentPlaceHolder ID="MainBodyContent" runat="server">
</asp:ContentPlaceHolder>
</form>
</body>
User Control:
<asp:ScriptManager ID="myScriptManager" runat="server"
EnablePartialRendering="True"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode = "Conditional"
runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="20000"
OnTick="Timer1_Tick"></asp:Timer>
<asp:PlaceHolder runat="server" id="lblMyOrders"></asp:PlaceHolder>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
User Control Code behind:
protected void Timer1_Tick(object sender, EventArgs e)
{
//This method creates the html string with data as an unordered list
and
//populates asp:PlaceHolder inte updatepanel
GetData();
}
UpdatePanel1's Content will be update by Timer1_Tick.
"entire master page refreshes" means master page's Page_Load will be call while Timer1 been trigger?
UpdatePanel always post entire page back server and only render UpdatePanel1's Content.
I had the same problem, but in our project the EnablePartialRendering was set to false on the Master Page, if set to true the whole project breaks.
To fix the problem, I defined another master page without ScriptManager and added the ScriptManager to the page in which I wanted to use UpdatePanels with the EnablePartialRendering attribute set to True.
This fixed the problem.
<asp:ScriptManager ID="myScriptManager" runat="server" EnablePartialRendering="True"></asp:ScriptManager>

clientidmode static is not working with updatepanel which forces full postback

I have RadioButtonList & Listvie in my page. I am using update panel to avoid postback Now my radioButtonList works as filter for listview. My Problem is in my radiobuttonList I have to use clientIDmode=static but if I do that then my updatepanel has no use since there is full postback when radiobuttonList gets changed. How to solve this problem without removing clientIdmode=static. I seen some solution for kind of same post but really didn't understand. Please help me.
My code has following structure.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:RadioButtonList ID="areasList" CssClass="mark" AutoPostBack="true" runat="server" ClientIDMode="static" RepeatLayout="Flow">
</asp:RadioButtonList>
ListviewHere
</ContentTemplate>
</asp:UpdatePanel>
There is an issue with your script.
You script is not being called after postback.
So use as below,
<script type="text/javascript">
// below will execute after ajax postback
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
//script
}
// executes after page load first time
//script
</script>
You can set the ClientIDMode of the RadioButtonList to AutoID (or not specify the attribute in the markup if that is the default value) and use a binding expression in client code to get the actual ID of the control:
$("#<%= areasList.ClientID %>")
or
document.getElementById('<%= areasList.ClientID %>')

Trigger asp.net update panel using hyperlink

I am developing a website in asp.net 2010 and use asp.net controls to use Ajax.
I have an update panel that does not have _Load event and no trigger tag and should be triggered (not updated) manually by clicking a hyperlink (tag 'a'). I have to use hyperlink instead of other controls such as button for some reasons.Now I want a javascript or jquery function to trigger my update panel or call a function in server side code that triggers it.
my asp.net code:
<a id="trg" href="#div5"></a>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
my c# function that should be called to update UpdateUanel1 by clicking hyperlink trg:
protected void func()
{
Label1.Text=System.DateTime.Now.ToString();
}

jQuery click disappears into some abyss

Here is my setup:
I have an asp.net button on a page --
<asp:Button id="btnSelectEmp" runat="server" Text="Select Employee" />
I have a .js file with the following jQuery click event --
$("input[id$='_btnSelectEmp']").click(function ($e) {
$("div[id$='_divEmpSearch']").css("display", "inline");
$e.preventDefault();
});
As you can see, clicking upon the button will set a div visible. Nothing special; not rocket science.
The div is wrapped with an asp.net update panel, and it contains an asp.net user control (.ascx)
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div id="divEmpSearch" runat="server" style="display: none;">
<uc:EmpSearch ID="ucEmpSearch" runat="server" />
</div>
// And a bunch of other controls that are updated according to whatever the user selects in the user control above
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ucEmpSearch" />
</Triggers>
</asp:UpdatePanel>
The user control above is also wrapped in an asp.net update panel, because it has to communicate with the server. Among other controls like textboxes and such, the user control has two buttons upon it: 1) an asp.net button that does a postback and 2) an asp.net button that does an asynchronous postback.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" /
<br />
asp:Button ID="btnContinue" runat="server" Text="Select" OnClick="btnContinue_Click" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
<asp:PostBackTrigger ControlID="btnContinue" />
</Triggers>
</asp:UpdatePanel>
The button in the user control that does a postback is working great. I click it, a postback occurs and my div control is re-hidden. I can then click on the Select Employee button (the one that I supplied the code for at the very first of the question) and the jQuery click event is handled and the div will be reshown.
However, the button in the user control that does an asynchronous postback works also, but after it hides the div, if I then click on the Select Employee button the jQuery click event will not be handled.
What this tells me is that for some reason during an asynchronous postback to the page, something happens to the Select Employee button so that the jQuery click event no longer happens. Why?
Your button is replaced with a new one when your update panel comes back with new content, so this:
$("input[id$='_btnSelectEmp']").click(function ($e) {
Binds to the elements it finds at that time, instead you'll want .delegate() or .live() here to listen for click events from current and future elements, like this:
$("input[id$='_btnSelectEmp']").live("click", function ($e) {
$("div[id$='_divEmpSearch']").css("display", "inline");
$e.preventDefault();
});
Or a bit cheaper using .delegate():
$("#container").delegate("input[id$='_btnSelectEmp']", "click", function ($e) {
$("div[id$='_divEmpSearch']").css("display", "inline");
$e.preventDefault();
});
In this case #container should be a parent of the update panel, one that doesn't get replaced in the postback.
Use the live() function. live() delegates the click event to a parent element, so the element (in this case btnSelectEmp) doesn't need to exist at the time the event is bound.
$("#<%=btnSelectEmp.ClientID%>").live("click" function ($e) {
$("#<%=divEmpSearch.ClientID%>").css("display", "inline");
$e.preventDefault();
});
What is happening is the btnSelectEmp button is getting replaced by the asynchronous call and the new element has not been bound to an event handler.
Also, I've modified the jquery selector here to use the exact client id of the element. This will improve speed, plus I seem to recall certain selectors don't work with event delegation in certain versions of Jquery.
try live('click', function(){...}) instead of click(function(){...})
Wild guess : "_btnSelectEmp" is used more than once?

FileUpload in FormView inside an UpdatePanel

The Scenario:
I have an ASP.Net webpage which I intend to use for letting the user(not the real users, but content manager basically) insert and edit the records in a table using a FormView. This FormView is inside an UpdatePanel, as I'm also using cascading dropdownlists to let the user select some values.
Now, this FormView also contains 4 FileUpload controls, and as you might know that these fileupload controls require a full postback since most browsers do not let Javascript access the disk. So, this problem would have been solved by doing something like:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="InsertButton" />
<asp:PostBackTrigger ControlID="UpdateButton" />
</Triggers>
<ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>
Edit: Forgot to add that the fileuploading takes place in the OnUpdating and OnInserting events of the SqlDataSource.
The Problem:
Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup. And MSDN says that:
Programmatically adding
PostBackTrigger controls is not
supported.
Please suggest some solution to make this work. Any insight on the matter is highly appreciated. Thanks.
P.S.- A workable solution for me was to set the UpdatePanel's PostBackTrigger as the whole FormView itself:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="FormView1" />
</Triggers>
<ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>
But now due to a bit of change in requirements, this solution(if you call it a solution) is not acceptable.
Have you given a though about using Iframe for doing the postback ? something like:
<iframe name="uploader" id=uploader
src="uploaderSender.aspx?AllowedExtension=<%= AllowedExtension %>&StoringPath=<%= StoringPath %>&StoringFileName=<%= StoringFileName %>&OldFileName=<%= OldFileName %>&MaximumSize=<%= MaximumSize %>"
width="450" height="50" frameborder=0 scrolling=no >
</iframe>
with uploaderSender.aspx like :
<form action="UploaderReceiver.aspx" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="file" onchange="document.getElementById('IsFileUploading').style.visibility = 'visible'; document.forms[0].submit()"/>
<span id="IsFileUploading" style="visibility: hidden">
<asp:Image ID="Image1" runat="server" ImageUrl="~/immagini/Ajax-loader.gif" />
</span>
</form>
and UploaderReceiver.aspx like :
protected void Page_Load(object sender, EventArgs e)
{
//if there is one file to process
if (Request.Files.Count > 0)
//create the folder if it does'nt exists and returns the local path to get it
string StoringPathToBeSaved = StoringPath.GetFolderPath();
// append the name of the file to upload to the path.
StoringPathToBeSaved = StoringPathToBeSaved + StoringFileName + Extension;
Request.Files[0].SaveAs(StoringPathToBeSaved);
}
this is just bits of code just for you to figure out if you would be interested in this way of dealing with the upload, I can give you more if you want after.
see you, and good luck with your code,
Yay!! Finally got it to work!
Here's How:
Well contrary to what MSDN says, we can in fact add PostBack Triggers Programmatically. Not necessarily to the UpdatePanel, but to the ScriptManager.
After hours of playing around, here's what worked:
We are not able to access controls inside a FormView, untill the template has been rendered, so we can only add postback triggers after the formview's OnDataBound Event.
protected void FormView1_DataBound(object sender, EventArgs e)
{
if (FormView1.CurrentMode == FormViewMode.Edit)
{
LinkButton lb = (LinkButton)FormView1.FindControl("UpdateButton");
ScriptManager.GetCurrent(Page).RegisterPostBackControl(lb);
}
//Similarily you can put register the Insert LinkButton as well.
}
And now, if your UpdatePanel causes ConditionalUpdate, you can do something like this to make it work:
The Markup:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>..
<EditItemTemplate>
...
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" OnClick="Cause_PostBack"CommandName="Update">Update</asp:LinkButton>
...
</EditItemTemplate>
..</ContentTemplate>
</asp:UpdatePanel>
CodeBehind:
//call this function as the OnClick Event Handler for the Controls you want to register as
//triggers.
protected void Cause_PostBack()
{
UpdatePanel1.Update();
}
Otherwise, if your situation allows it(as mine does), just set the UpdatePanel's UpdateMode="Always"
This is old, but was trying to solve another problem and ran into this. This wasn't my problem, but here's an alternative for anyone new who runs into this as well.
You stated your problem as:
Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup
You actually can access their ID's through markup to use as the ControlID in the PostBackTrigger. You just have to use the button's name that is created in the page html mark-up as the ControlID. You can find the name created by viewing the page source when you're viewing the page in the browser. It typically is the name of the FormView + $ + name of the button.
For example, let's say you have a FormView named "FormView1" that contains an Insert button which you gave the ID of "btnInsert" during design. If you open up your page in the browser to view it live and then view the page's source, you'll notice that the html mark-up of the button will actually be given the name "FormView1$btnInsert".
Use that name as the ControlID in your PostBackTrigger and your update panel will work.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="FormView1$btnInsert" />
</Triggers>
<ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

Resources