How to update part of a displayed view in MVC3
-
07-07-2021 - |
Question
I have a view which calls a partial view using:
Html.RenderPartial
I'd like to call this in isolation using a controller method to stop the whole page having to be refreshed but controller methods returning void seem to destroy the existing view (I get a blank screen).
I have the javascript code to update the HTML document section but I can't see how to retain the view/get a reference to it in the controller to call the javascript method.
I should add that I'm fairly new to this MVC3 thing.
N.B. to cut a long story short, using JQuery is not an option so we're limited to Javascript unfortunately.
Solution
The basic pattern is to create a PartialView result in the Controller and use that result to update the innerHTML of some container on your page:
HTML
<input type="button" onclick="UpdateMyContainer();" value="Update" />
<div id="MyContainer">
@Html.Partial( "_MyPartialView", Model )
</div>
JavaScript
Follow Ajax without jQuery for beginners for creating an Ajax method that doesn't require JQuery. Essentially:
function UpdateMyContainer() {
var xmlHttp = createXMLHttp();
// set your controller URL here:
xmlHttp.open('get', 'Url/To/SomeMethodInController', true);
xmlHttp.send(null);
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState === 4) {
if (xmlHttp.status === 200) {
// Set the Id of the container to update here:
document.getElementById('MyContainer').innerHTML = xmlHttp.responseText;
} else {
alert('Error: ' + xmlHttp.responseText);
}
} else {
//still loading
}
};
}
The above JS could be further refactored to take in a URL and an ID of an element to update.
Controller
[HttpPost]
public PartialViewResult SomeMethodInController()
{
var model = MethodToRetreiveModel();
return PartialView( "_MyPartialView", model );
}
OTHER TIPS
Just as a postscript, I finally got round to trying this on IE6 (don't ask!). Had to make some slight tweaks but otherwise it works a beauty!
var xmlHttp = new ActiveXObject('MSXML2.XMLHttp');
And
xmlHttp.open('post', 'Url/To/SomeMethodInController', true);