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

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 Ex-Fanboy Munich 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.