0

As recommend by various performance optimization tools my webpages all include the JQuery reference at the end of the page. Lately, I've been introducing JQuery code into my partial views. Since JQuery is not referenced yet, how can I use JQuery throughout my page in partial views?

UPDATE: Here's something I'm trying to do. This is in a partial view.

@model pending.Models.WidgetZone
<fieldset id="fieldset_Available-Widgets_@(Model.Slug)" class="available-widgets">
    <legend>@i18n.widgets_availableWidgetsList</legend>
    @Html.Action(MVC.Admin.WidgetFramework.Select(Model.Slug))
    @{
        string ddlId = "#select_Available-Widgets_" + @Model.Slug;
        string pageId = ViewContext.RouteData.Values["id"].ToString();
    }
    <p>
@*      <input type="button" value="@i18n.widgets_AddWidget" id="btn_AddWidget_@Model.Slug" onclick="pending.widgetAdmin.addWidget($('@ddlId').val(), '@Model.Slug', '@pageId')" />*@
        <input type="button" value="@i18n.widgets_AddWidget" id="btn_AddWidget_@(Model.Slug)" />
    </p>
</fieldset>

@section js_placeholder {
<script type="text/javascript">
    $('#btn_AddWidget_@(Model.Slug)').click(function () {
        pending.widgetAdmin.addWidget($('@ddlId').val(), '@Model.Slug', '@pageId');
    });
</script>
}

As you can see I have some JQuery selecting code in there that requires JQuery in the <head> of the page. I've already tried implementing Darin's suggestion (see @section) but it doesn't render anything.

mare
  • 13,033
  • 24
  • 102
  • 191
  • I faced the same issue. The only workable solution I have is to just have jQuery included in the `head` tag. The other way would be to come up with your own mechanism/helper of registering Script Blocks where you insert the scripts dynamically at runtime or render time after jQuery script tag. I think having jQuery as the exception is a good tradeoff. – Mrchief Aug 10 '11 at 14:48
  • Apparently this is a no-go as described here http://stackoverflow.com/questions/5355427/populate-a-razor-section-from-a-partial – mare Aug 10 '11 at 16:21

2 Answers2

0

Include the jQuery code in the _Layout, just before the closing </body> tag. Partials shouldn't be including any jQuery or javascript code. Add a section in your layout just after the jQuery inclusion and in all pages override this section to include the necessary scripts.

As an alternative you could write some helpers as shown in this answer. It is not something I would recommend but it could be a workaround.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • This is close and I did create my section declaration then override it in my partial file. However it doesn't work - nothing gets rendered. I think it must be because one can only override sections in view pages. – mare Aug 10 '11 at 16:01
  • i've updated my question to provide some visual clues what I'm doing – mare Aug 10 '11 at 16:02
  • @mare, you cannot override sections in partials, you should override them in the views including the partials. – Darin Dimitrov Aug 10 '11 at 16:21
  • This will cause an error if you have jQUery related `$(function() { /* ... */})` code in your partial view. Since the view will render ahead of jQuery script include, browser complains about undefined symbol '$'. – Mrchief Aug 10 '11 at 17:25
  • @Mrchief, that's why I said that there should not be any jQuery or javascript in partial views. Javascript should be included in the main view (NOT partial view) as an overriden section. – Darin Dimitrov Aug 10 '11 at 17:27
  • Well, so how should the JS for partial view be handled? PArtial view with just markup would be pretty powerless - not always though, but having no JS limits their application. Or is there some other way? – Mrchief Aug 10 '11 at 17:33
  • @Mrchief, a partial is included in a view, so it is this view's responsibility to include the javascript files required by the partial (they would be separate javascript files of course to avoid cluttering the markup). – Darin Dimitrov Aug 10 '11 at 17:36
  • Let me illustrate with an example: Let's say my partial view uses a plugin. I want to include plugin init code on document ready. How do I go about then? I don't want any view to be aware of the plugin, nor any code relating to it. – Mrchief Aug 10 '11 at 17:40
  • @Mrchief, the view is already aware of the fact that it includes a partial, so it should also include any required (javascript) files by this partial. There is a dirty way to do this by writing a helper method (I have already shown this somewhere on SO, can't find it where at the moment) but I wouldn't bother searching it as it is ugly and not something I would recommend. – Darin Dimitrov Aug 10 '11 at 17:45
  • Even this: `$(function(){ plugin.init(); })`? – Mrchief Aug 10 '11 at 17:46
  • @Mrchief, that's not something I would put inside a view. That's javascript and javascript code belongs into separate javascript files. Views are for MARKUP and nothing more. – Darin Dimitrov Aug 10 '11 at 17:47
  • 1
    I have found it, here's the link: http://stackoverflow.com/questions/5433531/using-sections-in-editor-display-templates/5433722#5433722 – Darin Dimitrov Aug 10 '11 at 17:50
  • Darin, while I understand your concerns about not putting JS code into partials, the partials I am currently working on are based on some Model instance that contain their IDs and other properties and those properties have to be embedded inside my JS code, for instance I have a widget with an ID of type Guid and when I create HTML tag for this widget it's id attribute is comprised of this GUID and some other characters. It would be an overkill to even try to get this into external JS file. That's why I have it alongside the View HTML. For now, I just moved JQuery referenced back into tag – mare Aug 10 '11 at 23:21
  • @mare, did you checkout the helper in the linked post? Also instead of using id selectors can't you use class selectors and thus externalize the javascript? – Darin Dimitrov Aug 11 '11 at 08:51
  • thank darin, your helpers could work. No, I cannot use class selectors because we are manipulating widget zones. Each one is unique. If I used class selectors, I'd be working with all of them. – mare Aug 11 '11 at 09:32
  • @mare, can't you apply the class only to elements that you are willing to manipulate? – Darin Dimitrov Aug 11 '11 at 09:37
0

I read about an extension/helper library for jQuery that covered exactly your problem, but can not remember which one :-(

Perhaps: http://aboutcode.net/knapsack/

There are some 'Scriptmanager' nuget packages that go in the same direction.

Or another possibility: http://assman.codeplex.com/

Rudi
  • 3,124
  • 26
  • 35