1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Requiring javascript in overlay templates

Discussion in 'XenForo Development Discussions' started by RichardKYA, Sep 4, 2016.

  1. RichardKYA

    RichardKYA Well-Known Member

    Having trouble getting js files to work when used in overlay templates, they work perfectly fine in all other templates, but overlay templates seem to be an issue.

    The scripts work fine in an overlay template if it's not minified and it's added directly in template, but as soon as I require them via xen:require, minified or not minified, boom, it doesn't work.

    I can't get my head round what the issue is, when looking in the console, it appears that the scripts are being loaded in the wrong order, and this continues to happen regardless of what order I actually require them in. BUT even with that said, I can require them in any order in all other templates and it still work perfectly fine, it's just overlay templates that seem to be an issue.

    Anyone have any insight on why this might be happening?

    Thank you in advance :)
    Last edited: Sep 4, 2016
  2. Mike

    Mike XenForo Developer Staff Member

    When scripts are loaded after the page is loaded, they're loaded and run asynchronously. That means they don't have a deterministic order. You'll need to detect whether what you want has loaded and delay your action if needed.
  3. RichardKYA

    RichardKYA Well-Known Member

    I'm not sure how to do that, to explain my issue a bit further:

    script 1 - defines functions, etc.
    script 2 - modifies these functions, etc.

    script 2 keeps being loaded before script 1 when required in overlays, obviously this causes it to "break" because the modified functions have not yet been defined because script 1 has not yet loaded.

    I can only modify script 2 because script 1 is an external source.

    How can I delay script 2 from loading until script 1 has loaded?
  4. CyberAP

    CyberAP Well-Known Member

    Use load event in document: document.addEventListener('load', function() { /*your code*/ });
    One thing to notice: it waits for all resources to be loaded.

    You can try another approach and trigger your custom event in the end of your script. Then use this event in your second script to launch.

    More detailed:

    For script 1
    // All your code
    For script 2
    $(document).one('scriptOneLoaded', function() {
      // All your code
  5. RichardKYA

    RichardKYA Well-Known Member

    Thank you @CyberAP for the suggestions, but I've just tried those and they don't work either :(

    Nothing seems to work when it comes to these damn overlay templates

  6. Nobita.Kun

    Nobita.Kun Well-Known Member

    In the first your file Javascript1. Using this:
    XenForo.loadJs('src_of_js', function() {
         // TODO when the JS loaded
  7. RichardKYA

    RichardKYA Well-Known Member

    Thank you for the suggestion @Nobita.Kun, but unfortunately, script 1 is a 3rd party source, so ideally I don't want to be making any edits to it. Modifications happen in script 2 so that script one doesn't have to be tampered with.

    I didn't think it would be this hard to get some js working in an overlay template, I thought it would work just like any other template lol
  8. Nobita.Kun

    Nobita.Kun Well-Known Member

    I dont say that you edit the third party source. Just put in your javascript file.
    RichardKYA likes this.
  9. RichardKYA

    RichardKYA Well-Known Member

    Sorry, I misunderstood what you meant :rolleyes:

    I have it working now using your example (y)

    At the moment though, it works fine because I know the file directory structure, but when adding the path to the "src_of_js", is there a way to get the path when you don't know what it is?

    For example, someone may have their directory set up like....


    ...and someone else may have...


    Is there a way to have something like:

    var scriptDirectory =  some code here to get directory
    XenForo.loadJs('scriptDirectory + "script-1.js"', function() {
        // TODO when the JS loaded
    Or something to that effect?

    I'm having a look for a solution and it does seem like it is possible, but the methods I have found end up breaking again when used in an overlay.

    Anyway, thank you for all your help guys, after 2 and half days, I think things are finally starting to move forward. Hurray! (y)
    Last edited: Sep 7, 2016
  10. Nobita.Kun

    Nobita.Kun Well-Known Member

    If you want js of each user then bypass it through template. Like this
    <div class="someClass" data-js="js_of_user">...</div>
    Then in your script use this:
    Var externalJs = $('.someClass').data('js');
    XenForo.loadJs(externalJs, ....)
    It is for per user setting.
  11. RichardKYA

    RichardKYA Well-Known Member

    I'm not sure I understand what you mean? What goes in place of "js_of_user"?
  12. cclaerhout

    cclaerhout Well-Known Member

  13. RichardKYA

    RichardKYA Well-Known Member

    OK, I've been making progress on this, but I've now hit another wall, so I need to request some help again...

    To build the path to js file location, I am passing the board url via a hidden input:

    <input type="hidden" name="boardurl" value="{$xenOptions.boardUrl}" />
    ...and then in my js file:

    var boardUrl = $("input[name=boardurl]").val() + "/path/to/js/file.min.js";
    ...I've tried doing the same thing but various ways in my js file, but the result is always the same, which is, immediately after the boardUrl portion, an "undefined" folder is being added, so instead of...


    ...I am getting...


    I've checked in the ACP > Basic Board Information and there is no trailing slash or anything there that shouldn't be, so I have no idea where this "undefined" is coming from or why it is being added :confused:

    Does anyone have any ideas?

    Thank you
  14. Mike

    Mike XenForo Developer Staff Member

    I'm not totally clear on what's happening or what you're needing specifically, but XenForo.canonicalizeUrl() might do what you need without passing things in. Don't use a leading slash on your path though unless it's at the root or your domain.
    RichardKYA likes this.
  15. RichardKYA

    RichardKYA Well-Known Member

    Thank you Mike, that done exactly what I needed (y)

Share This Page