使用 Ajax 的 Symfony 动态搜索字段
Symfony dynamic search field using Ajax
我想在 Symfony 中使用 Ajax 实现动态搜索。我的数据库中有一个名为 Session 的实体和一个 table。
我想从 table 加载数据并将它们显示在模板中。然后,使用文本字段,我可以简单地写下我要搜索的内容,它会动态显示。
我可以从数据库加载,并且可以使用刷新页面的提交按钮来执行搜索。但这不是我想要的,我不想刷新我希望它是动态的或者有些人称之为实时搜索。
这是我的 SessionController.php
/**
* @Route("/", name="app_session_index", methods={"GET", "POST"})
* @param Request $request
* @return Response
*/
public function index(Request $request): Response
{
$propertySearch = new MyPropertySearch();
//si si aucun nom n'est fourni on affiche tous les articles
$sessions= $this->getDoctrine()->getRepository(Session::class)->findAll();
$form = $this->createForm(PropertySearchType::class, $propertySearch);
$form->handleRequest($request);
//initialement le tableau des articles est vide,
//c.a.d on affiche les articles que lorsque l'utilisateur clique sur le bouton rechercher
$articles= [];
if($form->isSubmitted() && $form->isValid()) {
//on récupère le nom d'article tapé dans le formulaire
$titre = $propertySearch->getTitle();
if ($titre!="")
//si on a fourni un nom d'article on affiche tous les articles ayant ce nom
$sessions= $this->getDoctrine()->getRepository(Session::class)
->findByMultiple($titre);
}
return $this->render('session/index.html.twig',[ 'form' =>$form->createView(), 'sessions' => $sessions]);
}
这是使用实体和我创建的名为 PropertySearchType.php 的表单。我不认为这是相关的。
然而,它正在使用
findByMultuple($titre)
方法,它是一种自定义 QueryBuilder 方法,用于使用多个条件搜索会话。
/**
// * @return Session[] Returns an array of Session objects
// */
public function findByMultiple($searchValue)
{
return $this->createQueryBuilder('s')
->join('s.coach', 'c')
->addSelect('c')
->where('s.title LIKE :title')
->orWhere('s.description LIKE :desc')
->orWhere('s.rating LIKE :rate')
->orWhere('c.tier LIKE :tier')
->setParameters(
['title' => $searchValue, 'tier'=>$searchValue,
'desc'=>$searchValue, 'rate'=>$searchValue
])
->getQuery()
->getResult();
}
最后,它应该将我需要的内容输出到包含 javascript 和 ajax 必要的 session/index.html.twig 视图。
它确实会在我刷新时呈现所有会话和一个要写入的文本字段。但是当我写下我正在搜索的内容时,table 不会改变。
这是我正在渲染的树枝文件
{% extends 'base.html.twig' %}
{% block title %}Session index{% endblock %}
{% block body %}
<h1>Session index</h1>
<h2>Search A Session !!</h2>
<div class="sidebar-search">
<div class="input-group custom-search-form">
<input type="text" id="search" class="form-control" placeholder="Search here">
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Description</th>
<th>Date</th>
<th>StartTime</th>
<th>Link</th>
<th>Rating</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for session in sessions %}
<tr>
<td>{{ session.id }}</td>
<td>{{ session.title }}</td>
<td>{{ session.description }}</td>
<td>{{ session.date ? session.date|date('Y-m-d') : '' }}</td>
<td>{{ session.startTime ? session.startTime|date('H:i:s') : '' }}</td>
<td>{{ session.link }}</td>
<td>{{ session.rating }}</td>
<td>
<a href="{{ path('app_session_show', {'id': session.id}) }}">show</a>
<a href="{{ path('app_session_edit', {'id': session.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="8">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_session_new') }}">Create new</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js">
</script>
<script type="text/javascript">
jQuery( document ).ready(function() {
var searchRequest = null;
$("#search").keyup(function(e){
/* La variable value va prendre la valeur insérer dans le champ de texte afin d’effectuer la recherche */
var value = $(this).val();
/* Ajax est lancé lors du remplissage du champ texte dont l’id est « search » pour faire la recherche */
$.ajax({
/* l’url est une chaine de caractères contenant l’adresse où la requête est envoyée */
url :{{ path('searchSessions') }},
/* La méthode utilisée pour transférer les données est GET */
type : 'GET',
/*Ici search value va prendre la chaine entrée par un utilisateur dans la zone de recherche et sera placée après l’url */
data: {
'searchValue' : value
},
/*Cette fonction permet de vider le contenu du tableau pour recevoir le nouveau contenu*/
success : function(retour){
if(retour){
$('#t tbody#search').empty();
$.each(JSON.parse(retour), function(i, obj) {
$('#t tbody#all').hide();
$('#t tbody#search').append('<tr><td> '+obj.id+' </td><td> '+obj.title+' </td>' +
'<td>'+obj.description+' </td><td>'+obj.date+' </td><td> '+obj.startTime+' </td>' +
'<td> '+obj.link+' </td><td> '+obj.rating+' </td>' +
'<td><a href="/'+obj.id+'/edit">edit</a> </br>' +
'<a href="/'+obj.id+'">remove</a></td></tr>');
});
}
else
{
$('#t tbody#all').show();
$('#t tbody#search').empty();
$('#t tbody#search').fadeIn('fast');
}``
},
});
return false;
});
});
</script>
{% endblock %}
Visual representation!!
我注意到的第一件事是在你的树枝代码中:你调用 {{ path('searchSessions') }}
但在你的 symfony 代码中定义的路由是 app_session_index
.
使用 Postman(或其他类似软件)尝试您的 symfony 路径,如果它工作正常,则继续您的 javascript 代码。
否则你将无法找出问题的根源(或者需要更多时间:))
尝试隔离你的用例,如果你不知道执行了什么代码,你将无法调试。
正如我之前所说,使用 Postman 测试您的 back-end 代码,然后当我按照您的意愿工作时添加 AJAX 调用。
public function index(Request $request): Response
{
$propertySearch = new MyPropertySearch();
$form = $this->createForm(PropertySearchType::class, $propertySearch);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
// TEST IF YOU ARE PASSING HERE
//on récupère le nom d'article tapé dans le formulaire
$titre = $propertySearch->getTitle();
// TEST IF TITLE IS CORRECT
if ($titre!="") {
// TEST IF findByMultiple WORK AS YOU WANT
//si on a fourni un nom d'article on affiche tous les articles ayant ce nom
$sessions= $this->getDoctrine()->getRepository(Session::class)
->findByMultiple($titre);
}
} else {
// TEST IF YOU ARE PASSING HERE
//si si aucun nom n'est fourni on affiche tous les articles
$sessions= $this->getDoctrine()->getRepository(Session::class)->findAll();
}
return $this->render('session/index.html.twig',[ 'form' =>$form->createView(), 'sessions' => $sessions]);
}
我想在 Symfony 中使用 Ajax 实现动态搜索。我的数据库中有一个名为 Session 的实体和一个 table。 我想从 table 加载数据并将它们显示在模板中。然后,使用文本字段,我可以简单地写下我要搜索的内容,它会动态显示。
我可以从数据库加载,并且可以使用刷新页面的提交按钮来执行搜索。但这不是我想要的,我不想刷新我希望它是动态的或者有些人称之为实时搜索。
这是我的 SessionController.php
/**
* @Route("/", name="app_session_index", methods={"GET", "POST"})
* @param Request $request
* @return Response
*/
public function index(Request $request): Response
{
$propertySearch = new MyPropertySearch();
//si si aucun nom n'est fourni on affiche tous les articles
$sessions= $this->getDoctrine()->getRepository(Session::class)->findAll();
$form = $this->createForm(PropertySearchType::class, $propertySearch);
$form->handleRequest($request);
//initialement le tableau des articles est vide,
//c.a.d on affiche les articles que lorsque l'utilisateur clique sur le bouton rechercher
$articles= [];
if($form->isSubmitted() && $form->isValid()) {
//on récupère le nom d'article tapé dans le formulaire
$titre = $propertySearch->getTitle();
if ($titre!="")
//si on a fourni un nom d'article on affiche tous les articles ayant ce nom
$sessions= $this->getDoctrine()->getRepository(Session::class)
->findByMultiple($titre);
}
return $this->render('session/index.html.twig',[ 'form' =>$form->createView(), 'sessions' => $sessions]);
}
这是使用实体和我创建的名为 PropertySearchType.php 的表单。我不认为这是相关的。 然而,它正在使用
findByMultuple($titre)
方法,它是一种自定义 QueryBuilder 方法,用于使用多个条件搜索会话。
/**
// * @return Session[] Returns an array of Session objects
// */
public function findByMultiple($searchValue)
{
return $this->createQueryBuilder('s')
->join('s.coach', 'c')
->addSelect('c')
->where('s.title LIKE :title')
->orWhere('s.description LIKE :desc')
->orWhere('s.rating LIKE :rate')
->orWhere('c.tier LIKE :tier')
->setParameters(
['title' => $searchValue, 'tier'=>$searchValue,
'desc'=>$searchValue, 'rate'=>$searchValue
])
->getQuery()
->getResult();
}
最后,它应该将我需要的内容输出到包含 javascript 和 ajax 必要的 session/index.html.twig 视图。 它确实会在我刷新时呈现所有会话和一个要写入的文本字段。但是当我写下我正在搜索的内容时,table 不会改变。
这是我正在渲染的树枝文件
{% extends 'base.html.twig' %}
{% block title %}Session index{% endblock %}
{% block body %}
<h1>Session index</h1>
<h2>Search A Session !!</h2>
<div class="sidebar-search">
<div class="input-group custom-search-form">
<input type="text" id="search" class="form-control" placeholder="Search here">
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Description</th>
<th>Date</th>
<th>StartTime</th>
<th>Link</th>
<th>Rating</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for session in sessions %}
<tr>
<td>{{ session.id }}</td>
<td>{{ session.title }}</td>
<td>{{ session.description }}</td>
<td>{{ session.date ? session.date|date('Y-m-d') : '' }}</td>
<td>{{ session.startTime ? session.startTime|date('H:i:s') : '' }}</td>
<td>{{ session.link }}</td>
<td>{{ session.rating }}</td>
<td>
<a href="{{ path('app_session_show', {'id': session.id}) }}">show</a>
<a href="{{ path('app_session_edit', {'id': session.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="8">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_session_new') }}">Create new</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js">
</script>
<script type="text/javascript">
jQuery( document ).ready(function() {
var searchRequest = null;
$("#search").keyup(function(e){
/* La variable value va prendre la valeur insérer dans le champ de texte afin d’effectuer la recherche */
var value = $(this).val();
/* Ajax est lancé lors du remplissage du champ texte dont l’id est « search » pour faire la recherche */
$.ajax({
/* l’url est une chaine de caractères contenant l’adresse où la requête est envoyée */
url :{{ path('searchSessions') }},
/* La méthode utilisée pour transférer les données est GET */
type : 'GET',
/*Ici search value va prendre la chaine entrée par un utilisateur dans la zone de recherche et sera placée après l’url */
data: {
'searchValue' : value
},
/*Cette fonction permet de vider le contenu du tableau pour recevoir le nouveau contenu*/
success : function(retour){
if(retour){
$('#t tbody#search').empty();
$.each(JSON.parse(retour), function(i, obj) {
$('#t tbody#all').hide();
$('#t tbody#search').append('<tr><td> '+obj.id+' </td><td> '+obj.title+' </td>' +
'<td>'+obj.description+' </td><td>'+obj.date+' </td><td> '+obj.startTime+' </td>' +
'<td> '+obj.link+' </td><td> '+obj.rating+' </td>' +
'<td><a href="/'+obj.id+'/edit">edit</a> </br>' +
'<a href="/'+obj.id+'">remove</a></td></tr>');
});
}
else
{
$('#t tbody#all').show();
$('#t tbody#search').empty();
$('#t tbody#search').fadeIn('fast');
}``
},
});
return false;
});
});
</script>
{% endblock %}
Visual representation!!
我注意到的第一件事是在你的树枝代码中:你调用 {{ path('searchSessions') }}
但在你的 symfony 代码中定义的路由是 app_session_index
.
使用 Postman(或其他类似软件)尝试您的 symfony 路径,如果它工作正常,则继续您的 javascript 代码。
否则你将无法找出问题的根源(或者需要更多时间:))
尝试隔离你的用例,如果你不知道执行了什么代码,你将无法调试。
正如我之前所说,使用 Postman 测试您的 back-end 代码,然后当我按照您的意愿工作时添加 AJAX 调用。
public function index(Request $request): Response
{
$propertySearch = new MyPropertySearch();
$form = $this->createForm(PropertySearchType::class, $propertySearch);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
// TEST IF YOU ARE PASSING HERE
//on récupère le nom d'article tapé dans le formulaire
$titre = $propertySearch->getTitle();
// TEST IF TITLE IS CORRECT
if ($titre!="") {
// TEST IF findByMultiple WORK AS YOU WANT
//si on a fourni un nom d'article on affiche tous les articles ayant ce nom
$sessions= $this->getDoctrine()->getRepository(Session::class)
->findByMultiple($titre);
}
} else {
// TEST IF YOU ARE PASSING HERE
//si si aucun nom n'est fourni on affiche tous les articles
$sessions= $this->getDoctrine()->getRepository(Session::class)->findAll();
}
return $this->render('session/index.html.twig',[ 'form' =>$form->createView(), 'sessions' => $sessions]);
}