0

I think Sitecore devs may have experienced this and hence posting here.

I would like to add Javascript methods in a view. But jQuery is referred in the body tag at the end (moving to head is not an option). So, there is a $ undefined error on page load.

@{
    Layout = null;
 }
    <div>
    ....
    </div>
<script>
   $(document).ready(function(){
       $("#btn").click(function(){
            doSomething();
       });
       doSomething();
   });

   function doSomething(){
       alert();
   }
</script>

Things I have tried:

  1. Enclosing the script tag inside @section Script {}. There is no error in console but the alert is not triggered.
  2. Added @RenderSection("Scripts", required: false) in the layout file. It throws an error that - "layout.cshtml cannot be requested directly because it calls the "RenderSection" method".
  3. I never had the need to add Layout path in a view and always set it to null. As there was an error in step2, I specified the layout path in the view. Now there is an error about recursive rendering reference.

How can I add JS methods in the view, with jQuery still in the body tag.

2
  • 3
    Do you really need to add this to the view? Why not add it to a JS file that loads after jquery and target your selector using a css class or data attribute?
    – jammykam
    Commented Aug 14, 2020 at 14:08
  • @jammykam This view all the functionality related this module will be at one place. There are many JS already loading in the page and do not add one more specific to this module.
    – sukesh
    Commented Aug 16, 2020 at 12:39

2 Answers 2

2

The easiest method would be to remove your dependency on jQuery and just write vanilla JS. There are a lot of benefits to this, while jQuery used to be really useful, there is very little reason to use it in modern websites.

Take your example:

<script>
    $(document).ready(function(){
        $("#btn").click(function(){
            doSomething();
        });
        doSomething();
    });

    function doSomething(){
        alert();
    }
</script>

Without jQuery:

<script>
    var ready = (callback) => {
        if (document.readyState != "loading") {
            callback();
        }
        else
        {
            document.addEventListener("DOMContentLoaded", callback);
        }
    }

    ready(() => {
        const btn = document.getElementById("#btn");
        btn.addEventListener("click", function() {
            doSomething();
        });
        doSomething();
    });

    function doSomething(){
        alert();
    }
</script>

Sure its a bit more verbose, but problem instantly solved without any hacky timeouts or loading the framework at the top of the page.

1

We faced the same issue while working, so we came up with this solution. Although there can be a better solution than this, we tried this and it worked for us -

<script type="text/javascript">

        var waitForJQuery = setInterval(function () {
            if (typeof $ != 'undefined') {                    
                clearInterval(waitForJQuery);
                // Do your stuff here                       
            }
        }, 10);
    </script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.