4

In ASP.NET MVC, what is the preferred pattern for running Javascript on a partial view that is loaded via Ajax?

For example, suppose you need to wire up some click events in your partial view.

Of course, putting something like this in the partial view would not work, because the document ready event won't fire after the partial view is Ajax loaded.

<script type="text/javascript">
    $(function() {
        $("a.foo").click(function() {
            foo();
            return false;
        });
    });
</script>

I suppose something like this might work, but is it safe?

<script type="text/javascript">
    $("a.foo").click(function() {
        foo();
        return false;
    });
</script>

The pattern I have been using has been to run any Javascript from my parent view after loading the partial, like this:

$.get(url, function(html) {
    $("#partialDiv").html(html);

    // Now that the partial has loaded...
    RegisterClicks();
});

But I've been working through this example, and noticed that they simply put their click registering code inline in the partial view.

Is this a generally safe pattern to adopt? How can I be sure that the DOM for the partial view has finished loading before my script runs?

Eric
  • 5,842
  • 7
  • 42
  • 71
  • this is a good question. hopefully this post will help http://stackoverflow.com/questions/3619484/can-i-add-javascript-dynamically-to-an-existing-script-element and this http://www.hunlock.com/blogs/Howto_Dynamically_Insert_Javascript_And_CSS – Dave Alperovich Feb 12 '13 at 18:17
  • 1
    Either I do your second example, have had no problems, but I avoid it because if the partial repeats then the javascript is repeated unnecessarily and is also not minified. Instead I put javascript in an external *.js file and parent pages must include it(and thus if the parent page includes via a bundling/minifying framework it gets minified). I wish Partials had some sort of OnLoadJavascript or supported sections, but unfortunately they don't. – AaronLS Feb 12 '13 at 20:40
  • We really need this: http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/2204831-be-able-to-use-cumulative-section-declaration – AaronLS Feb 12 '13 at 20:41
  • @AaronLS, if I can ask, as a matter of style, would you have a separate js file for each partial? Or one js file that contained code for all partials? – Eric Feb 13 '13 at 20:32
  • 2
    @Eric Generally one per partial, but sometimes I have a partial page like "_AccountManager.cshtml", which in turn uses a few other child ajax partials like "_AccountTypeSelector.cshtml" for interactive parts of that page. Since that group of partials are always used together under _AccountManager.cshtml, I would have one AccountManager.js that holds all the javascript code for those closely related partials. – AaronLS Feb 13 '13 at 20:38

2 Answers2

4

The jQuery .on() function should do the trick, shouldn't it? It should work for dynamically added content.

Have this available as part of the full content

<script type="text/javascript">
    $(function() {
        $("#partialContent").on("click", "a.foo", function() {
            foo();
            return false;
        });
    });
</script>

<div id="partialContent">
   <a href="#" class="foo">Link 1</a>
   <a href="#" class="foo">Link 2</a>
   <!-- More dynamic content -->
</div>
Brett
  • 1,140
  • 10
  • 16
  • are you sure JQuery.on() will make rendered javascript executable? – Dave Alperovich Feb 12 '13 at 19:37
  • Perhaps I have misunderstood the question? I thought Eric was asking how to wire up events to dynamic elements, those added after the DOM had loaded. – Brett Feb 12 '13 at 19:49
  • Possibly. I though the question involved adding javascript to a rendered DOM and assuring that it will be recognized by the browser as new code. – Dave Alperovich Feb 12 '13 at 19:52
  • @Dave A, I shall leave it available until Eric provides some feedback, if I have then I shall delete the proposed answer. – Brett Feb 12 '13 at 19:55
  • @DaveA has it right - I'm interested in the best way to execute Javascript after loading something into the DOM. If I executed some Javascript that used `on` for all `a.foo`, and then I subsequently loaded some new `a.foo` elements into the DOM, I'd still need to execute more Javascript to wire up the new elements, right? – Eric Feb 12 '13 at 20:35
  • As I understand, the on method will pick the dynamically added elements after the DOM has loaded. – Brett Feb 12 '13 at 20:39
  • 2
    Yes, as long as `#partialContent` exists on the parent page, then any dynamic `a.foo`'s will get wired up. Since this code is specific to the partial though, I'd move it to it's own js file, the parent page would still include that script, but that way it can be minified, externalized, and reused on any parent page that leverages that partial view. – AaronLS Feb 12 '13 at 20:45
  • "Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to `.on()`" - http://api.jquery.com/on/ – Eric Feb 12 '13 at 20:45
  • 1
    @Eric, the elements would exist. I've created a very simple [fiddle](http://jsfiddle.net/BftZU/1/) to demonstrate that it works. – Brett Feb 13 '13 at 09:43
  • 1
    As @AaronLS mentions, drop the javascript code into it's own .js file that can be included onto any other views that required links wiring up in the same way, as well as the other added benefits described. Hope this helped anyway, mark it as the answer if you wish. – Brett Feb 13 '13 at 19:24
  • 2
    @Eric The element that has to exist is the items selected on the left hand side of .on, the "a.foo" selector on the right hand can be dynamically created. Basically what is happening is you are wiring an event up to `#partialContent` that says "watch for events that bubble up from a.foo". It's also more efficient for scenarios where you might have thousands of elements, such as `td`'s in a table, because instead of wiring up to thousands of `td`'s(which would create thousands of event handlers) you wire up to a single parent element and let the events bubble up. – AaronLS Feb 13 '13 at 20:05
0
Scripts are not loaded on Partial view via partial view loaded by ajax in Asp.net MVc 

 <div class="modal fade" id="myEditCourseModal" role="dialog">
            <div class="modal-dialog modal-lg">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal">&times;</button>
                        <h4 class="modal-title text-center">Update Data</h4>
                    </div>
                    <div class="modal-body" id="CourseEditPreview">
                        @Html.Action("CourseUpdatePartial", "AdminCourse")
                    </div>
                </div>
            </div>
        </div>

<script type="text/javascript">

    function OpenCourseEdit(currentId) {
        $.ajax({
            type: "Get",
            url: '@Url.Action("CourseUpdatePartial", "AdminCourse")',
            cache: false,
            Async: true,
            contentType: 'application/html;charset=utf-8',
            dataType: "html",
            data: { CourseID: currentId },
            success: function (data) {
                var content = $('#CourseEditPreview').html(data);
                eval(content);
                $('#myEditCourseModal').modal('show');
            },
            error: function (error) {
                $("#LoadingPanel").css("display", "block");
                $('#CourseEditPreview').html("");
            }
        })
    }
</script>
  • If you're posting an answer, try to explain why your solution works or is better – Red Sep 28 '18 at 09:53