Avoid infinite loop using onload event - javascript

I'm pretty new at javascript and I've encountered a problem:
I 've a method which calls an Action through a button in my jsp page.
The thing is, I want to execute this Action immediately after loading my jsp page, without having to use the button event.
I'm trying to use the onload() event inside the body of the JSP. This does executes my Action after loading, however, it stays in an infinite loop, because it loads the page over and over again.
<script language="JavaScript" type="text/javascript">
function send()
{
document.forms['thisForm'].submit();
}
</script
....
<body onload="send()">
<html:form action="/something/foo.do?method=methodFoo" method="post">
Is there anyway to avoid this infinite loop?
Thanks a lot!

You can try AJAX to execute your action without submiting the form.

There are a number of potential ways to solve this, but I will start with the one I like the best:
BODY onLoad="window.location.href='EXAMPLE.html';" onUnload="send();"
What happens here is that the first thing it does is pass you to a new web page ("EXAMPLE.html") but it has to run your JavaScript when it is exiting. By doing this it is unable to get into the infinite loop.
Another approach:
BODY onLoad="send();window.close();"
With this one it will attempt to close the window after running your command. I am not a big fan of this because that window.close command can behave differently depending on the browser they use, and it almost always needs the individual to agree to close it. But, it might work for you.

Related

How to (correctly) add JavaScript code to a Customization Project Screen in Acumatica?

I'm trying to add a button to a customization screen in Acumatica that will run a small JavaScript function when clicked.
I am able to type the function inside a JavaScript control, which will be called from the button's Click or MouseDown events. I can also directly type the function into any of these 2 button events, without the need of the JavaScript control.
Using a basic alert("test"); for testing, I can confirm the code runs, with any of the 2 methods I described above.
The problem:
Clicking on the button doesn't run the code. Instead, the message pops up right after the screen loads, and it actually does it 2 times, so it seems the function runs automatically twice on screen load.
Is this possibly a bug? or am I doing something wrong?
Is there a "correct" way or a specific set of steps to follow in order to include JavaScript code into a Customization Screen?
Notes:
Currently testing on Acumatica 2022 R1.
I have tested this prior to and after publishing the screen, getting the same results.
Add a Javascript function in Asp:Content block:
<script type="text/javascript">
function Test() {
alert("Test");
}
</script>
Put the name of the Javascript function in PXButton ClientEvents property:
<px:PXButton ID="edTest" runat="server" CommandSourceID="ds">
<ClientEvents Click="Test" />
</px:PXButton>
It's hard to tell why alert is showing many times without looking at your code.
Check the following:
is there a JS function in script block? or just JS alert statement?
are there multiple client events? perhaps you have hooked CommandPerformed
do you declare a document ready Javascript event that could execute alert?
I suggest trying on a new page to eliminate these potential mistakes. I tested code above by modifying Sales Order page directly (SO301000) and it does produce a single alert message when clicking test button.
One possible solution would be to define the function in the javascript object as you are doing. Then on the onclick event of the button you can call the function that you defined in the javascript block. A sample of this type of code can be found in the CS206020.aspx or OU201000.aspx page. It is imperative that you use the Client Events sub element of the PXButton to set the click event to the function that you defined.

Javascript run function in background regardless the page

i need to run a function periodically regardless the page where i am. This function will get some data periodically.
I dont think that this works:
function myFunc()
{
//your code
}
//set the interval
setInterval(myFunc,2000) //this will run the function for every 2 sec.
Because it works only for the page where I am right now, so if i go to another page, function is not executed anymore.
I would like to write a function that start running when user is at index page and then is called periodically until user close the page.
Any idea? Thanks in advance!
That's not possible with javascript in the browser. When you navigate away from the page, the script will stop. You have to include a script on every page that initializes this periodical update. Or you could rewrite your application to a "single page application", which seems to be popular nowadays.
You'll need a backend application or cron-job to do that.
Another way do that would be to make an Ajax-only single page application. I guess twitter uses that model.
Depending on what your doing in the function you may be best to use a JS Worker which will run as a new thread and allow you to continue processing as much as you want in the background without having to worry about JS timeouts.
The main point here is what your asking for is near enough impossible within JS unless you use something similar to jQUery and dynamically load your pages in to a div? This would mean you still have the effect (visually) that you changing page but the browser only loads the data in.
Its very easy to in fact to load content in to a DIV using jQuery its:
$('#elementoloadid").load("/path/to/load");
You could achieve this without using jQuery but will take you longer.

setTimeout not executing the passed function

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

How to detect that document loading has started through javascript?

I want to detect when the document has just started to load, so that I can make an ajax call right away...which will determine whether I need to navigate to another page or not. I don't want to wait for the entire page to load before firing the ajax, and then, possibly navigating away from this page on the basis of the result of this ajax request.
just put code in the head of the document, no?
or at the start of the body.
<script type="text/javascript">
function pageLoad() {
// Initialization code here, meant to run once.
}
</script>

JavaScript's get-it-done nature

Is JavaScript intended to be running as little as possible on a website/webapp? By that I mean is the usual intention to run through all your js files as soon as the page loads and put them aside, and then when functions come up to execute them right away and be done with it?
I'm working on a project using google maps and I have a custom marker object scripted out, and a debugger has told me that the browser runs through all my js files before anything even appears on the page.
My problem comes in here: I wanted to animate certain markers to bounce up and down continuously with jQuery (similar to OS X icons in the dock) and my several attempts at infinite loop functions all just crash the browser. So I understand that the browser doesn't like that, but is there a way to have a simple script be repeating itself in the background while the user navigates the page? Or is JavaScript just not supposed to be used that way?
(I worked with Flash for a long time so my mindset is still there.)
Yes, Javascript functions should just do their bit and exit as soon as possible. The GUI and the scripts run on the same single thread, so as long as you are inside a Javascript function, nothing shows up in the browser. If you try to use an infinite loop, the browser will appear to freeze.
You use the window.setInterval and window.setTimeout methods to trigger code that runs at a specific time. By running an interval that updates something several times a second, you can create an animation.
You have to set a timer to execute a script after a defined time.
var timer = setTimeout(code, milliseconds);
will execute code in so-and-so milliseconds. Each execution of the script can set a new timer to execute the script again.
You can cancel a timed event using clearTimeout(timer).
Use setTimeout() or setInterval(). The MDC articles on it are pretty good.
You'll need to update inside of functions that run quickly, but get called many times, instead of updating inside of a loop.
Since you said that you are using jQuery, consider using its effects API (e.g., jQuery.animate()), it will make your life much easier!
Personally, I save as much code as possible for execution after the page has loaded, partly by putting all my <script>s at the bottom of <body>. This means a (perceived) reduction in page load time, whilst having all my JS ready to run when need be.
I wouldn't recommend going through everything you need to do at the beginning of the document. Instead, bind things to events such as clicks of buttons, etc.

Categories

Resources