views:

533

answers:

3

We want to perform some calculations on some values in a view...so when the user enters a value in a input...we want to go back to the server...perform the calculations and "refresh" the view with the new values...With the code as it is now, it enters the correct (...or at least the one I ask it to) controller action, correctly performs the calculations and returns the updated ViewData to the view. When I step thru the loop that builds the html for the view, the ViewData has the updated values, but when the View is displayed on the browser, the values have not changed...

Here's the javascript

$('input.changeValue').change(function() {
    $('body').css('cursor', 'wait');
    var changedAmt = this.value;
    var frmUpdate = $('form#frmUpdate').serializeArray();

    fooSoldObj = new Object();
    fooSoldObj.name = 'fooSoldAmt';
    fooSoldObj.value = changedAmt;

    frmUpdate[frmUpdate.length] = fooSoldObj;

    $.ajax(
            {
                type: $('form#frmUpdate')[0].method,
                url: $('form#frmUpdate')[0].action,
                data: frmUpdate,
                dataType: 'html',
                error: function(error) {
                    alert('frmUpdate error' + error);
                }
            }
        ); 

    setTimeout(function() {
        $('body').css('cursor', 'default');
    }, 0);
});

Here's what the html for the form frmUpdate looks like

<form action="/Forecast/Update" id="frmUpdate" method="post" name="frmUpdate">
    <span>
        <input id="HiddenForecastID" name="HiddenForecastID" type="hidden" value="XXX" />
        <input id="HiddenForecastYear" name="HiddenForecastYear" type="hidden" value="2009" />
        <input id="HiddenForecastMonth" name="HiddenForecastMonth" type="hidden" value="3" />       
    </span>
</form>

Now just to confuse things further, the data that is not displaying correctly is in a different form on the view. The reason (right or wrong) I have two forms is that the other form on the view kicks off a save routine.

Here's the relevant part of the controller action

 [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Update(FormCollection frmUpdate)            
    {
        //go off and do some stuff...this part works as the ViewData 
        //is correct....meaning it has the updated values that
        //we want to see displayed in the view
        return View("MyView", ViewData[someData]);

    }

I'm thinking that maybe the reason it's not working is that I'm updating one form and then asking the MVC view engine to update/refresh the other form(but keep in mind that when I step thru the loop on the view that builds the page, the data is updated but the page in the browser is not)...How can I cause the view to display the correct html?

/****************************************
Added the following code just to test RedirectToAction
The ajax call DOES NOT error on the above return View("blah") stuff
******************************************/

P.S. Just tried RedirectToAction in the controller like this

 [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Update(FormCollection frmUpdate)            
    {
        //go off and do some stuff...this part works as the ViewData 
        //is correct....meaning it has the updated values that
        //we want to see displayed in the view
        return RedirectToAction("MyView", new RouteValueDictionary( new { controller = "Forecast", action = "MyView", addMonth = monthAdd } ) );
    }

but then the ajax call errors with a 500 error

Thanks,
Greg

A: 

You have 2 separate environments here. Your MVC code runs on the server, and your javascript runs on the client (browser). When you submit your form, the browser sends a request back to the server, and your controller handles it & provides data for the view to render. The view that is rendered is sent back to the browser, which must interpret it.

A 500 response code means "Server Error". In other words, the server is running into some problem before it sends the response to the browser. Try examining the error details that are provided when you see the error. It should give you some clue about what's going wrong. There is probably just a mistake in the view you're rendering.

Bryan
But I don't get the error if I just use the return View("blah") stuff...myabe I shouldn't have added that in, it does make the question confusing...
w4ik
A: 

I got the view to display the updated data...it's just not ajaxy...here's the change I made to the javascript

$('input.changeValue').change(function() {
    $('body').css('cursor', 'wait');
var changedAmt = this.value;
var frmUpdate = $('form#frmUpdate').serializeArray();

fooSoldObj = new Object();
fooSoldObj.name = 'fooSoldAmt';
fooSoldObj.value = changedAmt;

frmUpdate[frmUpdate.length] = fooSoldObj;

$.ajax(
        {
            type: $('form#frmUpdate')[0].method,
            url: $('form#frmUpdate')[0].action,
            data: frmUpdate,
            dataType: 'html',
            /* the line below is the change */
            success: function() { window.location = document.location.href; },
            error: function(error) {
                alert('frmUpdate error' + error);
            }
        }
    ); 

setTimeout(function() {
    $('body').css('cursor', 'default');
}, 0);
});

so now the $.ajax sends the data frmUpdate off to the server...server makes some changes to the data in the Session object...stores the saved data in the Session object...and then the view is loaded via the

window.location = document.location.href

line, which kicks off the controller action

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult MyView(int monthAdd)

which then looks in the Session object, gets the just changed data and returns the view...seems like I'm going around my elbow to get to my a$$ :)

w4ik
+1  A: 

You're almost there. This is how we do it.

In the view, for the section that you want to update via ajax, copy the html from here to a partial view we'll call Partial_View_of_Form and render it on the view. We'll put this inside a unique div so we can replace this content later on...

<div id="replace_me">
  <% Html.RenderPartial("Partial_View_of_Form", ViewData[someData]); %>
</div>

For the Update() instead of returning a View, return the partial view we just created with the new values:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update(FormCollection frmUpdate)
{
    // do whatever processing you need here
    return PartialView("Partial_View_of_Form", ViewData[updatedData]));
}

Finally, in the ajax post, grab the html that you're returning from the action and replace the contents of the original partial view.

success: function(html)
{
    $("#replace_me").html(html); 
}

This is pretty rough code and untested, but should be pretty easy to go from here

Adam
Thanks for that...I will definitely try that...it makes perfect sense
w4ik