May 12, 2016

MVC Refresh PartialView with Javascript

  • Hi all!

    This is going to be a long one so bear with me.
    Let's get this out there before we start: I've only scratched the surface of Umbraco and the whole MVC thingamagig, at least in ASP.Net.
    So what I have going on is your average webshop; you choose a product, type in the quantity and hit buy to add it to the cart. Simple.
    I haven't built the current functionality but I'm supposed to extend it.

    So what I want to do

    So far everything works as it should, items can be added, removed and edited. My problem is the "mini cart" that is shown in the header of the page. I can't get it to update without doing a postback.

    Some code

    This is the code for deleting an item from the cart on the checkout-page:

    Javascript:

    function deleteCartItem(item) {
        var serviceUrl = "/Service/DeleteCartItem";
        var request = $.post(serviceUrl, item);
        request.done(function (data) {
            $("#CartItems").html(data);
            updateMiniCart(); // My attempt to update the mini cart. See code a bit further down.
        })
        .fail(function () {
            //console.log("Does not compute!");
        });
    }
    

    C#

    public PartialViewResult DeleteCartItem(CartItem cartItem)
    {
        _cartManager.DeleteCartItem(cartItem);
        var cartItems = _cartManager.GetCart(); // Collection of CartItemModels
    
        return PartialView("~/Views/Partials/Cart.cshtml", cartItems);
    }
    

    CheckOutPage.cshtml

    @inherits Umbraco.Web.Mvc.UmbracoViewPage
        ...
        @Html.Partial("Cart", Model.CartItems)
        ...
    
    

    Cart.cshtml

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<>>
        ...
    
    So this does what it's supposed to do, it removes the item from the cart and temporary database table, and also updates the div#CartItemswith new HTML-content without postback.
    I tried to use this code as a guideline to update the mini cart in a similar fashion:

    Javascript

    function updateMiniCart(){
        var serviceUrl = "/MiniCart/RenderMiniCart";
        var request = $.post(serviceUrl);
        request.done(funtction(data){
            $("#minicartitems").html(data);
        })
        .fail(function(){
            console.log("Does not compute"); // I get this message constantly
        });
    }
    

    C#

    public ActionResult RenderMiniCart()
    {
        return PartialView("MiniCart", _cartManager.GetCart());
    }
    

    MainNavigation.cshtml

    @inherits Umbraco.Web.Mvc.UmbracoViewPage
        ...
        @Html.Action("RenderMiniCart", "MiniCart")
        ...
    

    MiniCart.cshtml

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<>>
        ...
    
    This does nothing.
    With the help of our common friend Google I ended up using @Html.Action("RenderMiniCart", "MiniCart") instead of @Html.Partialbecause...well it seemed to work.
    When debugging in Visual Studio I can see that on a postback, the C# RenderMiniCart-function runs and it in turn renders the PartialView MiniCart.cshtml and prints the content of the cart. Great!
    But when the same function is called via Javascript (without postback), it runs, but it doesn't re-render the PartialView. And also, the post made in the javascript fails.
    Does anyone have any suggestions? Is what I'm trying to attempt even possible or should I just fake everything with Javascript?
    Ninja edit: If possible, explain like I'm 5.
    If you made it this far..Kudos! Thanks for your time.
    /Nikola
  • Nikola Romcevic 26 posts 135 karma points
    Nov 28, 2013 @ 16:39
    Nikola Romcevic
    100
    So, I found a working solution in case someone else finds themselves in the same situation:
    I had to add a new function to my controller that returns a PartialViewResult instead of an ActionResult for the javascript call. So I ended up with two functions:
    public PartialViewResult GetCart()
    {
        return PartialView("MiniCart", _cartManager.GetCart());
    }
    public ActionResult RenderMiniCart()
    {
        return PartialView("MiniCart", _cartManager.GetCart());
    }
    
    And the javascript:
    function updateMiniCart(){
        var serviceUrl = "/MiniCart/GetCart";
        var request = $.post(serviceUrl);
        request.done(funtction(data){
            $("#minicartitems").html(data);
        })
        .fail(function(){
            //console.log("Does not compute");
        });
    }
    
    And that's it!

0 comments:

Post a Comment

Nam Le © 2014 - Designed by Templateism.com, Distributed By Templatelib