sah*_*oun 11 forms ajax jquery modal-dialog symfony
我正在尝试实现我的symfony表单/模式,使用ajax每次提交添加/删除和更新操作时都停止重新加载页面,但问题是我不熟悉ajax而我不知道如何做到这一点.任何人都可以帮助我理解这个概念.
mY实体:
<?php
namespace EvalBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Department
*
* @ORM\Table(name="department")
* @ORM\Entity(repositoryClass="EvalBundle\Repository\DepartmentRepository")
*/
class Department
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string",unique=true)
*/
private $name;
/**
* One Department has Many Collaborators.
* @ORM\OneToMany(targetEntity="Collaborator", mappedBy="department")
*/
private $collaborators;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Department
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
}
Run Code Online (Sandbox Code Playgroud)
形式:
<?php
namespace EvalBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DepartmentType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name');
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'EvalBundle\Entity\Department',
'attr' => array('novalidate' => 'novalidate')
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'evalbundle_department';
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
<?php
/**
* Created by PhpStorm.
* User: sa7noun
* Date: 5/15/17
* Time: 12:09 PM
*/
namespace EvalBundle\Controller;
use EvalBundle\Entity\Department;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
class DepartmentController extends Controller
{
/**
* Lists all Department entities.
*
* @Route("/department", name="department_index")
* @Method({"GET","POST"} )
*
*/
public function indexAction(Request $request)
{
$department = new Department();
$form = $this->createForm('EvalBundle\Form\DepartmentType', $department);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($department);
$em->flush();
return $this->redirectToRoute('department_index');
}
$em = $this->getDoctrine()->getManager();
$departments = $em->getRepository('EvalBundle:Department')->findAll();
/**
* @var $paginator \Knp\Component\Pager\Paginator
*/
$paginator = $this->get('knp_paginator');
$result = $paginator->paginate(
$departments,
$request->query->getInt('page', 1),
$request->query->getInt('limit', 5)
);
return $this->render('EvalBundle:Department:department.html.twig', array(
'departments' => $result,
'form' => $form->createView(),
));
}
// /**
// * Creates a new Department entity.
// *
// * @Route("/department/new", name="department_new")
// * @Method({ "POST"})
// */
// public function newAction(Request $request)
// {
// $department = new Department();
// $form = $this->createForm('EvalBundle\Form\DepartmentType', $department);
// $form->handleRequest($request);
//
// if ($form->isSubmitted() && $form->isValid()) {
// $em = $this->getDoctrine()->getManager();
// $em->persist($department);
// $em->flush();
//
// return $this->redirectToRoute('department_index');
// }
//
// return $this->render('EvalBundle:Department:department.html.twig', array(
// 'department' => $department,
// 'form' => $form->createView(),
// ));
// }
/**
* Displays a form to edit an existing department entity.
*
* @Route("department/{id}/edit", name="department_edit")
* @Method({"GET", "POST"})
*/
public function editAction(Request $request, Department $department)
{
$deleteForm = $this->createDeleteForm($department);
$editForm = $this->createForm('EvalBundle\Form\DepartmentType', $department);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('department_edit', array('id' => $department->getId()));
}
return $this->render('EvalBundle:Department:edit.html.twig', array(
'department' => $department,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a department entity.
*
* @Route("department/{id}", name="department_delete")
* @Method({"GET","DELETE"})
*/
public function deleteAction(Department $department)
{
// $response = array(
// 'success' => true,
// 'message' => '',
// 'html' => '',
// );
//
// $form = $this->createDeleteForm($department);
// if ($request->getMethod() == 'DELETE'){
// $form->handleRequest($request);
// }
//
if ($department) {
$em = $this->getDoctrine()->getManager();
$em->remove($department);
$em->flush();
}
return $this->redirectToRoute('department_index');
}
/**
* Creates a form to delete a department entity.
*
* @param Department $department The department entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Department $department)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('department_delete', array('id' => $department->getId())))
->setMethod('DELETE')
->getForm();
}
}
Run Code Online (Sandbox Code Playgroud)
查看(索引):
{% extends 'default/superAdminBase.html.twig' %}
{% block body %}
<div class="col-lg-6">
<div class="panel panel-default">
<div class="panel-heading" style="background-color: #0089db">
<h5 style="text-align: center"><b>Départements</b></h5>
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div class="table-responsive">
<table class="table table-hover table-fixed table-paginated">
<thead>
<tr>
</tr>
</thead>
<tbody>
{% for department in departments %}
<tr>
<td>
<b>{{ department.name }}</b>
<a href="{{ path('department_edit', { 'id': department.id }) }}"
class="btn btn-default btn-circle " style="float: right">
<i class="fa fa-edit"></i>
</a>
<a href="{{ path('department_delete', {'id': department.id}) }}"
class="btn btn-danger btn-circle remove-item"
data-entity-id="{{ department.id }}" style="float: right" data-toggle="modal">
<span class="glyphicon glyphicon-remove"></span>
</a>
<div class="modal fade" id="infos">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">x</button>
<h4 class="modal-title">Confirmation</h4>
</div>
<div class="modal-body">
Etes-vous sur de vouloir supprimer ce Département !
</div>
<div class="modal-footer">
<button href=" #" class="btn btn-info delete-item"
data-dismiss="modal">OUI
</button>
<button class="btn btn-info" data-dismiss="modal">NON</button>
</div>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
<div class="navigation text-center">
{{ knp_pagination_render(departments) }}
</div>
<!-- /.panel -->
<div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="myModal-1" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
{% if app.session.flashBag.has('success') %}
<div class="aler alert-success">
{% for msg in app.session.flashBag.get('success') %}
{{ msg }}
{% endfor %}
</div>
{% endif %}
<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>
<h4 class="modal-title"> Ajouter un nouveau département</h4>
</div>
<div class="modal-body" id="modal-input">
{{ form_start(form,{'attr': {'class': 'form-horizontal','data-parsley-validate':''}}) }}
{{ form_widget(form.name,{'attr': {'class': 'form-control','placeholder':'Nom de département', 'data-parsley-required':'true', 'data-parsley-required-message':'le nom ne doit pas être vide :D'}}) }}
<br>
<div class="form-group">
<div class="col-lg-offset-8 col-lg-4">
<button type="submit" class="btn btn-block btn-primary"><span
class="glyphicon glyphicon-plus"></span> Créer
</button>
</div>
</div>
{{ form_end(form) }}
</div>
</div>
</div>
</div>
</div>
<a href="#myModal-1" data-toggle="modal" class="btn btn-outline btn-primary "><i class="fa fa-plus"></i>Ajouter un
département</a>
{% block javascript %}
<script src="{{ asset('JS/departmentValidation.js') }}"></script>
{% endblock %}
{% endblo
ck %}
Run Code Online (Sandbox Code Playgroud)
joh*_*ith 23
我会基本回答这个问题,让你有个主意!
所以首先你必须在服务器端分离保存部分,因为它不会像indexAction那样返回视图.相反,它返回客户端的ajax调用可以接收的一些json数据
您的新控制器操作可能看起来像这样:
/**
* Creates a new Department entity.
*
* @Route("/department/new", name="department_new")
* @Method({ "POST"})
*/
public function newDepartmentAction(Request $request)
{
$department = new Department();
$form = $this->createForm('EvalBundle\Form\DepartmentType', $department);
$form->handleRequest($request);
$status = "error";
$message = "";
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($department);
try {
$em->flush();
$status = "success";
$message = "new department saved";
} catch (\Exception $e) {
$message = $e->getMessage();
}
}else{
$message = "invalid form data";
}
$response = array(
'status' => $status,
'message' => $message
);
return new JsonResponse($response);
// above is just an example of one way using formtypes,
// you can retrieve any parameter you send here like:
// $param = $request->get('param');
}
Run Code Online (Sandbox Code Playgroud)
你可以做任何你想做的事情,比如在所有部门上分页并返回它们,但你需要一个js方式来显示返回的JSON然后,你不能使用twig,因为视图已经返回,你绝对想要使用任何datadriven JS View Model lib具有自动ui刷新功能.
接下来,客户端 - 从客户端,您必须将正确的数据发送到该操作
因此,您必须将表单字段序列化为一组可以发送到服务器的属性和值.我们将首先将表单序列化为javascript对象.
在这里你有一个函数,你必须在jquery加载之后和你的进一步代码之前包含某个地方
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
Run Code Online (Sandbox Code Playgroud)
接下来你必须避免实际提交表单非ajax,因为点击提交按钮将导致提交表单并重新加载页面,我们阻止该行为,假设表单有一些独特的选择器eG.ID = "newDepartmentForm"
$(document).on("submit", "#newDepartmentForm", function(e){
e.preventDefault();
return false;
});
Run Code Online (Sandbox Code Playgroud)
现在让我们假设您想通过单击具有特定ID的按钮来保存
$(document).on("click", "#mySubmitButton", function(e){
e.preventDefault();
var form = $("#newDepartmentForm");
// you could make use of html5 form validation here
if(!form[0].checkValidity()){
// To show the native error hints you can fake a click() on the actual submit button
// which must not be the button #mySubmitButton and shall be hidden with display:none;
// example:
// <button type="button" id="#mySubmitButton" class"btn btn-default" > Save </button>
// <button type="submit" id="#myHIDDENSubmitButton" style="display:none;"></button>
//
$("#myHIDDENSubmitButton").click();
return false;
}
// get the serialized properties and values of the form
var form_data = form.serializeObject();
// always makes sense to signal user that something is happening
$('#loadingSpinner').show();
// simple approach avoid submitting multiple times
$('#mySubmitButton').attr("disabled",true);
// the actual request to your newAction
$.ajax({
url: '/department/new',
type: 'POST',
dataType: 'json',
data: form_data,
success:function(data){
// handling the response data from the controller
if(data.status == 'error'){
console.log("[API] ERROR: "+data.message);
}
if(data.status == 'success'){
console.log("[API] SUCCESS: "+data.message);
}
// signal to user the action is done
$('#loadingSpinner').hide();
$('#mySubmitButton').attr("disabled",false);
}
});
});
Run Code Online (Sandbox Code Playgroud)
基本上就是这样.
如果你想让你的网站完全由Ajax驱动,你可以从服务器请求任何数据,例如你可能想要首先加载所有现有的部门,就像上面那样.但正如我所提到的,你需要一种JS方式来显示你的数据,像单页面应用程序这样的术语,MVVM值得查找有很多有用的库,如vue,react,knockout,ember ......等等.喜欢简单的方法,根据模型的复杂程度,它们可能不是必需的.对于您的Api,您还可以深入了解高性能序列化,REST,CRUD,授权,不要重复自己.Websockets也可能非常有趣.
| 归档时间: |
|
| 查看次数: |
19284 次 |
| 最近记录: |