233

How do I render the partial view using jquery?

We can render the partial View like this:

<% Html.RenderPartial("UserDetails"); %>

How can we do the same using jquery?

Custodio
  • 8,594
  • 15
  • 80
  • 115
Prasad
  • 58,881
  • 64
  • 151
  • 199
  • You could have a look at below article as well. http://www.tugberkugurlu.com/archive/working-with-jquery-ajax-api-on-asp-net-mvc-3-0-power-of-json-jquery-and-asp-net-mvc-partial-views It follows a different approach and enhances the way. – tugberk Sep 09 '11 at 21:34
  • Stupid question. Is UserDetails a partial view as a cshtml page: UserDetails.cshtml? I am trying to load a partial view . And normally I would use: @Html.Partial("~/Views/PartialViews/FirstPartialViewTwo.cshtml") – George Geschwend Jan 04 '18 at 03:39
  • 3
    @GeorgeGeschwend, Nothing is stupid here, till someone can respond to it. UserDetails(UserDetails.cshtml) is the Partial View inside the User Controller. As in the comments of the marked answer, its better to use Url.Action instead of hard coding the full path of the view. – Prasad Jan 11 '18 at 13:35

8 Answers8

302

You can't render a partial view using only jQuery. You can, however, call a method (action) that will render the partial view for you and add it to the page using jQuery/AJAX. In the below, we have a button click handler that loads the url for the action from a data attribute on the button and fires off a GET request to replace the DIV contained in the partial view with the updated contents.

$('.js-reload-details').on('click', function(evt) {
    evt.preventDefault();
    evt.stopPropagation();

    var $detailDiv = $('#detailsDiv'),
        url = $(this).data('url');

    $.get(url, function(data) {
        $detailDiv.replaceWith(data);         
    });
});

where the user controller has an action named details that does:

public ActionResult Details( int id )
{
    var model = ...get user from db using id...

    return PartialView( "UserDetails", model );
}

This is assuming that your partial view is a container with the id detailsDiv so that you just replace the entire thing with the contents of the result of the call.

Parent View Button

 <button data-url='@Url.Action("details","user", new { id = Model.ID } )'
         class="js-reload-details">Reload</button>

User is controller name and details is action name in @Url.Action(). UserDetails partial view

<div id="detailsDiv">
    <!-- ...content... -->
</div>
R K
  • 133
  • 12
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • I keep getting bad request with this example code your gave. I copied as is and just changed the Controller action it should go to. I am not sure what "user" is for. – chobo2 Nov 08 '09 at 05:55
  • 1
    I just used some "likely" controller and action names since you didn't include any code that we could go by. Just replace "details" with your action and "user" with your controller name. – tvanfosson Nov 08 '09 at 13:04
  • any idea how this would work with Razor? tried $.get( "@Url.Action(\"Manifest\",\"Upload\", new { id = " + key + " })", function(data) { $("
    ").replaceWith(data); } );
    – Patrick Lee Scott May 24 '11 at 19:23
  • @Patrick - I'd use single quotes (double is harder to read) for the JS. Regardless you don't need to "quote" the quote characters or construct a string -- just let the UrlHelper do it's work. See my updated example. – tvanfosson May 24 '11 at 19:28
  • Works awesome thanks! Why is it caching the Partial View? In my partial view I'm simply outputting the current date and time. – Rick Glos Jan 06 '12 at 13:52
  • My bad, the issue was that the element was replaced and was no longer available for replacement the second time. – Rick Glos Jan 06 '12 at 14:23
  • Superb solution. And fixed a treeview state issue for me – Israfel Jul 06 '12 at 20:11
  • Looking at the supplied Controller code - Any chance the 'Partial' is supposed to be 'PartialView'? I'm getting an error as described here: http://stackoverflow.com/questions/17205888/mvc3-error-the-name-partial-does-not-exist-in-the-current-context – justSteve Jun 20 '13 at 10:14
  • @justSteve nice catch! Updated. – tvanfosson Jun 20 '13 at 13:02
  • @tvanfosson, please consider the usage of `.html`. I was forced to create some trick `$('#partialView').children('span').replaceWith('' + data + '');` to always have a span to replace with the new content. Best Luis – Custodio Jun 21 '13 at 15:55
  • @Custódio it's just an example, but the idea would be that the partial itself would be an entire container, i.e., be wrapped with `
    ...
    `, then you would simply replace the entire container with the new view. If your partial doesn't include the container then just use `$('#detailsDiv').html(data);`
    – tvanfosson Jun 21 '13 at 17:05
  • How to access "model" from within javascript ? – prthrokz Aug 16 '13 at 15:46
  • Very good stuff. I wonder if the first poster's idea has any merit? It'd be nice to address the replaceWith challenge for completeness. – Shawn J. Molloy Dec 29 '13 at 02:19
  • Is there a way to avoid inline javascript using this solution? – Odys Jan 12 '14 at 16:17
  • @Odys - there's no requirement for inline JavaScript with this. All of the JavaScript can be in separate files. – tvanfosson Jan 13 '14 at 15:00
  • @tvanfosson So javascript supports razor? – Odys Jan 13 '14 at 15:50
  • @Odys I see what you mean, but really that's only for this particular example. It's hard to show how you'd hook it together otherwise. In reality I'd probably use data attributes for the glue. – tvanfosson Jan 13 '14 at 17:25
  • I use this method to load a table. But now for some reason my Jquery data-table is not working? And I think it has to do with loading the content in. – Zapnologica Feb 27 '14 at 11:43
  • 1
    @Zapnologica - if you're reloading the entire table, you might need to reapply the plugin since the DOM elements it was originally connected to have been replaced. It might be better to connect it to a method that returns the data as JSON, https://datatables.net/examples/data_sources/server_side.html – tvanfosson Feb 27 '14 at 12:50
  • @tvanfosson I tried this example with a cshtml page. Well it didn't work. I a guessing I need to try another approach(?). I left the div empty thinking it would load the partial view into the
    . I debugged through the jquery and the Action method and that part works. but after I return: return PartialView("UserDetails", model); in the Details action method the div is empty. What am I doing wrong? this might be the wrong approach(?). Do you or anyone have any ideas?
    – George Geschwend Jan 04 '18 at 03:27
  • @GeorgeGeschwend I'm confident that this method works. Check to see if you're seeing errors in the console. Check if the jQuery selectors find the elements you're expecting (with the browser debugger). Make sure that the partial view you're returning via AJAX really contains the data you expect. – tvanfosson Jan 04 '18 at 14:08
  • @tvanfosson So for what I was doing, it worked (!) finally. It boiled down to a spelling error. *eye roll* $detailDiv is what I had created as a var in jquery, ergo: var $detailDiv = $('#detailsDiv'),... and later in the jquery I had $detailsDiv...ergo: $detailsDiv.replaceWith(data); so that screwed me up royally. Thanks its a great example! :) – George Geschwend Jan 05 '18 at 03:55
163

I have used ajax load to do this:

$('#user_content').load('@Url.Action("UserDetails","User")');
Jess
  • 23,901
  • 21
  • 124
  • 145
Prasad
  • 58,881
  • 64
  • 151
  • 199
  • 48
    Generally I think you're better off going with the Url.Action helper instead of hard-coding the path. This is going to break if your web site is in a subdirectory rather than at the root. Using the helper fixes that problem and allows you to add parameters with dynamically set values. – tvanfosson Nov 03 '10 at 19:33
  • 19
    You could do $('#user_content').load('@Url.Content("~/User/UserDetails")') to get around that- i often use this method if i need the javascript to slap on the querystring params at the end of the url – Shawson Apr 30 '12 at 10:08
  • In this answer, `UserDetails` is a name of an action, not a partial view, right? – Maxim V. Pavlov Jun 11 '12 at 23:02
  • Yes. UserDetails is the name of an action which returns a PartialView. – Prasad Jun 12 '12 at 04:07
  • 4
    @Prasad : **Urls** should always be evaluated using `@Url.Action("ActionName","ControllerName", new { area = "AreaName" } )` instead doing **Handcoding**. – Imad Alazani Jun 21 '13 at 18:05
  • 3
    @PKKG. @Url.Action() only evaluates in Razor. this doesn't work if OP wants to put their code in a separate js file and reference it. – Michael Jul 03 '13 at 21:06
  • @Michael : can't i initialize the js variable in View and access it in Js File ?? – Imad Alazani Jul 04 '13 at 06:11
  • @PKKG: Sure you can do that, but that defeats putting all your js code in it's own file. – Michael Jul 04 '13 at 15:31
  • @prasad i need to send model of partial view to action then do some tasks finally update model and send back to partial and update partial. How could i send model for example as form.serialize in load? i think it's impossible, but if you have any idea please share. – QMaster Apr 11 '14 at 09:25
  • Be careful of this solution. IE has tends to cache the content of the partial view. Since there is no parameter here that disables the cache, you can find yourself loading stale data. – spadelives May 06 '15 at 15:43
  • @Prasad what is `#user-content` here? – WAQ Apr 16 '17 at 07:42
  • @WAQ its the id of a div element – Prasad Apr 17 '17 at 05:50
63

@tvanfosson rocks with his answer.

However, I would suggest an improvement within js and a small controller check.

When we use @Url helper to call an action, we are going to receive a formatted html. It would be better to update the content (.html) not the actual element (.replaceWith).

More about at: What's the difference between jQuery's replaceWith() and html()?

$.get( '@Url.Action("details","user", new { id = Model.ID } )', function(data) {
    $('#detailsDiv').html(data);
}); 

This is specially useful in trees, where the content can be changed several times.

At the controller we can reuse the action depending on requester:

public ActionResult Details( int id )
{
    var model = GetFooModel();
    if (Request.IsAjaxRequest())
    {
        return PartialView( "UserDetails", model );
    }
    return View(model);
}
Community
  • 1
  • 1
Custodio
  • 8,594
  • 15
  • 80
  • 115
12

Another thing you can try (based on tvanfosson's answer) is this:

<div class="renderaction fade-in" 
    data-actionurl="@Url.Action("details","user", new { id = Model.ID } )"></div>

And then in the scripts section of your page:

<script type="text/javascript">
    $(function () {
        $(".renderaction").each(function (i, n) {
            var $n = $(n),
                url = $n.attr('data-actionurl'),
                $this = $(this);

            $.get(url, function (data) {
                $this.html(data);
            });
        });
    });

</script>

This renders your @Html.RenderAction using ajax.

And to make it all fansy sjmansy you can add a fade-in effect using this css:

/* make keyframes that tell the start state and the end state of our object */
@-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }

.fade-in {
    opacity: 0; /* make things invisible upon start */
    -webkit-animation: fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
    -moz-animation: fadeIn ease-in 1;
    -o-animation: fadeIn ease-in 1;
    animation: fadeIn ease-in 1;
    -webkit-animation-fill-mode: forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -o-animation-duration: 1s;
    animation-duration: 1s;
}

Man I love mvc :-)

Peter
  • 14,221
  • 15
  • 70
  • 110
  • Why did you each function? How it works? Do u mena something like: data-actionurl="@Url.Action("details","user", new { id = Model.ID } data-actionurl="*Another Action*"? – user3818229 Dec 22 '15 at 14:58
  • No, the each function loops over all html elements that have the data-actionurl attribute and fills it by invoking an ajax request for the action method. So multiple `
    ` elements.
    – Peter Dec 22 '15 at 16:44
10

You'll need to create an Action on your Controller that returns the rendered result of the "UserDetails" partial view or control. Then just use an Http Get or Post from jQuery to call the Action to get the rendered html to be displayed.

Chris Pietschmann
  • 29,502
  • 35
  • 121
  • 166
6

Using standard Ajax call to achieve same result

        $.ajax({
            url: '@Url.Action("_SearchStudents")?NationalId=' + $('#NationalId').val(),
            type: 'GET',
            error: function (xhr) {
                alert('Error: ' + xhr.statusText);

            },
            success: function (result) {

                $('#divSearchResult').html(result);
            }
        });




public ActionResult _SearchStudents(string NationalId)
        {

           //.......

            return PartialView("_SearchStudents", model);
        }
ASalameh
  • 783
  • 1
  • 8
  • 29
1

I did it like this.

$(document).ready(function(){
    $("#yourid").click(function(){
        $(this).load('@Url.Action("Details")');
    });
});

Details Method:

public IActionResult Details()
        {

            return PartialView("Your Partial View");
        }
Avan
  • 366
  • 3
  • 17
1

If you need to reference a dynamically generated value you can also append query string paramters after the @URL.Action like so:

    var id = $(this).attr('id');
    var value = $(this).attr('value');
    $('#user_content').load('@Url.Action("UserDetails","User")?Param1=' + id + "&Param2=" + value);


    public ActionResult Details( int id, string value )
    {
        var model = GetFooModel();
        if (Request.IsAjaxRequest())
        {
            return PartialView( "UserDetails", model );
        }
        return View(model);
    }
Rider Harrison
  • 441
  • 6
  • 12