Reputation: 109
I am in the process of porting a site I wrote from ASP.NET webforms to MVC3 and need some guidance as outlined below. I'm new to MVC3.
In my existing ASP.NET web forms project I have a simple page where the user enters a username, they then click a button which causes a postback, on postback there is some basic code that checks if the entered username exists in a user repository - if it does, a textbox containing the users e-mail is shown and the username textbox is made invisible. This happens with ajax and so when the username is entered, the textbox containing the e-mail along with an "Update" button is shown without a full page refresh.
I created a model such as:
public class ChangeEmailModel
{
[Required]
public string Username { get; set; }
[Required]
public string Email { get; set; }
}
Problem is that when the user first enters the page, they should only see a textbox prompting them to enter a username. Once the username is entered and an update button clicked, only then their e-mail is shown (retrieved from the database). Once the e-mail is shown, they can edit the e-mail and click update, which then will need to post to a controller action that saves the updated e-mail. I'm not yet fully used to thinking in the MVC way, so I'm not sure if I've started on the wrong foot with the model above...
Can someone give me some guidance on how this can be accomplished in MVC3 so I can give it a try?
Upvotes: 0
Views: 1899
Reputation: 3974
I will start off by suggesting that you start using JQuery for your javascript/ajax functions. ASP.Net MVC3 supports JQuery nicely. I will ignore validation of the email for now as it will be much easier to get you started without it. A high level overview will be:
1. Add the JQuery script to your page
This should be pretty easy - just drag it from your scripts folder. I think mvc3 comes with jquery-1.5.1.js. Use the min (minified) version when you release to production.
2. Add the JQuery vsdoc script to your page so you have some intellisense
Not quite as easy here - you will want to use an if statement that always evaluates to false so the script is not actually included in your content. Having it on the page though, will cause VS to use it for intellisense. Put this near the top of your view:
@if (false) { <script src="../../Scripts/jquery-1.5.1-vsdoc.js" type="text/javascript"></script> }
Hopefully you are using Razor. If not, start using it. It seemed a little foreign to me at first, but it requires much less markup.
3. Create a partial view to show the email and submit button
You could use the ViewBag to pass the Email address and UserName (for now as we are ignoring validation), but go ahead and make it strongly typed to your Model from above. Your view may look something like this:
@model ChangeEmailModel
@{using (Html.BeginForm("UpdateEmail", "Home", FormMethod.Post, new { id = "UpdateEmailForm" }))
{
<input type="hidden" name="userName" value="@Model.UserName" />
@Html.EditorFor(m => m.Email)
<button id="submitEmailUpdate" type="submit">Submit</button>
}
}
Note that we have given Ids to the form and the submit button. JQuery will find the form and button based on these ids. (if we need to, which we will if we want to "ajaxify" the action of updating the email. I did not go into that detail here, but it will be the same process to get that working as it is for the original username lookup)
4. Create a controller action that performs the email lookup you mentioned I won't go into controllers much here (as you are asking about ajax type updates) but it might look like:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LookupEmail(string userName)
{
//connect to db and lookup email based on passed in username
//create a new instance of your model
var changeEmailModel = new ChangeEmailModel(.....)
//return a partial view
return PartialView("EmailUpdateForm", changeEmailModel);
}
Make sure to return a PartialView here rather than a View.
5. Create a div to accept the newly returned Email Update form
Make sure this div is not contained in your Username lookup form (as you want to hide it). We will be working with two separate forms. This div could be hidden if you prefer (but will start out empty anyway) I am calling it emailFormDiv
6. Use JQuery to override the submit on your username lookup to perform an ajax update instead
JQuery will allow you to attach functions to... well a lot of things, but we will be using it to override the submit button on your username lookup form. Assume that your original username lookup form with an id of "formUserNameLookup" that has a submit button with an id of "submitUserNameLookup". You would then create a script tag that looks something like this:
<script type="text/javascript" language="javascript">
$(document).ready(function () { //The document.ready function will fire when the html document is... ready
$('#submitUserNameLookup').click(function (ev) { //fires when the submit button is clicked
ev.preventDefault(); //prevent the normal action of the button click
$.post($('#formUserNameLookup').attr('action'), //get the url from the form's action attribute. Could be hard coded for simplicity
$('#formUserNameLookup').serialize(), //serialize the data in the form
function (response, status) {
$('#emailFormDiv').html(response); //replace the html of your div with the response
$('#formUserNameLookup').hide(); //hide the original form
}, 'html'); //states that we are expecting html back from the post
});
});
</script>
The code above is attaching a function to be run when the submit button is clicked. It won't run, of course, until the button is actually clicked. Using JQuery/Javascript to attach functions to html elements, rather than embedding them directly inside the element is definitely preferred, and is referred to as unobtrusive javascript. If you continue with ajaxifying more of your page, you will want to look into JQuery's live and/or delegate functions. Note that there are plenty of things that can be changed once you start looking toward performance and/or best practices. The above should get you going though. I hope I haven't made too many assumptions on your current level of familiarity with ASP.Net MVC (like controllers and posting to controllers) but by all means, ask if you need further help.
Upvotes: 2