Ryand.Johnson
Ryand.Johnson

Reputation: 1906

MVC3 Change View from Jquery

I am new to MVC3 and Jquery. Maybe i am not taking the right approach to this, please let me know if there is a better solution.

I want to use JQuery to change views in my MVC app. I have a list of products on the main page. When the user clicks a product, I Jquery to send a request to the server with the product ID and change to a product details view. Before I change views, i do Jquery explode effect. I am using the callback function of the Jquery effect to submit the request. When i debug my code. The product details controller is called and it returns the details view. But the web browser does not change the the product details view. it stays on the home page.

Here is my product controller:

public class ProductController : Controller
{

    public ActionResult Details(string productId)
    {
        return View();
    }
}

Jquery explode effect with callback:

$(".productOriginal").click(function () {
            $(this).hide("explode", {}, 1000, productSelectedCallback);
});

Jquery Callback:

function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var data = { productId: prodId.toString() };
   $(this).load('/Product/Details');
}

In addition to .load, i have use .post and .ajax and got the same result with all. So, i must be fundamentally missing something here.

I am using the default register routes. The products folder is set up the same as the home folder and has a details.cshtml.

Thanks for you help!

Upvotes: 3

Views: 12138

Answers (5)

Ryand.Johnson
Ryand.Johnson

Reputation: 1906

I got it! Thanks to @jdangelo. I was trying to solve the problem using the wrong tools. There was no reason to post anything to the server. I already had a product Id. I could just redirect from the client.

Instead of:

function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/?productId=' + prodId.toString();
   $(this).load(targetUrl);
}

I used this:

function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/?productId=' + prodId.toString();
   top.location.href = targeUrl;
}

Upvotes: 0

andres descalzo
andres descalzo

Reputation: 14967

try this: EDIT FOR TEST

$(".productOriginal").click(function (event) {
     event.stopPropagation();

     var 
        _this = this,
        prodId = $(this).attr("id"); // is string

     alert("Id product: " + prodId);

     $(this).hide("explode", 1000,
        function() {
           var data = { productId: prodId };
           $(_this).load('/Product/Details', data, function(responseText){
                alert("responseText :" + responseText);
           });
        }
     );

     return false;
});

Upvotes: 0

Jim D'Angelo
Jim D'Angelo

Reputation: 3952

Try

function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/' + prodId.toString();
   $(this).load(targetUrl);
}

Edit:

Change your action method on your controller from

public ActionResult Details(string productId)
{
    return View();
}

to

public ActionResult Details(int id)
{
    return View();
}

or your jQuery code to:

function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/?productId=' + prodId.toString();
   $(this).load(targetUrl);
}

You probably don't have a route setup to take "productId" in your action. You can still use it (if you don't want to configure the route) but it will need to be in a query string.

Edit 2:

In light of your last comment, I am not sure you really want to be using AJAX for your solution since you are attempting to redirect from one page to another. I would suggest changing your return type to a RedirectToAction result. This will tell the browser that you need to redirect, but this will need to be done in an action other than your product details action (or you will get an endless redirect loop).

Try something like this:

// In the home controller where Id = the product id
public ActionResult RedirectToProductDetails (int id)
{
    // Use whatever names you want for Id and ProductId, respectively
    return RedirectToAction ("Details", "Products", new { id = id });
}

// And then in your Product Controller:
public ActionResult Details (int id)
{
    var MyProduct = // Get your product from the database or whatever
    return View (MyProduct);
}

(Please note, this will actually cause two trips for the client, effectively removing any advantage of using an "AJAX" approach.)

Upvotes: 3

mr.b
mr.b

Reputation: 2708

JQuery Callback

function productSelectedCallback() {
   var prodId = $(this).attr("id");
    var BaseUrl = 'http://' + top.location.host ;

    $.ajax({
                type: 'POST',
                url: BaseUrl + '/Product/Details',
                data: ({ productId: prodId.toString() }),
                success: function (resp) {

                }
            });
}

CallJquery explode effect with callback:

$(".productOriginal").click(function () {
            $(this).hide("explode", {}, 1000, productSelectedCallback);
});

Here is my product controller:

public class ProductController : Controller
    {
        [HttpPost] 
        public ActionResult Details(string productId)
        {
            return View();
        }
    }

Upvotes: 1

mr.b
mr.b

Reputation: 2708

You can actually achieve that by using jquery ajax() instead of load(). And on your controller add [HttpPost] to receive post data. That said, you can do whatever you want from your controller, whether you want to return the view or redirect to action and etc.

Upvotes: 0

Related Questions