How to perform CRUD operations (Entity Framework) in dialogues (jQuery UI) and process validation in my MVC application ?
My problem is related to jQuery, specifically on how to show the dialog then treat the responses/data validations from the Controller.
I have this code in Index.vbhtml:
@ModelType UsuariosModel
@Code
ViewData("Title") = "GradeUsuarios"
Dim grid As New WebGrid(Model.Usuarios, rowsPerPage:=3, canPage:=True, canSort:=True)
End Code
@Using Html.BeginForm()
@<div class="fluid responsive-pnl">
<div class="child">
<h2><b>Usuários</b></h2>
</div>
<div class="separator"></div>
<div class="child">
<b>Mostrar usuários:</b><br />
@Html.DropDownListFor(Function(m) m.RegraMaster, New SelectList(Model.Regras))
</div>
<div class="child">
<button type="submit" title="Filtrar">
<img src="~/Images/FilterAdd.png" alt="" style="border:none;width:24px;" />
</button>
</div>
<div class="separator"></div>
<div class="child">
<a href="#" title="Novo registro...">
<img src="../../Images/EditAdd.png" alt="" style="border:none;width:24px;" onclick="Criar()" />
</a>
</div>
<div class="separator"></div>
</div>
@grid.GetHtml(
tableStyle:="table table-responsive tabela",
mode:=WebGridPagerModes.All,
caption:="Usuários",
columns:=grid.Columns(
grid.Column("ProviderUserKey", "Id"),
grid.Column("UserName", "Usuário"),
grid.Column("CreationDate", "Criação"),
grid.Column("Email", "Email"),
grid.Column("IsApproved", "Aprovado ?"),
grid.Column("IsLockedOut", "Bloqueado ?"),
grid.Column(header:="Ações", format:=@@<text><img src="../../Images/EditEdit.png" alt="" title="Alterar dados" style="border:none;width:24px;" onclick='Editar("@Html.Raw(item.ProviderUserKey)")' /><img src="../../Images/UserPermissions.png" alt="" title="Alterar dados" style="border:none;width:24px;" onclick='Regrar("@Html.Raw(item.ProviderUserKey)")' /><img src="../../Images/EditDelete.png" alt="" title="Excluir Registro" style="border:none;width:24px;" onclick='Excluir("@Html.Raw(item.ProviderUserKey)")' /></text>)))
End Using
<div id="janelaModal" style="display:none;" class="aninate 8s bounceIn"></div>
@Section Scripts
@Scripts.Render("~/bundles/validate")
<script type="text/javascript">
$.ajaxSetup({ cache: false });
function Editar(pid) {
showDialogo("janelaModal", "/Admin/UserEdit?id=" + pid + "", "Alteração");
};
function Regrar(pid) {
showDialogo("janelaModal", "/Admin/UserRoles?id=" + pid + "", "Permissões");
};
function Excluir(pid) {
if (confirm("Excluír o registro ?")) {
showDialogo("janelaModal", "/Admin/UserDel?id=" + pid + "", "Excluir Registro");
}
};
function Criar() {
showDialogo("janelaModal", "/Admin/UserNew", "Inclusão");
};
function showDialogo(componente, endereco, titulo) {
var wHeight = $(window).height();
var wWidth = $(window).width();
var dWidth = wWidth * 0.7;
var dHeight = wHeight * 0.4;
var dlgOp = {
show: { effect: 'fade', direction: "up" },
hide: { effect: 'clip', direction: "down" },
modal: true,
width: dWidth,
height: dHeight,
title: titulo,
draggable: true,
resizable: true
};
var div = $("#" + componente);
div.load(endereco, function () { div.dialog(dlgOp); });
}
</script>
End Section
On the controller I have this code:
Imports System.IO
Imports System.Web.Mvc
Namespace Controllers
<Authorize(Roles:="Administradores")>
Public Class AdminController
Inherits Controller
<HttpGet>
Function Index() As ActionResult
Return View(New UsuariosModel)
End Function
<HttpPost>
Function Index(model As UsuariosModel,
Optional sortBy As String = "UserName",
Optional ascending As Boolean = True,
Optional page As Integer = 1,
Optional pageSize As Integer = 10,
Optional roleName As String = "") As ActionResult
Dim filteredResults = (From u As MembershipUser In Membership.GetAllUsers Select u).AsQueryable
If (String.IsNullOrEmpty(model.RegraMaster) = False) Then
filteredResults = filteredResults.Where(Function(p) Roles.IsUserInRole(p.UserName, model.RegraMaster))
End If
model.Usuarios = filteredResults.SortBy(model.SortExpression).Skip((model.CurrentPageIndex - 1) * model.PageSize).Take(model.PageSize).ToList
Return View(model)
End Function
<HttpGet>
Function UserEdit(id As String) As PartialViewResult
Dim model As Core.AspNet_User = Nothing
If String.IsNullOrEmpty(id) = False Then
model = (New Core.Context).aspnetUsers.Where(Function(m) m.PKID.Equals(id)).FirstOrDefault
End If
Return PartialView(model)
End Function
<HttpPost>
<ValidateAntiForgeryToken>
Function UserEdit(model As Core.AspNet_User) As ActionResult
If ModelState.IsValid Then
Return RedirectToAction("Index")
Else
Return Json(False)
End If
Return PartialView(model)
End Function
<HttpGet>
Function UserDel(userName As String) As ActionResult
Dim model As New Core.AspNet_User
Return PartialView(model)
End Function
<HttpPost>
Function UserDel(model As Core.AspNet_User) As ActionResult
If ModelState.IsValid Then
Return RedirectToAction("Index")
End If
Return PartialView(model)
End Function
<HttpGet>
Function UserNew() As ActionResult
Dim model As New Core.AspNet_User
Return PartialView(model)
End Function
<HttpPost, ValidationActionFilter>
Function UserNew(model As Core.AspNet_User) As PartialViewResult
If ModelState.IsValid Then
Dim stt As MembershipCreateStatus
Dim u As MembershipUser = Membership.CreateUser(model.UserName,
model.Password,
model.Email,
model.PasswordQuestion,
model.PasswordAnswer,
model.IsApproved, stt)
Select Case stt
Case MembershipCreateStatus.DuplicateEmail
ModelState.AddModelError("UserName", "O e-mail da conta já existe. Altere o e-mail da conta.")
Case MembershipCreateStatus.DuplicateProviderUserKey
ModelState.AddModelError("UserName", "A chave da conta já existe. Tente novamente com dados diferentes.")
Case MembershipCreateStatus.DuplicateUserName
ModelState.AddModelError("UserName", "O nome da conta já existe. Altere o nome da conta.")
Case MembershipCreateStatus.InvalidAnswer
ModelState.AddModelError("UserName", "A resposta da dica de senha é inválida. Tente alterar a resposta da dica de senha.")
Case MembershipCreateStatus.InvalidEmail
ModelState.AddModelError("UserName", "O endereço de e-mail é inválido. Será que ele não está cadastrado para outro usuário ?")
Case MembershipCreateStatus.InvalidPassword
ModelState.AddModelError("UserName", "A senha é inválida. Tente alterar a senha informada.")
Case MembershipCreateStatus.InvalidProviderUserKey
ModelState.AddModelError("UserName", "A chave do provedor é inválida. Essa conta provavelmente já existe.")
Case MembershipCreateStatus.InvalidQuestion
ModelState.AddModelError("UserName", "A dica de senha é inválida. Tente alterar a dica de senha.")
Case MembershipCreateStatus.InvalidUserName
ModelState.AddModelError("UserName", "Essa conta é inválida. Tente alterar o nome informado.")
Case MembershipCreateStatus.ProviderError
ModelState.AddModelError("UserName", "Ocorreu um erro com o provedor.")
Case MembershipCreateStatus.UserRejected
ModelState.AddModelError("UserName", "Essa conta foi recusada pelo provedor.")
Case Else
Return RedirectToAction("Index")
End Select
End If
Return PartialView(model)
End Function
<HttpGet>
Function UserRoles(id As String) As ActionResult
Return PartialView(New UserRolesModel(id))
End Function
<HttpPost>
Function UserRoles(model As UserRolesModel) As ActionResult
If ModelState.IsValid Then
For Each item In model.Regras
If item.Value = True Then
If Roles.IsUserInRole(model.UserName, item.Key) = False Then Roles.AddUserToRole(model.UserName, item.Key)
Else
If Roles.IsUserInRole(model.UserName, item.Key) = True Then Roles.RemoveUserFromRole(model.UserName, item.Key)
End If
Next
Return RedirectToAction("Index")
End If
Return PartialView(model)
End Function
End Class
End Namespace
To create, edit or delete a record, the jQuery UI dialog is shown with a model.
The dialog sends the model to the controller at end of edition.
When saving, if the model state (in controller) is not valid, the controller returns a partial view.
This partial view works, but no more inside the dialog.
It seams that I need to treat the response from controller and re-create the dialog if the response is invalid, in my jQuery script, but I don't know how to do it.
Thank you all again!