4

I'm new to ASP.NET MVC 4 and I would like to add a jquery control in one of the pages of my project.

Here is the end part of my _layout.cshtml file :

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)
    </body>
</html>

1. What exactly does the @Script.Render("~/bundles/jquery") line ?

Inside the page where I want my control added :

@{
    ViewBag.Title = "Test page";
}

@section scripts
{
    @Scripts.Render("~/Scripts/jquery-1.8.2.js") // The control needs jquery.
    @Scripts.Render("~/Scripts/icarousel.min.js") // The control in question.
    @Styles.Render("~/Content/icarousel.css") // A css file needed by the control.
}

<script type="text/javascript">
    $(document).ready(function () {
        $('#icarousel').iCarousel();
    });
</script>

(some html code here, including the #icarousel div ... )

When I run that page, I get the error : '$' is undefined.

It's like jquery is not loaded or something ...

2. What am I missing to make this work ?

3 Answers 3

4

You're putting the jQuery script tag at the very bottom of the body, but trying to use it at the top of your file. Everything runs top-to-bottom, so it's trying to use something that hasn't loaded yet.

Check out the rendered HTML source to see exactly what it looks like.

You should probably render your scripts section (specifically the ones that point to javascript files rather than inline script) inside the head, rather than the body.

Sign up to request clarification or add additional context in comments.

2 Comments

I slightly modified the default _layout.cshtml template, which has the jquery rendering at the end of the body. Everybody seems to advocate that it is better to render scripts at the end, but I don't understand how it can work that way ... ?
Often you'll see people put the <script src="somefile.js"></script> tags in the head, and inline custom scripts at the bottom of the HTML. You can put everything at the bottom if you want, and it probably will run a bit faster, but it may make it confusing, especially when you start talking about complex views with layouts, partials, etc., and libraries like jQuery - you have to be very careful to put the library references above the inline scripts in the rendered HTML.
4

What exactly does the @Script.Render("~/bundles/jquery") line ?

Go to App_Start -> BundleConfig. Inside that file you'll see something like this

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
    "~/Scripts/jquery-{version}.js"));

Bundling is a new feature in ASP.NET 4.5 that makes it easy to combine or bundle multiple files into a single file. You can create CSS, JavaScript and other bundles. Fewer files means fewer HTTP requests and that can improve first page load performance

What am I missing ?

You don't need your jquery declaration on your page as @Script.Render("~/bundles/jquery") is already redering a reference to your jquery file. You should remove that.

Be sure to place any jquery code after library reference.

Comments

2

@Scripts.Render("~/bundles/jquery") is mechanism of asp.net mvc 4 that bandles and minifies your scripts.

Try to relocate @Scripts.Render("~/bundles/jquery") as high as possible between head tags. Something like this on your _Layout.cshtml:

<head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
        @Scripts.Render("~/bundles/jquery")
    </head>

3 Comments

It works that way, thanks. But, why does the default template has that line at the end of the body ?
It's optimisation for page loading because browser renders all code line by line - scripts are optimal to load in the end of body.
Take a look at this article: developer.yahoo.com/blogs/ydn/…

Your Answer

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