4

I'm working on ASP.NET MVC 5. I have a viewstart.cshtml and imported the reference for my jquery like this

<!-- jQuery and Bootstrap JS-->
<script src="~/Scripts/jQuery/jQuery-2.1.4.min.js"></script>
<script src="~/Scripts/Bootstrap/js/bootstrap.min.js"></script>

In my view for HomeController I have alert function on document ready but there is an error that says $ is not defined.

But when I import the jquery directly to the view of my HomeController, it works fine. Why is that? The view of my HomeController is actually using the viewstart.cshtml that has the reference for jquery. Am I doing the correct way to import all my js/css files in Layout.cshtml? thanks for any help

In my View for HomeController if I reference the jquery directly, there is no error and it's working fine. But I want to do it once so all of the views don't need to reference it.

see below code:

@{
    ViewBag.Title = "Welcome";
} 

 <script src="~/Scripts/jQuery/jQuery-2.1.4.min.js"></script>

 <script>
    $(function () {
        alert("hello francis!")
    })
</script>

<h2>WELCOME !!</h2>
Andrey Korneyev
  • 26,353
  • 15
  • 70
  • 71
Francis Saul
  • 728
  • 2
  • 16
  • 37

4 Answers4

10

It looks like you're loading your custom scripts before jquery.

Make sure you have something like this in Layout.cshtml (not _ViewStart.cshtml) somewhere between @RenderBody and </body>:

<script src="~/Scripts/jQuery/jQuery-2.1.4.min.js"></script>
<script src="~/Scripts/Bootstrap/js/bootstrap.min.js"></script>
@RenderSection("scripts", required: false)

and in the view you have to include your scripts into scripts section like:

@section scripts {
    <script> 
       //your custom scripts here
   </script>
}

This will ensure you that jquery will be loaded before your scripts.

Anything placed into section in the view will not be rendered during view render in RenderBody, and will be rendered only in RenderSection.

So jquery is loaded first in layout file, and only then section from the view containing your custom scripts that uses jquery being rendered.

Dejan
  • 9,150
  • 8
  • 69
  • 117
Andrey Korneyev
  • 26,353
  • 15
  • 70
  • 71
  • I tried your code but it gives this error : The following sections have been defined but have not been rendered for the layout page "~/Views/Shared/_Layout.cshtml": "script". – Francis Saul Jan 28 '16 at 07:42
  • Check the name of section. It looks like you've typed it as "script" not "scripts" in the view. – Andrey Korneyev Jan 28 '16 at 07:44
2

usually you should use bundling to get jquery working. inside the App_Start folder there's a file called BundleConfig.cs. Place the required jquery libs inside your scripts folder and update the bundle config file as follows:

public static void RegisterBundles(BundleCollection bundles)
{
        // The jQuery bundle
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        //"~/Scripts/jquery-1.9.1.*",
                        "~/Scripts/jquery.min.js"
                        //"~/Scripts/jquery-ui-1.10.2.custom.js"
                        ));

bundles.IgnoreList.Clear();
bundles.IgnoreList.Ignore("*.intellisense.js");
bundles.IgnoreList.Ignore("*-vsdoc.js");
bundles.IgnoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
}

in your Layout.cshtml right in the <head> tag area place the following piece of code to render your bundles defined:

@Scripts.Render("~/bundles/jquery")

You should now be able to use jQuery as expected.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
pavemann
  • 384
  • 1
  • 3
  • 9
  • this seems great! but can you explain what does it mean by the ff codes: bundles.IgnoreList.Clear(); bundles.IgnoreList.Ignore("*.intellisense.js"); bundles.IgnoreList.Ignore("*-vsdoc.js"); bundles.IgnoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled); – Francis Saul Jan 28 '16 at 07:46
  • there is error says The 'Scripts' doesnt exist in the current context. When I put this @Scripts.Render("~/bundles/jquery") in the Layout.cshtml that error pops out. – Francis Saul Jan 28 '16 at 07:54
  • .IgnoreList.Ignore simply means that all files which contain .intellisense.js, vsdoc.js etc. will not be included into the bundle to get rid of the error "The Scripts does not exist in the current context: within the reference folder you need to add the reference "System.Web.Optimization" – pavemann Jan 28 '16 at 08:09
  • But what happens when you need jQuery at the Layout level, but you want a JS file (that depends upon jQuery) to be only used by a single page (not included everywhere)? – Developer Webs Aug 17 '17 at 14:08
1

This line:

<script src="~/Scripts/jQuery/jQuery-2.1.4.min.js"></script>

runs on the client's end.

The tilde (~) is the way to get to the server's root directory.

You can use url's with a tilde(~) on you server (e.g. using Server.MapPath) but they shouldn't be used on the client's end.

You can either create a relative url or an absolute url on your client, but don't use the tilde (~).

Your error ($ is not defined) means that JQuery has not been loaded. Either:

  1. You didn't load JQuery correctly - check you url (easy to with the dev tools).

  2. You are using the JQuery before it was loaded.

Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
  • 2
    Frankly, it is pretty valid to use tilda sign in the views in scripts addresses since it will be correctly handled during view rendering. In your sample this tilda will be just removed and path mentioned will be sent to client as `/Scripts/jQuery/jQuery-2.1.4.min.js` – Andrey Korneyev Jan 28 '16 at 07:26
0

Go to Views/Shared/_Layout.cshtml and move this piece of code:

@Scripts.Render("~/bundles/jquery")   
@Scripts.Render("~/bundles/bootstrap")  
@RenderSection("scripts", required: false)

from the body tag to the head tag and that should look like this:

...
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")/
    @RenderSection("scripts", required: false)
</head>
...

...For me personally that worked out fine, there is no more need to embed direct references to jquery in each html page.

Eugene
  • 1
  • 3