I am working on a custom control that is being used on a webpage that contains many updatepanels. In my custom control, there is extensive use of jquery and many plugins are used as well. Now, on every updatepanel's postback, THE CONTROL GETS RENDERED AGAIN AND AGAIN, it loads the javascript resources again too, but doesnt call the javascript functions again. This is causing problem that many elements in my control which has to be turned in to one thing or another by jquery plugin are not working(javascript functions not calling in simple).
Now I have tried many solutions, including the ones mentioned in this question
How to have a javascript callback executed after an update panel postback?
but in vain. Previously, when my page contained only one updatepanel,
pageLoad(sender, Args);
functon was working fine, now in the case of multiple updatepanels that is not working, neither
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoaded);
function pageLoaded() { }
If you don't want your control to refresh on every UpdatePanel's postback - set UpdateMode for the UpdatePanel that hosts your control to Conditional this way it will be refreshed only when its own trigger or child control fire (Ref: http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.updatemode(v=vs.90).aspx).
That said, you don't have to manually add pageLoaded event handler on client side. Use intristic pageLoad function which fires on every page load be it via UpdatePanel or otherwise (Ref: http://msdn.microsoft.com/en-us/library/bb386417(v=vs.90).aspx)
One other way to fire a JS function is from server-side code. Every time your control loads or performs some server-side init - use ClientScript.RegisterStartupscript call to make sure JS function will be called on the client afterward, for example
ClientScript.RegisterStartupscript(this.GetType(),"myFunc", "myFunction();", true);
Ref: http://msdn.microsoft.com/en-us/library/z9h4dk8y(v=vs.90).aspx
Related
I've written a code that clears the form on every reset event like that:
$("form").on("reset", function(event) {
event.preventDefault();
$("form").clearForm();
$("#reportGenerated").empty();
});
This code is inside an external js loaded in every page so this handles the entire system.
In one specific form in my system I have three inputs that loads Ajax requests into another parts of the page, then when I try to reset and clear the form the information provided by the Ajax request isn't cleared.
So my question is, is there a way I can extend my functionality above without being forced to copy/paste what it already does?
I've read the jQuery Event Extension but does not seem to do what I need, plus, is quite "dangerous" to do it if you don't know exactly how every browser and its version handle JavaScript events.
You can easily add another click handler with will run along with this one(no need to do anything in the already existing handler).
$("form").on("reset", function(event) {
//do your custom stuff here
});
I have a couple of small javascript functions:
// Show cookie notice
$('#site-cookie-notice').slideDown();
// Hide cookie notice
$('.close-cookie-notice').click(function (e) {
if (e.preventDefault) {
e.preventDefault();
}
else {
e.returnValue = false;
}
$('#site-cookie-notice').slideUp();
});
The functions are only relevant to a single user control, that appears a maximum of once in a user visit (not at all for returning customers). The rest of the time the control is not rendered.
The above code currently resides in my global.js, inside the document.ready function, so loads every page, however it seems like this is wrong an uneccessary use of resource.
I'd be interested to know if there is a better approach to registering this code on such an adhoc basis.
You can use the ScriptManager class to register scripts in the load of your user control. This can also be used to ensure that the script isn't loaded more than once.
You can use either RegisterClientScriptBlock or RegisterClientScriptInclude depending on whether you want to provide the script in-line or have it in a separate file.
Use the ScriptManagerProxy in the user control to reference this script. That will include it on your page without having to have it on all pages.
This requires a ScriptManager or ToolkitScriptManager (if using AjaxControlToolkit) on your master page or content page. You can only have one script manager per entire rendered page.
http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanagerproxy.aspx
After searching online with multiple different keywords, I haven't been able to find the solution to my problem.
I started by looking for a way to popup a message asking for a user to renew their session a minute before it cancels. The solution I decided to use was the run a javascript timer in the masterpage and have it be called on a Masterpage.Page_Load(). In this way, whenever my user navigates from page to page, they reset the timer. However, because many of the pages the user will be using have updatepanels and update asynchronously, the function I am using is being reached, but being skipped over (according to the debugger).
The function I am using is:
ScriptManager.RegisterStartupScript(main, this.GetType(), "callTimer", "callTimer();", true);
This function runs fine on a regular postbacks, or asynchronous postbacks on the masterpage (I update the timer by doing a postback on a updatepanel in the masterpage), however, will be skipped on asynchronous postbacks.
I have tried a few things, making the control of the function Page or the UpdatePanel in the masterpage or the updatepanel in the childpages. I have tried putting this code in the childpages as well, but while these change do reset the timer, it causes the javascriptcode to run multiple times and they fight over the label displaying the countdown.
I'm really at a loss here. I think a possible solution would be to change the startupscript's control and terminate all javascripts running before that code again. However searching for a way to terminate, cancel or stop javascript functions programatically yields no useful results as well.
Another solution I would be okay with is reseting the timer on mouse movement, but since I'm designing for IE8, this will not work unless the window is out of focus.
You need to inject the script through the ScriptManager in the case of a partial postback or it will not be re-executed. Here's a utility function (vb.net) to handle the injection logic for you:
Public Shared Sub InjectScript(ByVal containingPage As Page, ByVal scriptKey As String, ByVal scriptText As String)
Dim sManager = ScriptManager.GetCurrent(containingPage)
If sManager IsNot Nothing AndAlso sManager.IsInAsyncPostBack Then
//the page is being partially-posted back by an Ajax control (e.g. UpdatePanel)
ScriptManager.RegisterStartupScript(containingPage, GetType(Page), scriptKey, scriptText, True)
Else
//standard postback
containingPage.ClientScript.RegisterStartupScript(GetType(Page), scriptKey, scriptText, True)
End If
End Sub
I found a solution to the problem: I was able to solve this by sending the current date.time as a number to the javascript function. from there I set the value of the countdown label to the date.time. there, during my timer if I found that the date.time of the label didn't match the one that the function started with, it would return and end the function. This meant that only the latest instance of the function would remain running at any given time.
My question is about using Back and Next buttons (of the browser) on an AJAX (dynamical) webpage.
The solution I self came up with:
setInterval(function(){
if (location.hash != hash)
{
hash = location.hash;
app.url = window.location.href.toString().replace('http://xxxxx.nl/xxxx/#!/','')
app.handleURL();
}
}, 500);
this function reads the url(hash) and compares it with the last stored url(hash), every 0.5 second. If url has changed (back/next is pushed) it runs handleUrl() which runs more functions to dynamically build my page.
the problem is, this sort of works BUT when I click an html [A] element or when I change the url in an other way (javascript), that content will be loaded TWICE because of the setInterval()... functionality.
How can I build my HTML/Javascript in such way that my content will always be loaded once,
once when I push back/next
once when I click on an HTML element/use Javascript functions on
runtime
I searched the sh*t out of google for a solution, plz help!
You don't need a timer to check it. Just use the onhashchange event, and fire your AJAX calls when the event is called. This event isn't supported in IE versions below 8, though, so your method seems fine if you need IE support.
Also, it doesn't make sense that they're being called twice for a elements, since there's no reason for the interval to call your AJAX loader twice just because the hash was changed using an a element. You probably have an event listener attached to the a element which causes it to load the AJAX content, which wouldn't be needed since you're detecting any change in the hash, no matter how it was changed.
I suggest using a library for that. It will be tricky to make your own solution. Take a look at these:
http://www.asual.com/jquery/address/docs/#sample-usage
http://benalman.com/projects/jquery-bbq-plugin/
I have a usercontrol that can be used in for example a gridview itemtemplate, this means that the control might or might not be on the page at page load. In the case where the control is inside an itemtemplate i will popupate the gridview via asynchronous postbacks (via updatepanels).
The control itselfs registrers scriptblocks since it is depending on javascripts. First i used
Page.ClientScript.RegistrerClientScriptBlock
But this doesn't work on asynchronous postbacks (updatepanels) so i then tried the same using ScriptManager which allows me to registrer scripts on the page after async postbacks. great!.
ScriptManager.RegisterClientScriptBlock
However, ScriptManager (what i know of) does not have the functionallity to see if a script already is on the page, so i will for every postback generate duplicates of the script blocks, this is ofcourse unwanted behaviour.
I did a run at Google and found that i can call the Dispose() method of the PageRequestManager can be used, this does work since it clears the scripts and then adding them again (this also solves my issue with removing unused script blocks from removed controls).
Sys.WebForms.PageRequestManager.getInstance().Dispose()
However, ofcourse there is a downside since im posting here :).
The Dispose() method disposes the instance on the master page as well which leads to scripts running there will stop to function after an async postback (updateprogress for example).
So, is there a way to check if a script already exists on the page using ScriptManager or any other tools, that will prevent me of inserting duplicate scripts? Also, is there a way to remove certain script blocks (when i am removing an item in itemtemplate for example).
Big thanks in advance.
Try a function like this one:
Public Sub AddScriptToCompositeScriptSafety(ByRef manager As ScriptManager, ByRef script As ScriptReference)
For Each item In manager.CompositeScript.Scripts
If (item.Path = script.Path) Then
Return
End If
Next
manager.CompositeScript.Scripts.Add(script)
End Sub
If you set the same type and key attributes when registering then I think the SM will include only one of these.