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.
Related
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
I'm working on a simple interface for testers to use, which I'm writing as an HTML page. What I need to do is open a specific URL when the user presses a button (the URL triggers a Hudson/Jenkins job on another server). Here is the code I'm using to accomplish this:
function triggerJob() {
var url = "...";
var trigger = window.open(url);
setTimeout(function() {trigger.close();}, 1000);
}
A couple of notes:
I know this a bad way of accomplishing what I want to do. I have already implemented the solution using jQuery, and for some reason the job on the Hudson server does not get kicked off when querying the URL in that way. The weird thing is that when I query it using a Ruby script from the same machine, it works just fine.
I have to do the timeout because if I just open the window then immediately close it, the browser does what it is supposed to, but it's too quick for the Hudson server to register it and start the job.
I have tried putting other statements besides trigger.close(); inside the anonymous function, and they are not executed either. There is no question that setTimeout is not executing the block it is supposed to be.
Thank you for any help you may be able to give me. I have been toying with this for hours and cannot figure out why my code is not doing the timeout right.
figured out this problem in the course of doing something else, so I thought I'd share the solution in case anyone else has the same problem. The issue was that I was calling this function using the onClick attribute of a submit button in a form. When the form is submitted it calls the function, and then the page is immediately reloaded after the function executes, which cancels the timeout that was set in the triggerJob function. You must use a link, radio button, etc. if you want to use setTimeout in this manner. Thanks for everyone who tried to help me.
Drew
When injecting a div server-side from ASP.NET (using .Visible), is it possible that my pages are occasionally being redirected by the server before the javascript in the injected div block finishes executing? If so, how can I prevent a server-side redirect from occurring before my client-side code is done running?
Specifics of my issue:
I needed a quick solution to conditionally track google conversions on ASP.NET pages right before a redirect. I ended up creating an invisible div for each conversion, and when the submit button was clicked, the correct div block would be made visible from the code-behind, and then the rest of the code would process. A redirect is occasionally only a few lines of code away.
After a few weeks of monitoring the numbers, some aren't adding up properly. For example, on a page that cannot be accessed without a previous conversion happening, I'm getting more conversion on the inner page than the outer (which should not be possible). To make sure this div code was executing every time a submit button was clicked, I added a javascript alert as the last line and it did pop up for me every single time. Even after this testing, though, the only logical explanation I can come up with is that the redirect is occurring before the client-side javascript code fully executes. Since the redirect is happening server-side, these run independently of each other.
This will be extremely unreliable. Most likely the tracking is loading an external script or img. As soon as the redirect begins all active requests from the current page are aborted.
If you must track when the user leaves the page I would try some sort of intermediate tracking landing page, or actually encompass all of the tracking code in the submit client function.
In the latter you would have to load the script/image and only process the submit once the onload callback fires.
Hope this helps.
My VB.NET code is supposed to execute third party Javascript code in an attempt to fill in and submit a form. This process consists of five steps, and I have been able to submit the form when all the steps are kept separate (i.e. behind 5 separate consecutive button clicks). Now, what I'd like to have is one button to handle all the five steps.
The problem is that the form originally only appears after calling "webbrowser.Navigate" command, which apparently modifies the page's HTML code. I seem to be unable to detect when Javascript has finished loading the new HTML in order to fill and submit the form. I have tried a timer control to wait for a certain HTML element ID to appear, but in vain.
This question has been asked before in different forms, but at least I could not find much help from the earlier answers:
InvalidCastException with WebBrowser.IsBusy or ReadyState (VB .NET)
Detect when AJAX changes HTML in a DIV in WebBrowser
http://www.techtalkz.com/vb-net/374234-vb-net-webbrowser-control-how-capture-javascript-events-statusbar-changed-mouseclick-etc.html
Please help me.
Well, this is the way it normally works in the software industry: Only after you've explained the problem to others, are you in a position to sufficiently understand it - and solve it yourself.
The problem was that I had not been using System.Windows.Forms.Timer() but another (less suitable) timer class for tracking changes in the HTML code. This was the reason why Application.DoEvents() did not work. With System.Windows.Forms.Timer() I was able to create a Timer.Tick event that keeps track of the phase of the form submittal (1-5 in my example) and attempts to execute the required Javascript commands in a Try-Catch construction. If an exception is caught, Application.DoEvents() is executed instead, and the timer ensures that the same commands are attempted to be executed shortly again.
This seems to work for me.
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.