Reputation: 1230
I have a list of users on a page, they are loaded during an ajax event when I click on a tab (easytabs). I then ajax load a create new user partial view to the same tab. I then create a new user using this form, but I do not know how to re-load the first partial view with a new list of users (including the newly created user).
HTML to load tab panel with list of users:
<%= Ajax.ActionLink("Manage Users", "tabsUsers", null, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "ManageUsersPartial", InsertionMode = InsertionMode.Replace }, htmlAttributes: new { data_target = "#tabs-users" })%>
Controller:
[HttpGet]
public PartialViewResult tabsUsers()
{
return PartialView("UsersPartial", userManager.GetUsers());
}
UsersPartial View
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<LMS.Data.User>>" %>
<p>
<%: Ajax.ActionLink("Create New", "Create", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "CreateUserPartial", InsertionMode = InsertionMode.Replace })%>
</p>
<table>
<tr>
<th>
<%: Html.DisplayNameFor(model => model.UserName) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.FirstName) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.LastName) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.Email) %>
</th>
<th>Actions</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.DisplayFor(modelItem => item.UserName) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.FirstName) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.LastName) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.Email) %>
</td>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id = item.UserID })%> |
<%: Html.ActionLink("Details", "Details", new { id=item.UserID }) %> |
<%: Html.ActionLink("Delete", "Delete", new { id=item.UserID }) %>
</td>
</tr>
<% } %>
</table>
<br />
<div id="CreateUserPartial"></div>
This works great, every time I click the tab, the data is re-loaded as expected.
Now,
In the UsersPartial view, I have another Ajax Actionlink that loads another partial view into this partial view, to create a new user:
HTML Ajax Actionlink from UsersPartial View:
<%: Ajax.ActionLink("Create New", "Create", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "CreateUserPartial", InsertionMode = InsertionMode.Replace })%>
This loads the following CreateUserView view inside of the UsersPartial view:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<LMS.Data.User>" %>
<script src="<%: Url.Content("~/Scripts/jquery-1.6.2.min.js") %>"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>"></script>
<script type="text/javascript">
$(function () {
$('form').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#result').html(result);
}
});
}
return false;
});
});
</script>
<div id="result"></div>
<% using (Html.BeginForm())
{ %>
<%: Html.ValidationSummary(true, "Could not create new user.") %>
<fieldset>
<legend>User</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.UserName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.UserName) %>
<%: Html.ValidationMessageFor(model => model.UserName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FirstName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.FirstName) %>
<%: Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.LastName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.LastName) %>
<%: Html.ValidationMessageFor(model => model.LastName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Password) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Password) %>
<%: Html.ValidationMessageFor(model => model.Password) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Email) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Email) %>
<%: Html.ValidationMessageFor(model => model.Email) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
Finally, the code for CreateUser is called in the controller CreateUserPartial Controller code:
[HttpPost]
public ActionResult Create(AccountUser user)
{
if (ModelState.IsValid)
{
try
{
user.Password = user.Password.Encrypt();
userManager.AddUser(user);
}
catch (DbEntityValidationException dbex)
{
foreach (var validationErrors in dbex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
ModelState.AddModelError(validationError.PropertyName, validationError.ErrorMessage);
}
}
}
catch (DbUpdateException dbuex)
{
if (dbuex.InnerException != null)
if (dbuex.InnerException.InnerException != null)
if (dbuex.InnerException.InnerException.Message.Contains("Cannot insert duplicate key row in object"))
return Content("User already exists!", "text/html");
else
ModelState.AddModelError("", "An unknown error occured when creating the user.");
}
catch (Exception)
{
ModelState.AddModelError("", "An unknown error occured when creating the user.");
}
}
return Content("User created!", "text/html");
}
This all works...when a user is created, it says User created! as expected.
Now on to my question, how do I re-load the list within the UsersPartial view with the new user? I cannot figure this part out. I have a feeling it has to do with the jQuery ajax success method, but I do not know how to re-load the list of users, including this newly created one.
Any ideas?
Thanks!
Upvotes: 1
Views: 6864
Reputation: 538
Please don't Postback the form. Instead of that Call the ajax call
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<LMS.Data.User>" %>
<script src="<%: Url.Content("~/Scripts/jquery-1.6.2.min.js") %>"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>"></script>
<% using (Html.BeginForm())
<%: Ajax.BeginForm("Create",new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "ManageUsersPartial", InsertionMode = InsertionMode.Replace }, htmlAttributes: new { data_target = "#tabs-users" })
{ %>
<%: Html.ValidationSummary(true, "Could not create new user.") %>
<fieldset>
<legend>User</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.UserName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.UserName) %>
<%: Html.ValidationMessageFor(model => model.UserName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FirstName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.FirstName) %>
<%: Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.LastName) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.LastName) %>
<%: Html.ValidationMessageFor(model => model.LastName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Password) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Password) %>
<%: Html.ValidationMessageFor(model => model.Password) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Email) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Email) %>
<%: Html.ValidationMessageFor(model => model.Email) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
And then method should return the paratail view instead of Content Type
public ActionResult Create(AccountUser user)
{
if (ModelState.IsValid)
{
try
{
user.Password = user.Password.Encrypt();
userManager.AddUser(user);
}
catch (DbEntityValidationException dbex)
{
foreach (var validationErrors in dbex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
ModelState.AddModelError(validationError.PropertyName, validationError.ErrorMessage);
}
}
return PartialView("CreateUserPartial", user);
}
catch (DbUpdateException dbuex)
{
if (dbuex.InnerException != null)
if (dbuex.InnerException.InnerException != null)
if (dbuex.InnerException.InnerException.Message.Contains("Cannot insert duplicate key row in object"))
return Content("User already exists!", "text/html");
else
ModelState.AddModelError("", "An unknown error occured when creating the user.");
return PartialView("CreateUserPartial", user);
}
catch (Exception)
{
ModelState.AddModelError("", "An unknown error occured when creating the user.");
return PartialView("CreateUserPartial", user);
}
return PartialView("UsersPartial", userManager.GetUsers());
}
return PartialView("UsersPartial", userManager.GetUsers());
}
Upvotes: 2
Reputation: 1
You must return a new list after the create. Instead of:
return Content("User created!", "text/html");
You should do:
return PartialView("UsersPartial", userManager.GetUsers());
EDIT : your partial wants a IEnumerable
of users. If you need a message, send it via the ViewBag
.
Upvotes: 0