Use server side form submission and validation for role crud
This commit is contained in:
parent
277ac8e05b
commit
aece8408e8
3 changed files with 139 additions and 37 deletions
|
|
@ -8,6 +8,7 @@ use App\Entity\Role;
|
|||
use Doctrine\ORM\Query;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
class RoleController extends BaseController
|
||||
{
|
||||
|
|
@ -103,10 +104,8 @@ class RoleController extends BaseController
|
|||
return $this->render('role/form.html.twig', $params);
|
||||
}
|
||||
|
||||
public function createSubmit(Request $req)
|
||||
public function createSubmit(Request $req, ValidatorInterface $validator)
|
||||
{
|
||||
// TODO: validation
|
||||
|
||||
// create new row
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$row = new Role();
|
||||
|
|
@ -115,17 +114,34 @@ class RoleController extends BaseController
|
|||
$row->setID($req->request->get('id'))
|
||||
->setName($req->request->get('name'));
|
||||
|
||||
$em->persist($row);
|
||||
$em->flush();
|
||||
// validate
|
||||
$errors = $validator->validate($row);
|
||||
|
||||
// set success
|
||||
$this->addFlash(
|
||||
'success',
|
||||
'Changes have been saved!'
|
||||
);
|
||||
// initialize error list
|
||||
$error_array = [];
|
||||
|
||||
// response
|
||||
return $this->redirectToRoute('role_list');
|
||||
// add errors to list
|
||||
foreach ($errors as $error) {
|
||||
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
||||
}
|
||||
|
||||
// check if any errors were found
|
||||
if (!empty($error_array)) {
|
||||
// return validation failure response
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'errors' => $error_array
|
||||
], 422);
|
||||
} else {
|
||||
// validated! save the entity
|
||||
$em->persist($row);
|
||||
$em->flush();
|
||||
|
||||
// return successful response
|
||||
return $this->json([
|
||||
'success' => 'Changes have been saved!'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function update($id)
|
||||
|
|
@ -136,6 +152,7 @@ class RoleController extends BaseController
|
|||
$em = $this->getDoctrine()->getManager();
|
||||
$row = $em->getRepository(Role::class)->find($id);
|
||||
|
||||
// make sure this row exists
|
||||
if (empty($row))
|
||||
throw $this->createNotFoundException('The item does not exist');
|
||||
|
||||
|
|
@ -146,14 +163,13 @@ class RoleController extends BaseController
|
|||
return $this->render('role/form.html.twig', $params);
|
||||
}
|
||||
|
||||
public function updateSubmit(Request $req, $id)
|
||||
public function updateSubmit(Request $req, ValidatorInterface $validator, $id)
|
||||
{
|
||||
// TODO: validation
|
||||
|
||||
// get row data
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$row = $em->getRepository(Role::class)->find($id);
|
||||
|
||||
// make sure this row exists
|
||||
if (empty($row))
|
||||
throw $this->createNotFoundException('The item does not exist');
|
||||
|
||||
|
|
@ -161,16 +177,33 @@ class RoleController extends BaseController
|
|||
$row->setID($req->request->get('id'))
|
||||
->setName($req->request->get('name'));
|
||||
|
||||
$em->flush();
|
||||
// validate
|
||||
$errors = $validator->validate($row);
|
||||
|
||||
// set success
|
||||
$this->addFlash(
|
||||
'success',
|
||||
'Changes have been saved!'
|
||||
);
|
||||
// initialize error list
|
||||
$error_array = [];
|
||||
|
||||
// response
|
||||
return $this->redirectToRoute('role_list');
|
||||
// add errors to list
|
||||
foreach ($errors as $error) {
|
||||
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
||||
}
|
||||
|
||||
// check if any errors were found
|
||||
if (!empty($error_array)) {
|
||||
// return validation failure response
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'errors' => $error_array
|
||||
], 422);
|
||||
} else {
|
||||
// validated! save the entity
|
||||
$em->flush();
|
||||
|
||||
// return successful response
|
||||
return $this->json([
|
||||
'success' => 'Changes have been saved!'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
|
|
|
|||
|
|
@ -32,25 +32,25 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ row is defined ? url('role_update_submit', {'id': row.getId()}) : url('role_create_submit') }}">
|
||||
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ row is defined ? url('role_update_submit', {'id': row.getId()}) : url('role_create_submit') }}">
|
||||
<div class="m-portlet__body">
|
||||
<div class="form-group m-form__group row{{ error.id is defined ? ' has-danger' }}">
|
||||
<label class="col-lg-3 col-form-label">Role ID:</label>
|
||||
<div class="form-group m-form__group row no-border">
|
||||
<label class="col-lg-3 col-form-label" data-field="id">
|
||||
Role ID:
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input type="text" name="id" class="form-control m-input{{ error.id is defined ? ' form-control-danger' }}" value="{{ values.id is defined ? values.id : (row is defined ? row.getId()) }}">
|
||||
{% if error.id is defined %}
|
||||
<div class="form-control-feedback">{{ error.id }}</div>
|
||||
{% endif %}
|
||||
<input type="text" name="id" class="form-control m-input" value="{{ values.id is defined ? values.id : (row is defined ? row.getId()) }}">
|
||||
<div class="form-control-feedback hide" data-field="id"></div>
|
||||
<span class="m-form__help">Unique identifier for this role</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row{{ error.name is defined ? ' has-danger' }}">
|
||||
<label class="col-lg-3 col-form-label">Name:</label>
|
||||
<div class="form-group m-form__group row">
|
||||
<label class="col-lg-3 col-form-label" data-field="name">
|
||||
Name:
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input type="text" name="name" class="form-control m-input{{ error.id is defined ? ' form-control-danger' }}" value="{{ values.name is defined ? values.name : (row is defined ? row.getName()) }}">
|
||||
{% if error.name is defined %}
|
||||
<div class="form-control-feedback">{{ error.name }}</div>
|
||||
{% endif %}
|
||||
<input type="text" name="name" class="form-control m-input" value="{{ values.name is defined ? values.name : (row is defined ? row.getName()) }}">
|
||||
<div class="form-control-feedback hide" data-field="name"></div>
|
||||
<span class="m-form__help">Display name for this role</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -70,4 +70,73 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
$(function() {
|
||||
$("#row-form").submit(function(e) {
|
||||
var form = $(this);
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: form.prop('action'),
|
||||
data: form.serialize()
|
||||
}).done(function(response) {
|
||||
// remove all error classes
|
||||
removeErrors();
|
||||
swal({
|
||||
title: 'Done!',
|
||||
text: 'Your changes have been saved!',
|
||||
type: 'success',
|
||||
onClose: function() {
|
||||
window.location.href = "{{ url('role_list') }}";
|
||||
}
|
||||
});
|
||||
}).fail(function(response) {
|
||||
var errors = response.responseJSON.errors;
|
||||
var firstfield = false;
|
||||
|
||||
// remove all error classes first
|
||||
removeErrors();
|
||||
|
||||
// display errors contextually
|
||||
$.each(errors, function(field, msg) {
|
||||
var formfield = $("[name='" + field + "']");
|
||||
var label = $("label[data-field='" + field + "']");
|
||||
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
|
||||
|
||||
// add error classes to bad fields
|
||||
formfield.addClass('form-control-danger');
|
||||
label.addClass('has-danger');
|
||||
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
||||
|
||||
// check if this field comes first in DOM
|
||||
var domfield = formfield.get(0);
|
||||
|
||||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
||||
firstfield = domfield;
|
||||
}
|
||||
});
|
||||
|
||||
// focus on first bad field
|
||||
firstfield.focus();
|
||||
|
||||
// scroll to above that field to make it visible
|
||||
$('html, body').animate({
|
||||
scrollTop: $(firstfield).offset().top - 200
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
// remove all error classes
|
||||
function removeErrors() {
|
||||
$(".form-control-danger").removeClass('form-control-danger');
|
||||
$("[data-field]").removeClass('has-danger');
|
||||
$(".form-control-feedback[data-field]").addClass('hide');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
|
||||
swal({
|
||||
title: 'Confirmation',
|
||||
text: 'Are you sure you want to delete ' + id + '?',
|
||||
html: 'Are you sure you want to delete <strong>' + id + '</strong>?',
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
}).then((result) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue