I'd like the paging link render by pagerfanta be submitted with the form data.
This is to consider the data entered in the search form.
A simple pagination link will not allow me to navigate in my search result.
Any help please ?
controller
/**
* #Route("/{page}/", name="admin_user",requirements={"page" = "\d+"}, defaults={"page" = 1})
* #Template()
*/
public function indexAction($page = 1)
{
$data = [];
$data['name'] = $this->getUser()->getName();
$form = $this->createForm('admin_user_search_type', null);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
$data = array_merge($data, $form->getData());
}
return $this->render('AABundle:User:index.html.twig', array(
'pager' => $this->getDoctrine()->getManager()->getRepoitory('AABundle:User')->search($data, 4, $page, $this->getUser()),
'form' => $form->createView(),
));
}
view.html.twig
{% if pager.haveToPaginate %}
{{ pagerfanta(pager, 'twitter_bootstrap3') }}
{% endif %}
The solution is to submit the form with Get methode instead of Post to be able to retrieve form data .Also we don't need to check whether is valid or not , while it is a search form .
The controller will be as it shown below:
**
* #Route("/{page}/", name="admin_user",requirements={"page" = "\d+"}, defaults={"page" = 1})
* #Template()
*/
public function indexAction($page = 1)
{
$data = [];
$data['name'] = $this->getUser()->getName();
$form = $this->createForm('admin_user_search_type', null);
$request = $this->getRequest();
$form->bind($request);
$data = array_merge($data, $form->getData());
return $this->render('AABundle:User:index.html.twig', array(
'pager' => $this->getDoctrine()->getManager()->getRepoitory('AABundle:User')->search($data, 4, $page, $this->getUser()),
'form' => $form->createView(),
));
}
the form.html.twig
<form name= "search" action="{{ path('admin_user') }}" novalidate method="get"{{ form_enctype(form) }}>
</form>
Related
I'm looking to retrieve information from an entity by twig by passing the id as a parameter. But I block on the function in my entity:
My entity (function need call):
public function getNameFournisseur($id)
{
???
}
My twig:
{{ staticFournisseur.getNameFournisseur(idFournisseur) }}
My controller:
/**
* #Route("/new", name="new_invoice", methods={"GET","POST"})
*/
public function new(Request $request, SessionInterface $session, ArticlesRepository $articlesRepository, FournisseursRepository $fournisseursRepository): Response
{
$invoice = new Invoice();
$form = $this->createForm(InvoiceType::class, $invoice);
$form->handleRequest($request);
$articles = $session->get('articleInvoice', []);
$articleData = [];
foreach ($articles as $k => $article) {
$articleData [] = [
'articleInvoice' => $articlesRepository->find($k),
'quantityInvoice' => $article
];
}
$total = 0;
foreach ($articleData as $totalArticle) {
$totalArticles = $totalArticle['articleInvoice']->getPrice() * $totalArticle['quantityInvoice'];
$total += $totalArticles;
}
$session->set('totalHt', $total);
$totalAllArticles = $session->get('totalHt');
$tauxDiscount = $session->get('discountTaux');
if (!$tauxDiscount) {
$totalWithDiscount = $total;
} else {
$totalWithDiscount = $totalAllArticles - ($totalAllArticles * $tauxDiscount) / 100;
}
if ($form->isSubmitted()) {
//$session->remove('idFournisseur');
$id_fournisseur = (int)$request->request->get('order')['fournisseur_id'];
$fournisseur = $fournisseursRepository->findOneBy(['id' => $id_fournisseur]);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($invoice);
$entityManager->flush();
return $this->redirectToRoute('invoices');
}
return $this->render('admin/invoices/new.html.twig', [
'staticFournisseur' => new Fournisseur(),
'idFournisseur' => $session->get('idFournisseur'),
'discountTaux' => $tauxDiscount,
'totalHt' => $totalWithDiscount,
'art' => $articleData,
'form' => $form->createView()
]);
}
I therefore seek to recover the name of the supplier thanks to the id that I pass as a parameter in my twig.
getNameFournisseur($id) is a function that retrieves data from the database, not from a single (already loaded) entity; in other words, it should be in FournisseursRepository instead
Also, if you're using Doctrine, you usually want to load the full entity instead of just a field
'staticFournisseur' => $fournisseursRepository->findOneById($session->get('idFournisseur'));
and in twig:
{{ staticFournisseur.getName() }}
or even
{{ staticFournisseur.name }}
I would like to create a function to search for a movie through the query builder
I have a table Movie:
1. Id
2. Titre
3. Content
And i have class MovieRepository :
class MovieRepository extends EntityRepository
{
public function myFindAll()
{
return $this->createQueryBuilder('a')
->getQuery()
->getResult();
}
public function getSearchMovies($movie){
$qb = $this->createQueryBuilder('m')
->where('m.title LIKE :title')
->setParameter('title', '%' . $movie->getTitle() . '%')
->orderBy('m.title', 'DESC')
->getQuery();
}
}
Also i have MovieController :
public function indexAction()
{
$movie = new Movie;
$form = $this->createForm(new SearchMovieType(), $movie);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
$movies = $this->getDoctrine()
->getManager()
->getRepository('AreaDownloadBundle:Movie')
->getSearchUsers($movie);
return $this->render('AreaDownloadBundle:Download:index.html.twig', array('form' => $form->createView(),array('movies' => $movies)));
} else {
$movies = $this->getDoctrine()
->getManager()
->getRepository('AreaDownloadBundle:Movie')
->myFindAll();
return $this->render('AreaDownloadBundle:Download:index.html.twig',array('form' => $form->createView(), 'movies' => $movies));
}
}
SearchMovieType :
class SearchMovieType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title','text', array('required' => false, ))
;
}
And i have index.hml.twig, which can display movies with a search bar :
{% extends "::template.html.twig" %}
{% block body %}
<form action="{{ path('area_download_index') }}" method="post">
<div id="bar">
{{ form_widget(form.title) }}
<input type="submit" value="Chercher">
{{ form_rest(form) }}
</div>
</form>
{% for movie in movies %}
{{ movie.title }}
{{ movie.content }}
{% endfor %}
{% endblock %}
when I seized a title of a movie he sends me this error
Variable "movies" does not exist in AreaDownloadBundle:Download:index.html.twig at line 12
Instead of posting it as a comment, it should have been posted as an answer in the correct formatting; like so:
return $this->render(
'AreaDownloadBundle:Download:index.html.twig',
array(
'form' => $form->createView(),
'movies' => $movies
)
);
This definitely should fix the problem!
Based on documentation: http://symfony.com/doc/2.8/form/dynamic_form_modification.html#form-events-submitted-data
I prepared dynamic generated form. And everything works properly but only when I use form for adding new data (/new) when I use the same form for editing existing data - not working
Simple form for "Appointment". It should work like that: User select client and then second "select" is filling proper data - depends on each client from first select. And this works ok but only when I try add new Appointment. When I try edit no.
class AppointmentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('client', EntityType::class, array(
'class' => 'SystemAdminBundle:Client',
'placeholder' => '',
));
$formModifier = function(\Symfony\Component\Form\FormInterface $form, Client $client)
{
$diseases = array();
if($client !== null) {
$diseases = $client->getDiseases();
}
$form->add('disease', EntityType::class, array(
'class' => 'SystemAdminBundle:Disease',
'placeholder' => '',
'choices' => $diseases,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
$data = $event->getData();
$formModifier($event->getForm(), $data->getClient());
}
);
$builder->get('client')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$client = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $client);
}
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'System\AdminBundle\Entity\Appointment'
));
}
}
Appointment controller - here is function for add new appointment and edit. For "new" my code works, for "edit" no.
public function newAction(Request $request)
{
$appointment = new Appointment();
$form = $this->createForm(AppointmentType::class, $appointment);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $request->request->get('appointment');
if(array_key_exists('name', $data)) {
$em = $this->getDoctrine()->getManager();
$em->persist($appointment);
$em->flush();
return $this->redirectToRoute('appointment_show', array('id' => $appointment->getId()));
}
}
return $this->render('appointment/new.html.twig', array(
'appointment' => $appointment,
'form' => $form->createView(),
));
}
public function editAction(Request $request, Appointment $appointment)
{
$deleteForm = $this->createDeleteForm($appointment);
$appointment = new Appointment();
$editForm = $this->createForm('System\AdminBundle\Form\AppointmentType', $appointment);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$data = $request->request->get('appointment');
if(array_key_exists('name', $data)) {
$em = $this->getDoctrine()->getManager();
$em->persist($appointment);
$em->flush();
return $this->redirectToRoute('appointment_show', array('id' => $appointment->getId()));
}
return $this->redirectToRoute('appointment_edit', array('id' => $appointment->getId()));
}
return $this->render('appointment/edit.html.twig', array(
'appointment' => $appointment,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
View for "new" appointment
{% block content %}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
window.onload = function() {
var $sport = $('#appointment_client');
$sport.change(function() {
var $form = $(this).closest('form');
var data = {};
data[$sport.attr('name')] = $sport.val();
data['appointment[_token]'] = $('#appointment__token').val();
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
$('#appointment_disease').replaceWith(
$(html).find('#appointment_disease')
);
}
});
});
};
{% endblock %}
View for "edit" appointment - it's almost the same as for "new" appointment
{% block content %}
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
{{ form_end(edit_form) }}
window.onload = function() {
var $sport = $('#appointment_client');
$sport.change(function() {
var $form = $(this).closest('form');
var data = {};
data[$sport.attr('name')] = $sport.val();
data['appointment[_token]'] = $('#appointment__token').val();
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
$('#appointment_disease').replaceWith(
$(html).find('#appointment_disease')
);
}
});
});
};
{% endblock %}
You create a new Appointment in your editAction and then persist it. You should take the one that's in your function parameters, handle the request and just flush, since your object is already persisted.
So remove these lines :
$appointment = new Appointment();
// ...
$em->persist($appointment);
I am using symfony3 with window 7 AND using custom form rending. like that
{{ form_start(form,{ 'attr': {'class': 'form-horizontal','role':'form','id':'form'} }) }}
---- form field here
{{ form_widget(form._token) }}
{{ form_end(form, {'render_rest': false}) }}
/**
* #Route("entity/entity/{id}", name="entity_entity",defaults={"id" = 0})
*/
public function entityAction(Request $request,$id){
$action = false;
$arr_XYZ_data = array();
$arr_XYZ_prepare_data = array();
$form_title = 'Add New XYZ';
$obj_XYZ = new XYZ();
$form = $this->createForm(XYZType::class, $obj_XYZ);
if($id!=0){
$obj_repo = $this->getDoctrine()->getRepository('AppBundle:XYZ');
$arr_XYZ_data = $obj_repo->find($id);
if($arr_XYZ_data){
$action = true;
$form_title = 'Update XYZ';
$arr_XYZ_data = $obj_repo->findXYZById($id);
$arr_XYZ_prepare_data = $this->_prepareData($arr_XYZ_data);
}
}
$form->handleRequest($request);
if (($form->isSubmitted())&&($form->isValid())) {
$obj_XYZ->setXYZId($id);
$str_hiddenfield_result = $form->get('extraformfield')->getData();
$arr_hiddenfield_result = explode('&',$str_hiddenfield_result);
$obj_XYZ->setDef($obj_XYZ->getDef()->getDefId());
$obj_XYZ->setAbc($arr_hiddenfield_result[3]);
$obj_XYZ->setAuthor(1); //ldap session value
$em = $this->getDoctrine()->getManager();
$em->persist($obj_XYZ);
$em->flush();
$this->addFlash('success', 'Your record has been added successfully!');
return $this->redirectToRoute('XYZ_index', array(), 301);
}else{
$form->getErrors();
}
}
above code does not print any error but unable to submit. so please anyone can suggest me how can i fix the issue.
how to get all error in string with corresponding each form field.
Just calling the getter will not print anything, you need to do it by yourself using another (printing) function.
return new \Symfony\Component\HttpFoundation\Response($form->getErrors());
It will render a string containing all errors.
Depending on the context (traditional, ajax, ...), you can just re-render the form like so:
return $this->render('YourBundle:YourView.html.twig', [
'form' => $form->createView(),
]);
The errors should be properly displayed.
I am implementing a simple search function that I've used on other projects without any problems. For some reason it's giving me an error on my showAction - 'Show page' that I can't figure out why.
Impossible to access an attribute ("title") on a NULL variable ("") in AcmeBundle:Blog:show.html.twig at line 9
I've done a dump on my $blog variable in showAction (which gives me the the error above - if I do not comment out the if statement I get the NotFoundException in my showAction(). My search code doesn't even go to any show action or template.
My blog entity is has a ManyToMany relationship to one entity and a ManyToOne on another, not sure if this is messing up my search code?
Question: I'm at a loss to why the search function is going to my showAction and why it's coming up null?
showAction()
/**
* #Route("/{slug}", name="AcmeBundle_show")
* #Method("GET")
* #Template("AcmeBundle:Blog:show.html.twig")
*/
public function showAction($slug)
{
$em = $this->getDoctrine()->getManager();
$blog = $em->getRepository('AcmeBundle:Blog')->findOneBy(array(
'slug' => $slug
));
var_dump($blog);
if (!$blog) {
throw $this->createNotFoundException('Unable to find blog post');
}
return array(
'blog' => $blog,
'slug' => $slug,
);
}
Search code as a service
public function search()
{
$results = null;
$query = $this->request->query->get('q');
if (!empty($query)) {
$em = $this->doctrine->getManager();
$results = $em->createQueryBuilder()
->from('AcmeBundle:Blog', 'b')
->select('b')
->where('b.title LIKE :search')
->addOrderBy('b.created', 'DESC')
->setParameter('search', "%${query}%")
->getQuery()
->getResult();
}
return array(
'query' => $query,
'results' => $results,
);
Controller with searchAction
/**
* #Route("/search", name="AcmeBundle_search")
* #Template("AcmeBundle:Page:search.html.twig")
*/
public function searchAction()
{
$em = $this->getDoctrine()->getManager();
// Search code: calling from the service Search
$query = $this->get('search');
$results = $query->search();
$recentBlogLimit = $this->container->getParameter('acme.latest.blogs_limit');
$latestBlogs = $em->getRepository('AcmeBundle:Blog')
->getBlogs($recentBlogLimit);
$tags = $em->getRepository('AcmeBundle:Tag')
->getTags();
return array(
'query' => $query,
'results' => $results['results'],
'latestBlogs' => $latestBlogs,
'tags' => $tags,
);
}
Search code on twig
<section class="section">
<form action="{{ path('AcmeBundle_search') }}" method="GET">
<label><input type="search" name="q" value={{ app.request.query.get('q') }}></label>
<input type="submit" value="Search">
</form>
</section>