I have a form that contains a hidden field, it uses this field to send a variable that indicates the id of the item to remove, to the action. I have a table that displays the content of the database table 'profil', for every line there is a button "supprimer" that deletes this line, but as i said, it only deletes the first line. Apparentlu this loop creates only one form for the first item, so I want to create this form for every item in the table.
{% if profils %}
<div id="prof_table">
<table style="background-color: #f9f9f9;position: absolute;top:10vmin;left: 5vmin;"
class="table table-responsive table-bordered">
<tr>
<th style="color: #1b6d85"> Identificateur </th>
<th style="color: #1b6d85"> Libellé</th>
<th style="color: #1b6d85"> Actions</th>
</tr>
{% for profil in profils %}
<tr><td>{{ profil.id }}</td><td>{{ profil.libelle }}</td>
<td>
<button id="delete" class="btn btn-danger btn-xs">
<a data-fancybox data-src="#hidden-content3" href="javascript:;"
style="color: #ffffee;text-decoration: none;">Supprimer</a>
</button>
</td></tr>
<!-- HERE IS THE POPUP FORM TO DELETE PROFILES-->
<div style="display: none; height: 40vh; width: 30vw;" id="hidden-content3">
<span style="position:relative;top:10vmin;font-size: medium;"></span>
{% if form3 %}
<label style="display:inline-table;">
<span style="font-size: medium;">Etes vous surs de vouloir supprimer ce profil?</span>
</label>
</section>
{{ form_start(form3, { attr: {novalidate: 'novalidate'} }) }}
<section class="col-lg-9 col-md-9 col-sm-9 col-xs-9" style="position: relative; left: 5vmin;top: 6vmin">
<label style="display:inline-table;">
<span>{{form_widget(form3.idprof, {attr: { value : profil.id}} )}}</span>
</label>
</section>
<section class="col-lg-5 col-md-5 col-sm-5 col-xs-5" style="position: relative; left: 5vmin;top: 6vmin">
<span>{{ form_widget(form3.Confirmer) }}</span>
</section>
{{ form_end(form3) }}
{% endif %}
</div>
{% endfor %}
</table>
</div>
{% else %}
{{ "Aucun profil n'a été trouvé." }}
{% endif %}
/**
* #Route("/webmaster/gestProf/{idprof}", defaults={"idprof": 0},name="gestProf")
* Method ("POST")
* #Template()
*/
public function gestProfAction(Request $request)
{
$session = new Session();
$session->start();
$em=$this
->getDoctrine()
->getManager();
$repository = $em->getRepository("CNAMCMSBundle:profil");
$profils = $repository->findAll();
foreach ($profils as $prof) {
$id = $prof->getId();
$libelle = $prof->getLibelle();
}
$prof = new profil();
$form3 = $this->createFormBuilder($prof, array('csrf_protection' => false))
->setMethod("POST")
->add('idprof', 'hidden', array('mapped' => false))
->add('Confirmer', 'submit', array('attr' => array('class' => 'btn btn-primary btn-block rounded_btn', 'id' => 'login_btn',
'style' => "width:6vw;height:5vh;padding:0px 0px; position:relative;left:5vmin;top:1vmin;font-size:2vmin;")))
->getForm();
$form3->handleRequest($request);
if ($form3->isSubmitted()) {
//$idprof = $request->request->get('idprof');
$idprof = $form3->get('idprof')->getData();
$repository = $em->getRepository("CNAMCMSBundle:profil");
$prof = $repository->findOneById($idprof);
$em=$this
->getDoctrine()
->getManager();
$em->remove($prof);
$em->flush();
}
var_dump($request->getContent());
return $this->render('CNAMCMSBundle:Default:gestProf.html.twig', array('profils'=>$profils,
'form3'=>$form3->createView()
));
}
Related
I'm working on an app with Symfony/Twig, and I want to scan a directory and add all photos of this directory in a Bootstrap carousel.
Controller
public function index(int $id, ManagerRegistry $doctrine): Response
{
$entityManager = $doctrine->getManager();
$establishment = $entityManager->getRepository(Establishment::class)->find($id);
$establishmentName = $establishment->getEstablishmentName();
$establishmentDirectory = $this->getParameter('media_directory').'/establishments_pages/'.$establishmentName;
$establishmentAssetDir = '/ressources/uploads/establishments_pages/'.$establishmentName;
$photos = [];
$buttons = [];
$count = 0;
$count1 = 1;
if ($establishmentDirectory) {
$results = scandir($establishmentDirectory);
foreach ($results as $value) {
if ($value !== '.'
&& $value !== '..'
&& $value !== 'Suite Deluxe'
&& $value !== 'Suite standard'
&& $value !== 'Suite VIP') {
if ($count === 0) {
$button = '<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide '.$count1.'"></button>';
$photo = '<div class="carousel-item active"><img src="{{ asset("'.$establishmentAssetDir.'/'.$value.'")}}" class="d-block w-100" alt="Photo de l\'hotel"></div>';
array_push($buttons, $button);
array_push($photos, $photo);
$count++;
$count1++;
} else {
$button = '<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="'.$count.'" aria-label=" Slide '.$count1.'"></button>';
$photo = '<div class="carousel-item"><img src="{{ asset("'.$establishmentAssetDir.'/'.$value.'")}}" class="d-block w-100" alt="Photo de l\'hotel"></div>';
array_push($buttons, $button);
array_push($photos, $photo);
$count++;
$count1++;
}
}
}
} else {
echo 'Le dossier n\'existe pas.';
}
dump($photos);
return $this->render('establishment/establishment.html.twig', [
'id' => $id,
'establishment' => $establishment,
'establishmentName' => $establishmentName,
'establishmentDirectory' => $establishmentDirectory,
'buttons' => $buttons,
'photos' => $photos,
]);
}
When I dump $photos in this Controller, I obtain what I'm looking to do: real paths to the photos with all slashes.
array:3 [▼
0 => "<img src="{{ asset("/ressources/uploads/establishments_pages/Chez Eros/HM_francesca-saraco-dS27XGgRyQ-unsplash-625fd4f334cbd.j ▶"
1 => "<img src="{{ asset("/ressources/uploads/establishments_pages/Chez Eros/eddi-aguirre-ZAVHbpOn4Jk-unsplash-625fd4f33559c.jpg")}}" class ▶"
2 => "<img src="{{ asset("/ressources/uploads/establishments_pages/Chez Eros/marten-bjork-n-IKQDCyrG0-unsplash-625fd4f3364ae.jpg")}}" class ▶"
]
But when Twig interprets this code, it transforms all slashes to spaces, EVEN IF I put the unescape function on false!
The TWIG code :
<div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="carousel">
{% autoescape false %}
<div class="carousel-indicators">
{% for button in buttons %}
{{ button }}
{% endfor %}
</div>
<div class="carousel-inner">
{% for photo in photos %}
{{photo}}
{% endfor %}
</div>
{% endautoescape %}
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
The result in debug toolbar on chrome:
<img src="{{ asset(" ressources="" uploads="" establishments_pages="" chez="" eros="" hm_francesca-saraco-ds27xggryq-unsplash-625fd4f334cbd.jpg")}}"="" class="d-block w-100" alt="Photo de l'hotel">
I already try to add "|raw" inline on the photo variable in TWIG, but it doesn't change anything!
Can anybody help me to keep my paths?
I would like to know if it is possible to pass variables in a modal using Symfony?
Before integrating a modal, my line looked like
<span class="glyphicon glyphicon-remove"></span> Supprimer
It is used to delete a line from my database.
I wanted to add a modal sign confirmation request.
Then I added a modal and now I have this:
<span class="glyphicon glyphicon-remove"></span> Supprimer
The modal :
<div class="modal" id="mymodal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<a href="#HereIWantMyVariablesForMyControllerPathRendering" type="button" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Is there a parameter to put in my link calling the modal, to place the variables?
EDIT:
After using macros, by Fabian, here is my code:
Views/macro/macro.html.twig:
{%- macro create_delete_modal(body, deleteLink) -%}
{% filter spaceless %}
<div id="deleteModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Supprimer?</h4>
</div>
<div class="modal-body">
<p>{{ body }}</p>
</div>
<div class="modal-footer">
Supprimer
<button type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
{% endfilter %}
{%- endmacro -%}
Controller delete fonction:
/**
* Suppression d'un package | Suppression d'un type d'utilisateur attribué à un package
*
* #Route("/{id}/{type}/delete", name="paquets_delete")
*/
public function deleteAction(Request $request, $id, $type)
{
$em = $this->getDoctrine()->getManager();
$unPaquet = $em->getRepository('PagesBundle:Paquet')->find($id); //Récupération du package
$nbTypes = count($unPaquet->getTypeUser()); //Récupération du nombre de TypeUser auquel est attribué le package
if($nbTypes == 1)
{
$em->remove($unPaquet); // Si un seul destinataire, on supprimme le package.
}
else if($nbTypes > 1)
{
$am = $this->getDoctrine()->getManager();
$leType = $am->getRepository('PagesBundle:TypeUser')->findByTypeUtilisateur($type);
$unPaquet->deleteTypeFromTypesUser($leType[0]); // Si plusieurs destinataires, on supprimme juste le type d'utilisateur passé en paramètre
}
$em->flush(); // Validation
$this->getDoctrine()->getManager()->getRepository('PagesBundle:User')->updateNbDDLAll("dec"); // A la suppression d'un package, on décrémente le nombre de télécharme
$this->addFlash( // Message d'information à l'admin
'info_delete',
'Package supprimée !'
);
return $this->redirectToRoute('paquets_index'); // Actualisation de la page
}
index.html.twig :
{% extends 'base.html.twig' %}
{% import 'macro/macro.html.twig' as macro %}
{% block body %}
<br/>
<span class="glyphicon glyphicon-plus"></span> Ajouter un package
<br/> <br/>
{% for unType in typesUser %}
{% set i=loop.index0 %}
<h1 class="text-primary text-center">{{unType['typeUtilisateur']}} <span class="badge badge-primary badge-pill w3-small">{{ tabInfos[i]|length }}</span></h1>
<br />
<table class="table table-stripped">
<thead>
<tr>
<th>Id</th>
<th>Titre</th>
<th>Package</th>
<th>Notice</th>
<th>Commentaire</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for uneInfo in tabInfos[i] %}
<tr>
<td>{{ uneInfo.id }}</td>
<td>{{ uneInfo.titre }}</td>
<td><a href="{{ path('paquet_fileDDL', { 'id': uneInfo.id, 'type': 'package'}) }}"</a>{{ uneInfo.urlPaquet }} </td>
<td><a href="{{ path('paquet_fileDDL', { 'id': uneInfo.id, 'type': 'notice'}) }}"</a>{{ uneInfo.urlNotice }} </td>
<td>{{ uneInfo.commentaire }}</td>
<td>
<span class="glyphicon glyphicon-edit"></span> Modifier
{#<span class="glyphicon glyphicon-remove"></span> Supprimer #}
<button class="btn btn-danger" type="button" data-toggle="modal" data-target="#deleteModal"><span class="glyphicon glyphicon-remove"></span> Supprimer</button>
{{ macro.create_delete_modal('Voulez-vous vraiment supprimer ce package ? ', path('paquets_delete', {'id':uneInfo.id, 'type': unType['typeUtilisateur']})) }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<br/><br/>
{% endfor %}
{% endblock %}
The most important part of the html.twig:
{% for uneInfo in tabInfos[i] %}
<tr>
<td>{{ uneInfo.id }}</td>
<td>{{ uneInfo.titre }}</td>
<td><a href="{{ path('paquet_fileDDL', { 'id': uneInfo.id, 'type': 'package'}) }}"</a>{{ uneInfo.urlPaquet }} </td>
<td><a href="{{ path('paquet_fileDDL', { 'id': uneInfo.id, 'type': 'notice'}) }}"</a>{{ uneInfo.urlNotice }} </td>
<td>{{ uneInfo.commentaire }}</td>
<td>
<span class="glyphicon glyphicon-edit"></span> Modifier
<button class="btn btn-danger" type="button" data-toggle="modal" data-target="#deleteModal"><span class="glyphicon glyphicon-remove"></span> Supprimer</button>
{{ macro.create_delete_modal('Voulez-vous vraiment supprimer ce package ? ', path('paquets_delete', {'id':uneInfo.id, 'type': unType['typeUtilisateur']})) }}
</td>
</tr>
{% endfor %}
The problem: it removes the first packages, not the ones I want to delete
I would recomment you to use a macro for your modal. This one you can reuse everytime you want. This would look something like this:
{%- macro create_delete_modal(body, deleteLink) -%}
{% filter spaceless %}
<div id="deleteModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Supprimer?</h4>
</div>
<div class="modal-body">
<p>{{ body }}</p>
</div>
<div class="modal-footer">
Supprimer
<button type="button" class="btn btn-default" data-dismiss="modal">close</button>
</div>
</div>
</div>
</div>
{% endfilter %}
{%- endmacro -%}
And to use it:
{% import 'macro/macro.html.twig' as macro %}
{{ macro.create_delete_modal('Are you sure you want to delete this?', path('paquets_delete', { 'id': uneInfo.id, 'type':unType['typeUtilisateur'] }) }}
<button class="btn btn-danger" type="button" data-toggle="modal" data-target="#deleteModal"><span class="glyphicon glyphicon-remove"></span> Supprimer</button>
Edit
The id of the modal (id="#deleteModal") is not unique any more, as you loop over it. Simply add the current loop index to it and it will work as expected.
{%- macro create_delete_modal(id, body, deleteLink) -%}
{% filter spaceless %}
<div id="{{ id }}" class="modal fade" role="dialog">
And in your loop pass the loop index:
{% for uneInfo in tabInfos[i] %}
<tr>
<td>
<button class="btn btn-danger" type="button" data-toggle="modal" data-target="#deleteModal-{{ uneInfo.id }}"><span class="glyphicon glyphicon-remove"></span> Supprimer</button>
{{ macro.create_delete_modal('deleteModal-'~uneInfo.id, 'Voulez-vous vraiment supprimer ce package ? ', path('paquets_delete', {'id':uneInfo.id, 'type': unType['typeUtilisateur']})) }}
</td>
</tr>
{% endfor %}
i'm using Symfony 3.3.9 and when I'm trying to render a form I have the following error:
An exception has been thrown during the rendering of a template
("Unable to render the form because the block names array contains
duplicates: "_fos_user_registration_form_errors", "user_errors",
"user_errors", "fos_user_registration_errors", "form_errors".").
Thank you in advance for your help !
EDIT 17/09/2017
Here you go:
public function indexAction()
{
/** #var $formFactory FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
$form = $formFactory->createForm();
return $this->render('AppTMMainBundle:Default:index.html.twig', array(
'form' => $form->createView(),
));
}
My Twig:
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register')}) }}
<div class="card-content">
<h3 class="text-center title" style="color: #3C4858;margin:10px 0;">Inscription</h3>
<div class="social text-center">
<a class="btn btn-just-icon btn-round btn-facebook" href="{{ path('hwi_oauth_service_redirect',{'service': 'facebook'}) }}">
<i class="fa fa-facebook"> </i>
</a>
<a class="btn btn-just-icon btn-round btn-twitter" href="{{ path('hwi_oauth_service_redirect',{'service': 'twitter'}) }}">
<i class="fa fa-twitter"></i>
</a>
<a class="btn btn-just-icon btn-round btn-google" href="{{ path('hwi_oauth_service_redirect',{'service': 'google'}) }}">
<i class="fa fa-google-plus"></i>
</a>
</div>
<p class="description text-center">Ou de façon plus classique</p>
<div class="row">
<div class="col-xs-6">
{{ form_label(form.firstname) }}
{{ form_widget(form.firstname) }}
</div>
<div class="col-xs-6">
{{ form_label(form.lastname) }}
{{ form_widget(form.lastname) }}
</div>
</div>
<div class="row">
<div class="col-xs-12">
{{ form_label(form.email) }}
{{ form_widget(form.email) }}
</div>
</div>
<div class="row">
<div class="col-xs-6">
{{ form_widget(form.plainPassword.first, {'attr': {'class': 'form-control', 'placeholder': 'form.password'}}) }}
</div>
<div class="col-xs-6">
{{ form_widget(form.plainPassword.second, {'attr': {'class': 'form-control', 'placeholder': 'form.password_confirmation'}}) }}
</div>
</div>
<!-- If you want to add a checkbox to this form, uncomment this code -->
<div class="input-group">
<div class="checkbox">
<label>
<input type="checkbox" name="optionsCheckboxes" checked="">
{{ 'index.proceed.agree'|trans }} {{ 'index.proceed.cgu'|trans }}.
</label>
</div>
</div>
<div class="footer text-center">
<input type="submit" class="btn btn-primary btn-round" value="{{ 'index.action.subscribe'|trans }}">
</div>
</div>
{{ form_end(form) }}
for anyone having such an exception:
You probably shouldn't extend a form type, but instead create your own and use getParent to inherit the behaviour.
And if your class name is the same as an other type (excluding namespaces)
you must override the getBlockPrefix from AbstractType.
The getBlockPrefix method from AbstractType uses the last part of fqcn (the class name) and you could have a duplicate block name.
I found the answer to my question.
That was from my RegistrationType class where I was trying to extends with another Type Class. getParent not working as well expected...
RegistrationType > UserType > FOS\UserBundle\Form\Type\RegistrationFormType
I move all fields from UserType in RegistrationType and it's working :)
I have tried this code in my twig : some stupid tests :/
<form class="form-horizontal" id="form-search" action="{{path('search_robe')}}" method="POST" enctype="multipart/form-data">
{% for robeoption in robeoptions %}
{% if robeoption.values|length>0 %}
<div class="col-md-3 col-sm-3 col-xs-3 ">
<div class="Robeoption-title">
{{robeoption.translate.title}}
</div>
<div class="Robeoption-value">
{% for robeoptionval in robeoption.values %}
<label>
<input type="checkbox" class="radio" value="1" name="{{robeoption.translate.title}}" />{{robeoptionval.translate.title}}</label>
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
</form>
I have this code in my Form Type
class SearchrobeType extends AbstractType {
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('robeoptions', 'entity', array(
'required' => false,
'class' => 'BrainAdminBundle:RobeOption',
/** #Ignore */
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('s')
->Join('s.values', 'values')
->groupBy('s.id');
},
'label' => true,
'multiple' => true,
'expanded' => true,
))
->add('robeoptionvalue', 'entity', array(
'required' => false,
'class' => 'BrainAdminBundle:RobeOptionValue',
/** #Ignore */
'label' => false,
'multiple' => true,
'expanded' => true,
))
;
}
So, the point is that i Have Two entities : robeoption and robeoptionvalues which have a oneTomany relation , I'm new to Symfony and I want to use the formBuilder in my twig so it will be something like that instead :
<form class="form-horizontal" id="form-search" action="{{path('search_robe')}}" method="POST" enctype="multipart/form-data">
{{form_widget(form.robeoptions)}} //
{{form_widget(form.robeoptionvalue)}}
</form>
I want to show each Robeoption in a label and just under each one its Robeoptionsvalue with an input checkbox button, Any help plz?
There is only one way to do that : it's to do it dynamically from my twig `
<form class="form-horizontal col-md-12 col-sm-12 col-xs-12" id="form-search" action="{{path('searchrobe')}}" method="POST" enctype="multipart/form-data">
<div class="sh" style="display:none;">
{{form_row(form._token)}}
<div class="col-md-12 col-sm-6 search-slide">
{% for robeoption in robeoptions %}
{% if robeoption.values|length>0 %}
<div class="col-md-4 col-sm-4 col-xs-4 ">
<div class="Robeoption-title">
<label> {{robeoption.translate.title}} </label>
</div>
<div class="Robeoption-value">
{% for robeoptionval in robeoption.values %}
<input type="checkbox" name="robeoptionValues[{{robeoptionval.id}}]" />{{robeoptionval.translate.title}}<br>
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
</div>
<div class="col-md-12 col-sm-12 search-slide">
<div class="col-md-12 col-sm-12 contour">
<button class="btn btn-default btn-slider">{{'search'|trans({})}}</button>
</div>
</div>
</div>
</form>
And then get the array of options from controller
if ($_request->getMethod() == 'POST') {
$optionsvalues=$_request->request->get('robeoptionValues');
$robe = $_em->getRepository('BrainAdminBundle:Robe')->searchforRobes($optionsvalues);
}
searchforRobes($optionsvalues); Is a function in the Robe Repository
I'm developping a blog using Symfony 2.7. I've an ArticleBundle and a CommentBundle. My entities Article and Comment are linked by a ManyToOne relation.
When I try to send a comment, it fails. The $form->isValid() method returns false.
Here, my add method to send a comment :
public function addAction(Article $article, Request $request){
$comment = new Comment();
$form = $this->createForm(new CommentType(), $comment);
$form->handleRequest($request);
if($form->isValid()){
$comment->setArticle($article);
$em = $this->getDoctrine()->getManager();
$em->persist($comment);
$em->flush();
return $this->redirect($this->generateUrl('esgi_article_view', array(
'id' => $article->getId()
)));
} else{
return $this->render('ESGICommentBundle:Comment:add.html.twig', array(
'form' => $form->createView(),
'article' => $article
));
}
}
My comment form is inclued into article's view like this :
{{ render(controller("ESGICommentBundle:Comment:add", { 'id' : article.id })) }}
And here my form :
{{ form_start(form) }}
<div class="form-group">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-8">
{{ form_label(form.author, "Auteur") }}
{{ form_widget(form.author, { 'attr' : { 'class' : 'form-control' } }) }}
{{ form_errors(form.author) }}
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-8">
{{ form_label(form.email, "Email (optionnel)") }}
{{ form_widget(form.email, { 'attr' : { 'class' : 'form-control' } }) }}
{{ form_errors(form.email) }}
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-8">
{{ form_label(form.content, "Commentaire") }}
{{ form_widget(form.content, { 'attr' : { 'class' : 'form-control' } }) }}
{{ form_errors(form.content) }}
</div>
</div>
</div>
<button class="btn btn-success" type="submit">Poster</button>
{{ form_end(form) }}
Thanks, have a nice day !
IF you submit the form, you should have all the errors in the profiler bar(there is a form icon which you can click to see errors in the submitted form)