Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Javascript to run after page load

Hi,

I am writing a plugin with a form and an input field

<input type="file" id="inputfile" />

I also wrote some javascript with the first line as

var control = document.getElementById("inputfile");

I verified the javascript works:

https://jsfiddle.net/qyvzsvq8/

And then I save it as a .js file in my plugin's "js" folder. But I can't seem to get it working in the Vanilla plugin. Here's what I do:

  1. At the appropriate place, I put echo <input type="file" id="inputfile" />. The button shows up on the page correctly.
  2. Inside Base_Render_Before, try to call the javascript using $Sender->AddJsFile('script-input.js','plugins/ScriptRepoPlugin');. However, this throws an error -- the line var control = document.getElementById("inputfile"); returns null.

I did some digging and this can happen if the javascript is run before the page is loaded. Some people suggested to wrap the .js in

jQuery(document).ready(function($){ ... });

It doesn't work.

Some people suggested to wrap the .js in

window.onload = function() { ... }

It doesn't work.

Some people on Vanilla forums site suggest to run this code:

function YourFunctionHere(&$PageEnd) { 
    echo '<script type="text/javascript" src="js/filename.js" />'."\n";
}
$Context->AddToDelegate('PageEnd', 'PreRender', 'YourFunctionHere');

But I can't figure out where to put this code. I tried putting it between the $PluginInfo definition and the class definition i.e.class MyPlugin extends Gdn_Plugin {...}, but apparently that is the wrong place.

Gah. Any ideas? I simply want the javascript to run AFTER the page is loaded.

Tagged:

Comments

  • @R_J,

    WOW! Solved all my problems and then some!

    However I have a related question.

    For a different purpose, I need to run javascript code after the page loads on the new discussion page (i.e. not on a custom form). I took your working code and tried to make it work inside, say, the PostController_BeforeBodyInput_Handler function.

    Inside that function, I tried echoing the relevant html content, and I tried inserting a line saying $Sender->Render(parent::getView('form.php'));. Both ways actually work in terms of showing the content -- i.e. I can get the elements to show up and they all have the correct html attributes.

    However still I have the original problem -- the line var control = document.getElementById("inputfile"); (referring to the original post in this thread) returns null. Therefore the javascript is still running before page load, not after. So it cannot find the id='inputfile' attribute because it does not exist at javascript runtime.

    How do I get some javascript to run after page load, on the New Discussions page not a custom form?

    Is it possible?

    Thanks mucho!

  • R_JR_J Admin

    The answer, again, is:

    $(document).ready(function() {
        alert('This is executed after all elements are available.');
    });
    

    I guess the ID is not "inputfile". Look at the generated HTML source of a new discussion page for the ID.

    I have two thoughts when reading your answer:
    First one is just a matter of style. I prefer adding JavaScript not at some event, but at "the first event for the page". This would always be someController_render_before. It feels to me like the head of the page and that's where the script tag will be in the end. But I guess there is no "correct" event for doing so.

    The second thought is "WTF? A form in a form!?" I don't know what you are trying to do, but adding a form inside a form is simply wrong. If you tell us what the purpose of all this is, we might be able to come up with a better solution.
    Extending an existing form is actually quite simple.

Sign In or Register to comment.