This is what I'm trying to do -
Using jQuery when the document is ready and if the page is not postback I issue a manual postback for an updatepanel to retrieve data from a database.
While the updatepanel is getting the data I present an updateprogress which I hide when the specific updatepanel finishes. I also want to "BLOCK" the screen from any interaction. After the data is loaded I have additional buttons on the form and I want to block everything in case of any partial-postback.
Here is the code:
$(document).ready(function ()
{
if(<% =(Not Page.isPostBack).ToString().ToLower() %>)
{
__doPostBack('upShipping');
}
}
function pageLoad() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
}
function BeginRequestHandler(sender, args)
{
$('.blur').css("display", "block");
if (args._postBackElement.id == 'upShipping') {
$get('divCalculating').className = 'Show';
}
}
function EndRequestHandler(sender, args)
{
$('.blur').css("display", "none");
if (sender._postBackSettings.sourceElement.id == 'upShipping')
{
$get('divCalculating').className = 'Hidden';
}
}
If I do not "CLICK" on the screen everything works great. But if I just click anywhere on the screen while the updatepanel updates the "EndRequestHandler" doesn't fire and I'm stuck with the loading gif and blocked screen.
I get the following error in the error console of the browser: sender._postBackSettings.sourceElement is undefined
Any ideas?
Thanks!
Nick
For some reason sender._postBackSettings.sourceElement kept coming back as NULL in the EndRequestHandler.
I defined a global var, assigned it a value at the BeginRequestHandler and checked its value instead in the EndRequestHandler.
This solved the problem.
Related
I have 1 page which has 1 updatepanel which contains 1 user control(lets call it user.ascx) and 2 buttons.
My user.ascx has some checkboxes which can disable/enable other controls. I am doing it in javascript added to user.ascx, but when updatepanel updates( async postback after clicking 1 of those 2 buttons) my javascript events for checkboxes (click or change) arem't fired.
I know I can just wrapp $().ready() with function pageLoad(sender,args) and it works perfect but according to that page http://blog.dreamlabsolutions.com/post/2009/03/25/jQuery-live-and-ASPNET-Ajax-asynchronous-postback.aspx it is better to use live() function.
Unfortunately all available ways to bind event like .click(), .change(), .bind(), .live() and .on() work after postback can't after asynchronus postback.
Sample of code which doesn't work:
<script type="text/javascript">
$().ready(function () {
var ddlAge= $("#<%= ddlAge.ClientID %>");
var cboxFirst= $("#<%= cboxFirst.ClientID %>");
var cboxSecond= $("#<%= cboxSecond.ClientID %>");
$(document).on("change", cboxFirst, function () {
if (cboxFirst.is(":checked")) {
ddlAge.attr("disabled", "disabled");
ddlAge.val("");
}
else { ddlAge.removeAttr("disabled"); }
});
cboxSecond.live('change',function () {
if (cboxSecond.is(":checked")) {
ddlAge.attr("disabled", "disabled");
ddlAge.val("");
}
else { ddlAge.removeAttr("disabled"); }
});
});
</script>
Both checkboxes work only after postbacks. What may I do wrong? Does anyhone have such problem? I am using Jquery 1.7.1 and I am not getting any js errors.
I will be grateful for any help.
I'm surprised that the .on works at all. According to the documentation http://api.jquery.com/on/ it's second parameter should be a selector string and not a jquery object.
I would try something like this:
$(document).on("change", "#<%= cboxFirst.ClientID %>", function () {
if ($(this).is(":checked")) {
ddlAge.attr("disabled", "disabled");
ddlAge.val("");
}
else { ddlAge.removeAttr("disabled"); }
});
As long as the ClientID stays the same the event will still work even when the UpdatePanel replaces all its content.
Also, .live has been deprecated in favor or .on
I am using DOJO (1.7) together with ASP.NET. I have attached an onclick event to the submit button but am trying to validate on client side first. In plain javascript, if I used a 'return false' statement, that stopped the postback. However, returning false in the code does not stop the statement while using DOJO. I am a DOJO newbie and have no idea what to do. Thank you for your time.
require(["dojo/io/script", "dojo/on", "dojo/dom", "dojo/domReady!"],
function (script, on, dom) {
on(dom.byId("<%= btnSubmit.ClientID %>"), "click", function () {
dom.byId("<%= txtSellPercentage.ClientID %>").value = "farax";
return false;
}
)
});
I had to tweak the code a little. Apparently I was trying to call some event method without importing the particular script for events. So here goes
<script type="text/javascript">
require(["dojo/io/script", "dojo/on", "dojo/dom", "dojo/domReady!", "dojo/_base/event"],
function (script, on, dom, event) {
on(dom.byId("<%= btnSubmit.ClientID %>"), "click", function (e) {
dom.byId("<%= txtSellPercentage.ClientID %>").value = "farax";
event.stop(e);
}
)
});
</script>
I need to get the id of the panel that is about to start a postback, so I have a generic way to block ui on this panel.
So far I have this function:
function BeginRequestHandler(sender, args) {
$('#' + args.get_updatePanelsToUpdate()[0]).block({ message: null });
}
attached like this:
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
this works pretty well to get the id if control that causes partial postback is inside update panel, but if it is outside (using a trigger), args.get_updatePanelsToUpdate() is always null
I've seen this answer, but it wont work forme because function is fired after partial postback is complete, I need it before..
Thank you
So here's what I did:
created 2 functions to block (on partial postback begin) and unblock (on partial postback end):
function BeginRequestHandler(sender, args) {
$('#' +sender._postBackSettings.panelsToUpdate[0].ReplaceAll('$', '_')).block({ message: 'loading...' });
}
function EndRequestHandler(sender, args) {
$('#' + sender._postBackSettings.panelsToUpdate[0].ReplaceAll('$', '_')).unblock();
}
Registered above functions on my page right after my script manager:
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
</script>
Some conditions:
I'm using jquery UI block plugin but you should use what better fits your needs.
You update panels should have ClientIDMode="AutoID" if your using .NET 4.0 +
I used the following helper function cause js doesn't make a real replace all and to deal with asp net autoID's:
String.prototype.ReplaceAll = function (stringToFind, stringToReplace) {
var temp = this;
var index = temp.indexOf(stringToFind);
while (index != -1) {
temp = temp.replace(stringToFind, stringToReplace);
index = temp.indexOf(stringToFind);
}
return temp;
}
If you just want to disable (or animate in some other way) the UpdatePanel, why not just use UpdatePanelAnimation? It provides you with the following hooks (not sure if that's the right word):
OnUpdating - Generic animation played as when any UpdatePanel begins
updating
OnUpdated - Generic animation played after the UpdatePanel
has finished updating (but only if the UpdatePanel was changed)
I have a fb:like button inside the GridView and GridView is inside the update panel. The first time of page load the fb:like button showing but when we click the next button, on the next page the fb:like button doesn't render. Any idea what's wrong?
Due to the fact that you are updating the page with an update panel, the like button will not be rendered when only part of the page is updated. You will have to attach to the clientside updated event (in JS) and then trigger the Facebook XFBML render command:
FB.XFBML.parse();
more about this here:
http://developers.facebook.com/docs/reference/javascript/FB.XFBML.parse/
You can do this using the following code:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoaded);
var _panels, _count;
function pageLoaded(sender, args)
{
if (_panels != undefined && _panels.length > 0)
{
for (i=0; i < _panels.length; i++)
_panels[i].dispose();
}
var panels = args.get_panelsUpdated();
if (panels.length > 0)
{
updateFbLike();
}
}
function updateFbLike()
{
FB.XFBML.parse();
}
</script>
this is taken from this article:
http://msdn.microsoft.com/en-us/magazine/cc163413.aspx
Richard's solution worked fine for me. I shortened the code to:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandlerBerliner);
function EndRequestHandlerBerliner(sender, args) {
if (args.get_error() == undefined) {
FB.XFBML.parse();
}
}
On load I'm both calling a JavaScript setTimeout() function that will hide a .NET Panel control, and hiding it in the code behind on first load. Clicking the save button will set the Panel to visible then reload the page at which point a setTimeout() function is called... so basically you click save, and see a panel with "Details Saved" for three seconds, at which point it disappears.
The problem is the external JavaScript file can't find _pDivAlert.ClientID (I've debugged and it returns null). It only works when the code is in a tag in the .aspx page. Any suggestions as to how I can either pass the client ID to the HideControl() function or find the ClientID from the external JS file?
Here's my code, any suggestions?
<script language="javascript" src="Forms.js" type="text/javascript"></script>
<body onload="ToggleAlert()">
<form id="form1" runat="server">
<script type="text/javascript">
//alert the user that the details were saved
function HideControl() {
var control = document.getElementById('<%=_pDivAlert.ClientID %>');
if(control != null)
control.style.display = 'none';
}
function ToggleAlert() {
setTimeout("HideControl()", 3000);
}
</script>
I've also tried sending the ClientID within the ToggleAlert() call, but that didn't work:
<body onload="ToggleAlert('<%=_pDivAlert.ClientID %>')">
External JS:
function HideControl(_c) {
var control = _c;
if (control != null)
control.style.display = 'none';
}
function ToggleAlert(_c) {
setTimeout("HideControl(_c)", 3000);
}
can you show your markup with the panel and the codebehind where you hide it?
there's a difference between setting the Visible property to false and setting the style display attribute to none- the first will not render the element at all, meaning there isn't anything rendered with the id you're looking for.
edit: it's probably because of the way you're calling HideControl in the timeout- this should be a function instead of a string.
try doing
function ToggleAlert(_c) {
setTimeout(
function () {
HideControl(_c);
}, 3000);
}
just for clarity, when you pass a string to setTimeout, it's evaluated and then run. the code chunk that eval produces will run in a different scope than your ToggleAlert method, and so _c won't be available at that time.
edit: you also need to actually get a reference to the control. you're passing the id string to ToggleAlert, which relays it to HideControl, which is expecting an object not a string.
function HideControl(_c) { // _c is the id of the element
var control = document.getElementById(_c);
if (control != null)
control.style.display = 'none';
}