Reputation: 5725
I am using .NET 4, MVC 3 and jQuery to create a diagnostics page. This page will allow users to manually run tests on our system by calling out to various web services. I want to have 3 forms on a view for 3 separate tests. Each form submission should return a value asynchronously so that they could submit just two of the tests and then see the return values of the tests without refreshing the page.
In my PHP days, I would have setup an Ajax call for each form and then hit a server-side script to do the work and return a value, but I'm having a hard time, conceptually, translating this over to an MVC solution. I would be grateful if someone would provide some example code on how to accomplish this and where each piece of code should go (Views, Controllers, Partial Views, etc...)
It seems so simple, but I just can't seem to wrap my head around it today.
Thanks in advance...
EDIT
Eric Sowell put on a great lesson, teaching MVC 3 and jQuery best practices. It's an hour long and includes DDD design principles along with DI and focuses on creating reusable jQuery code.
Upvotes: 4
Views: 3633
Reputation: 3084
Here's a quick rundown on code using a single form as an example. I know you specified multiple but it should be relatively easy to expand this
1) Make a PostModel for each form that will hold the values. So create a models.cs file and add the following class to it:
public class Form1ViewModel() // This will hold all the fields you need in the form
{
public string Field1 { get; set; }
public string Field2 { get; set; }
// etc...
}
public class Form1PostModel()
{
public string Value1 { get; set; }
public string Value2 { get; set; }
// add for each post value you expect
}
public class ReturnModel() // some object to hold the values you want to return
{
public string Message { get; set; }
public bool Success { get; set; }
}
2) In your Controller: HomeController.cs setup the following:
public ActionResult Index()
{
return View( new Form1Model() ); // default view
}
[HttpPost]
public JsonResult Form1(Form1PostModel model)
{
ReturnModel returnModel = SomeAction(model);
return JsonResult(returnModel);
}
3) In your View (Views/Home/Index.cshtml) you'd then display this form and call the ajax post:
@using (Html.BeginForm()) {
@Html.EditorForModel()
<div class="editor-actions">
<input type="button" value="Update" id="btnUpdateForm1" />
</div>
}
4) Then Jquery:
$('#btnUpdateForm1').click(function(){
$.post(
"/Home/Form1", // url
{ Value1 : "", Value2 : "" }, // payload
function(result) // success
{
// can access result.Message or result.Success here (I.E fields returned from the model)
},
function( msg ) // error
{
alert( 'Error' );
}
);
return false; // for the button
});
Hopefully that gives you an idea.. Did this from the top of the head, so pardon any minor things
Upvotes: 2
Reputation: 11677
Here's what I do for updating some information on page elements:
Im my view Practices.ascx, I've got a div of the practice to update
<div style=" width:20%; float:right; background-color:inherit" >
(Last Seen: <span id="<%: practice.ID %>LastSeenPractice" class="LastSeenPractice" >Loading...</span>)
</div>
Also in the Practices.ascx in the scripting section jQuery to update the practice, i do it every 10 minutes:
function UpdatePractice() {
jQuery.post("/reporter/LastSeenPractice", $.param({ practiceID: pid, doctorIDs: DoctorIDs }, true), UpdateLastSeenPractice, "json");
}
setInterval(UpdatePractice, 1000*60*10)
In your controller, create a function to recieve the jquery call:
[HttpPost]
public JsonResult LastSeenPractice(string practiceID, List<String> doctorIDs)
{
... process query ...
return Json(new { pid = practiceID, LastSeenPractice = lastSeenPractice, LastSeenDoctor = lastSeenDoctor });
}
and lastly back in your jscript, create a call back function to process the json result
function UpdateLastSeenPractice(data) {
$("#" + data.pid + " .LastSeenPractice").html(data.LastSeenPractice);
for (var key in data.LastSeenDoctor) {
$("#" + key + " .LastSeenDoctor").html(data.LastSeenDoctor[key]);
}
};
and that should be the basic flow of making a ajax call using jQuery
Update: Forgot about partial views part of the question. I use nested partial views to reduce the complexity of the already complex syntax. Each of my practice is under it's own view, and the index.ascx loops through all practices and creates a partial view in a treenode and passes in a parameter (unfortunately u can only pass one in so i put all the setup required for the partial view in a dictionary hence PracticesDict:
<div id="bodyPracticesList" style="float:left; width:100%">
<% Html.RenderPartial("Practices", Model.PracticesDict); %>
</div>
All of my scripts is in the index.aspx and the html is in the practices.ascx so you can do something similar with your three forms, i.e put them in partial views as Max suggested to break things up.
Upvotes: 0
Reputation: 10397
Create controllers representing each concept in your domain. You may only need one, "TestsController".
Create Actions for each test, returning JsonResult.
Write the functionality for each test, build some kind of return object, and then serialize it by calling Json(result, JsonRequestBehavior.AllowGet)
.
In the Index Action of your home controller (provided by default with a new MVC project), return View() and make a corresponding View.
In this view, make your Ajax calls with Jquery, the same way you always would, and display the results. The URLs for the Ajax calls will look like:
/Tests/Test1
etc
Upvotes: 2
Reputation: 7203
Partial Views might be a better way to approach what you need. Then you can ajaxify each view separately.
Upvotes: 0