Symfony Datatables button pages don't work - symfony

I'm using DataTables but I don't understand why in table my symfony page don't work when i press page 2,3 etc..
my html code is
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
{{ form_start(form,{'attr':{'novalidate':'novalidate'}}) }}
<div class="row" >
<div class=" col-md-4 form-group">
{{ form_row(form.data_inizio,{'attr':{'class':'form-control'}}) }}
</div>
<div class=" col-md-4 form-group">
{{ form_row(form.data_fine,{'attr':{'class':'form-control'}}) }}
</div>
<div class="col-md-4 form-group">
{{ form_row(form.Stampa,{'attr':{'class':'form-control'}}) }}
</div>
</div>
</div>
{{ form_end(form) }}
{#</div>#}
<div class=row">
<div class="col-md-6">
<h1>Elenco Analisi</h1>
</div>
<div class="col-md-6">
{# <p style="text-align:right;width:100%;">
<span style="font-weight:bold;">Totale:</span> <input type="text" id="totale" name="totale" maxlength="50" disabled/>
</p>#}
</div>
</div>
<table id="tblSearch" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Id</th>
<th>Codice</th>
<th>Effettuato da</th>
<th>Data</th>
<th>Proprietario</th>
<th>Autorizzata da </th>
<th>Laboratorio</th>
<th>Edit</th>
<th>Stampa</t>
<th>Accettazione</th>
<th>Totale</th>
<th>Totale Scontato</th>
<th>File</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Id</th>
<th>Codice</th>
<th>Effettuato da</th>
<th>Data</th>
<th>Proprietario</th>
<th>Autorizzata da </th>
<th>Laboratorio</th>
<th>Edit</th>
<th>Stampa</th>
<th>Accettazione</th>
<th>Totale</th>
<th>Totale Scontato</th>
<th>File</th>
</tr>
</tfoot>
<tbody>
{% for singola_analisi in analisi %}
<tr>
<td>{{singola_analisi.id}}</td>
<td>{{singola_analisi.codice}}</td>
<td>{{singola_analisi.idUser.nome}}</td>
<td>{{ singola_analisi.data|date('d-m-Y') }}</td>
<td>{{singola_analisi.idProprietario.ragionesociale}} </td>
<td>{{singola_analisi.autoriazzatada.nome}} {{singola_analisi.autoriazzatada.cognome}}</td>
<td>{{singola_analisi.idLaboratorio.nome}}</td>
{# <td><i class="glyphicon glyphicon-plus"></i></td>#}
{# #}
{% if is_granted('ROLE_ADMIN') %}
{# se è sua l'analisi#}
{% if user.id==singola_analisi.iduser.id %}
{% if singola_analisi.stato == 1 %}
<td><i class="fa fa-cogs" aria-hidden="true"></i></td>
<td><i class="fa fa-file" aria-hidden="true"></i></td>
<td>
<button type="button">Accetta</button>
<button style="margin-top:2px;" type="button">Rifiuta </button>
</td>
{% elseif singola_analisi.stato == 2%}
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><i class="fa fa-file" aria-hidden="true"></i></td>
<td>
<button type="button">Accetta</button>
<button style="margin-top:2px;" type="button">Rifiuta </button>
</td>
{% else %}
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><i class="fa fa-file" aria-hidden="true"></i></td>
<td>Accettata</td>
{% endif %}
{% else %}
{% if singola_analisi.stato == 1 %}
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td>In Elaborazione</td>
{% elseif singola_analisi.stato == 2%}
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><i class="fa fa-file" aria-hidden="true"></i></td>
<td>
<button type="button">Accetta</button>
<button style="margin-top:2px;" type="button">Rifiuta </button>
</td>
{% else %}
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><i class="fa fa-file" aria-hidden="true"></i></td>
<td>Accettata</td>
{% endif %}
{% endif %}
{% else %}
{% if singola_analisi.stato == 1 %}
<td><i class="fa fa-cogs" aria-hidden="true"></i></td>
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><button type="button">Richiedi accettazione</button></td>
{% elseif singola_analisi.stato == 2%}
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td>Accettazione in attesa</td>
{% else %}
<td><i class="fa fa-times" aria-hidden="true"></i></td>
<td><i class="fa fa-file" aria-hidden="true"></i></td>
<td>Accettato</td>
{% endif %}
{% endif %}
<td>{{singola_analisi.totale}}</td>
<td>{{singola_analisi.totalescontato}}</td>
<td>
{% if singola_analisi.path != NULL %}
<i class="fa fa-download" aria-hidden="true"></i>
{% else %}
<i class="fa fa-upload" aria-hidden="true"></i>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('js/lista_modulo.js') }}"></script>
{% endblock %}
My js code is:
$( document ).ready(function() {
$('#tblSearch').DataTable( {
"columnDefs": [
{
"targets": [ 0 ],
"visible": false,
"searchable": false,
},
],
"order": [[0, 'desc']],
} );
});
and in my base.html file there is:
{% block stylesheets %}
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
{# <link href="{{ asset('css/jqueryautocomplete/autocomplete.css') }}" rel="stylesheet">#}
<link href="{{ asset('css/bootstrap-chosen/bootstrap-chosen.css') }}" rel="stylesheet">
<link href="{{ asset('css/template_base.css') }}" rel="stylesheet">
<link rel="stylesheet" href="{{asset('css/font-awesome/css/font-awesome.min.css')}}">
<link href="{{asset('js/plugins/data-tables/css/jquery.dataTables.min.css')}}" type="text/css" rel="stylesheet" media="screen,projection">
{% endblock %}
{% block javascripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="{{asset('js/jqueryautocomplete/chosen.jquery.js')}}"</script>
<script type="text/javascript" src="{{asset('js/plugins/data-tables/data-tables-script.js')}}"></script>
<script type="text/javascript" src="{{asset('js/plugins/data-tables/js/jquery.dataTables.js')}}"></script>
<script type="text/javascript" src="{{asset('js/plugins/data-tables/js/dataTables.bootstrap.js')}}"></script>
{% endblock %}
i try to load also a example from tutorial but still page button don't work .
I see some forum but noting help me to undestard my problem .
Please can help me to understand?
Thanks

Related

Symfony 3.4 - Passing variables in my modals?

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 %}

Grid and cards issues with Bootstrap

I almost finish a very important part in my Django project by creating panels which contains some cards. I'm using Bootstrap 3 (BS3) and I integrated cards from BS4 to BS3.
I'm getting an issue and I would like to get your mind because the behaviour is a little bit weird.
My issue :
As you can see in the animated picture below, there is an offset when I open dropdown from Publication n°1 and Publication n°2. It creates an offset with cards from the second row.
[![enter image description here][1]][1]
My question is : How I can rewrite bootstrap part in my code in order to make a normal behaviour ?
What I would like to get for each card:
This is what I would like for each card : open the card > make an offset to the entire row below
[![enter image description here][2]][2]
What I have and I don't want as behaviour :
And don't have a behaviour like that :
[![enter image description here][3]][3]
My code :
This is my entire code :
{% for category in research_categories|dictsort:'name' %}
<div class="panel-group accordion" id="accordion_{{ category.id }}" role="tablist"
aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion_{{ category.id }}"
href="#collapseOne_{{ category.id }}" aria-expanded="true" aria-controls="collapseOne">
<i class="more-less glyphicon glyphicon-plus"></i>
{{ category }}
{% for item in category.publication.all %}
{% if item.new_publication == True %}
<span class="glyphicon glyphicon-flag"></span>
{% endif %}
{% endfor %}
</a>
</h4>
</div>
<div id="collapseOne_{{ category.id }}" class="panel-collapse collapse" role="tabpanel"
aria-labelledby="#accordion_{{ category.id }}">
<div class="panel panel-default subpanel ">
<div class="row">
{% for element in research_publications|dictsort:'pub_id' %}
{% if element.category|stringformat:"s" == category|stringformat:"s" %}
<div class="col-md-4">
<div class="card" style="width:350px">
<img class="card-img-top" style="width: 350px; height: 350px" src="{{ element.cover.url }}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{ element }} - {{ element.pub_id }}
{% if element.new_publication == True %}
<span class="glyphicon glyphicon-flag"></span>
{% endif %}
</h4>
<button class="btn btn-default display-document" type="button" data-toggle="collapse"
data-target="#dropdown_{{ element.id }}"
aria-expanded="false"><span
class="glyphicon glyphicon-chevron-down"></span></button>
<div id="dropdown_{{ element.id }}" class="collapse">
<div class="publication-title">
<table class="table table-condensed">
<tbody>
{% for item in test_research %}
{% if item.publication|stringformat:"s" == element|stringformat:"s" %}
<tr>
<td class="col-md-1">
<input type="checkbox" class="fakeRadio" name="DocumentChoice"
value="{{ item.code }}">
</td>
<td class="col-md-5 document-title">{{ item.title }}</td>
<td class="col-md-1 document-language"> {{ item.language }}</td>
<td class="col-md-1">
{% if item.format == 'pdf' %}
<img src="{% static 'app/img/pdf-icon.png' %}"
style="width:20px; height:20px;"/>
{% endif %}
{% if item.format == 'epub' %}
<img src="{% static 'app/img/epub-icon.png' %}"
style="width:20px; height:20px;"/>
{% endif %}
</td>
<td class="col-md-1 document-flag">
{% if item.publication.new_publication == True %}
<span class="glyphicon glyphicon-flag"></span>
{% else %}
<span></span>
{% endif %}
</td>
<td class="col-md-1 document-cover">
{% if item.publication.cover %}
<a href="{{ item.publication.cover.url }}">
<img class="popup_image"
style="width:20px; height:20px; border-radius:2px;"
id="myImg_{{ item.id }}" src="{{ item.publication.cover.url }}">
</a>
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
And this is a simplified version from my previous code in order to try some things :
{% for category in research_categories|dictsort:'name' %}
<div class="panel-group accordion" id="accordion_{{ category.id }}" role="tablist"
aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion_{{ category.id }}"
href="#collapseOne_{{ category.id }}" aria-expanded="true" aria-controls="collapseOne">
<i class="more-less glyphicon glyphicon-plus"></i>
{{ category }}
</a>
</h4>
</div>
<div id="collapseOne_{{ category.id }}" class="panel-collapse collapse" role="tabpanel"
aria-labelledby="#accordion_{{ category.id }}">
<div class="panel panel-default subpanel ">
<div class="row">
{% for element in research_publications|dictsort:'pub_id' %}
{% if element.category|stringformat:"s" == category|stringformat:"s" %}
<div class="col-md-4">
<div class="card" style="width:350px">
<img class="card-img-top" style="width: 350px; height: 350px" src="{{ element.cover.url }}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{ element }}</h4>
<button class="btn btn-default display-document" type="button" data-toggle="collapse"
data-target="#dropdown_{{ element.id }}"
aria-expanded="false"><span
class="glyphicon glyphicon-chevron-down"></span></button>
<div id="dropdown_{{ element.id }}" class="collapse">
<div class="publication-title">
<table class="table table-condensed">
<tbody>
{% for item in test_research %}
{% if item.publication|stringformat:"s" == element|stringformat:"s" %}
<tr>
<td class="col-md-5 document-title">{{ item.title }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
I don't know if you need my css part, but I think the issue is maybe due to my bootstrap grid ?
Thank you !
That looks like a clearfix issue. Can you try adding this to your css:
.panel.panel-default.subpanel > .row > .col-md-4:nth-child(3n+1) {
clear: both;
}
Depending on your other code it might need some more variations for different screen sizes.

Twig {% if statement %} using Symfony 2

How can I access an entity attribute in Twig (using the Winzou Symfony2 tutorial on OpenClassroom)?
Category is an attribute of my class Advert which contains all my adverts. I just want to show an error message if there are no Advert entities.
Here is my accordion that lists "adverts" from my Advert entity. One accordion is for the category incident and the one other is for the category general.
<div class="well">
<div class="accordion" id="accordion2">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseGen">
<h3><i class="icon-chevron-right"></i> Incidents</h3>
</a>
</div>
<div id="collapseGen" class="accordion-body collapse">
<div class="accordion-inner">
<div class="accordion" id="accordion4">
{% for advert in listAdverts %}
{% if advert.category == "incident" %}
<div class="accordion-group">
<div class="accordion-heading decalage">
<a href="{{ path('info_view', {'id': advert.id}) }}">
<h3 class="{{ advert.category }}">{{ advert.title }}</h3>
</a>
<div>
<span>{{ advert.content|truncate(100, true, '...')|raw }}</span>
</div>
<div>
{% if (advert.UpdatedAt is empty) %}
<i>Créé par {{ advert.author }}, le {{ advert.date|date('d/m/Y') }}
à {{ advert.date|date('H:i') }}</i>
{% else %}
<i>Modifié par {{ advert.author }},
le {{ advert.updatedAt|date('d/m/Y') }}
à {{ advert.updatedAt|date('H:i') }}</i>
{% endif %}
</div>
<div>{% if advert.readers is not empty %}
<i>Vu par :
{% for reader in advert.readers %}
{{ reader.username }},
{% endfor %}
{% endif %}</i>
</div>
<br>
<div>
{% if is_granted("IS_AUTHENTICATED_FULLY") %}
<p>
<a href="{{ path('info_edit', {'id': advert.id}) }}"
class="btn btn-default">
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
Modifier
</a>
<a href="#myModal{{ advert.id }}" role="button" class="btn btn-danger"
data-toggle="modal">
<i class="fa fa-trash-o" aria-hidden="true"></i>
Supprimer
</a>
</p>
<div id="myModal{{ advert.id }}" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h3>Suppression annonce "{{ advert.title }}"</h3>
</div>
<div class="modal-body">
<p>Voulez-vous vraiment supprimer l'annonce : "{{ advert.title }}" ? </p>
</div>
<div class="modal-footer parente">
<div>Annuler</div>
<div>
<form class="nomargin"
action="{{ path('info_delete', {'id': advert.id}) }}"
method="post">
<input type="submit" value="Supprimer"
class="btn btn-danger"/>{{ form_rest(form) }}
</form>
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
{# HERE I DONT KNOW HOW TO DO IT #}
{% else %} No Advert !
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseCo">
<h3><i class="icon-chevron-right"></i> Général</h3>
</a>
</div>
<div id="collapseCo" class="accordion-body collapse">
<div class="accordion-inner">
<div class="accordion" id="accordion4">
{% for advert in listAdverts %}
{% if advert.category == "general" %}
<div class="accordion-group">
<div class="accordion-heading decalage">
<div class="accordion-heading">
<a href="{{ path('info_view', {'id': advert.id}) }}">
<h3 class="{{ advert.category }}">{{ advert.title }}</h3>
</a>
<span>{{ advert.content|truncate(100, true, '...')|raw }}</span>
<div>
{% if (advert.UpdatedAt is empty) %}
<i>Créé par {{ advert.author }}, le {{ advert.date|date('d/m/Y') }}
à {{ advert.date|date('H:i') }}</i>
{% else %}
<i>Modifié par {{ advert.author }},
le {{ advert.updatedAt|date('d/m/Y') }}
à {{ advert.updatedAt|date('H:i') }}</i>
{% endif %}
</div>
<div>{% if advert.readers is not empty %}
<i>Vu par :
{% for reader in advert.readers %}
{{ reader.username }},
{% endfor %}
{% endif %}</i>
</div>
<br>
<div>
{% if is_granted("IS_AUTHENTICATED_FULLY") %}
<p>
<a href="{{ path('info_edit', {'id': advert.id}) }}"
class="btn btn-default">
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
Modifier
</a>
<a href="#myModal{{ advert.id }}" role="button" class="btn btn-danger"
data-toggle="modal">
<i class="fa fa-trash-o" aria-hidden="true"></i>
Supprimer
</a>
</p>
<div id="myModal{{ advert.id }}" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h3>Suppression annonce "{{ advert.title }}"</h3>
</div>
<div class="modal-body">
<p>Voulez-vous vraiment supprimer l'annonce : "{{ advert.title }}" ? </p>
</div>
<div class="modal-footer parente">
<div>Annuler</div>
<div>
<form class="nomargin"
action="{{ path('info_delete', {'id': advert.id}) }}"
method="post">
<input type="submit" value="Supprimer"
class="btn btn-danger"/>{{ form_rest(form) }}
</form>
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
My error message " No Adverts !" doesnt appears..
EDIT : According to Mitchel's answer, i've tried this :
{% endif %}
{% else %}<li>No Adverts</li>
{% endfor %}
I don't know why it doesn't work when one advert is in the other category...
{% for advert in listAdverts if advert.category == "incident" %}
{% if listAdverts is empty%}
<li>No Adverts</li>
{% endif %}
{% endfor %}
That code does not work.
I'm not sure to understand your question, but if so, you can maybe try a thing like this according to the documentation:
{% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no user found</em></li>
{% endfor %}
In Twig a for statement can have an associated else. It basically means that if the for has no results, the else is used. You should put the {% endif %} before the {% else %} and it should work.

Set a menu item active, and keep it in memory using TWIG and Symfony

I'm having a problem using Twig because I have a vertical sidebar used as a menu. When the user clicked on the menu item, it add an active class. But when the user change of page, active page disapear. I know this is the behavior expected but that's what I'm here. I wanted to know if someone have an idea to keep this active class in my layout when the user click on this item, so that, when he change of page, the menu will be as he desired (i.e. active or not)
Here is my layout.html.twig file :
<!DOCTYPE HTML>
<html>
<head>
{% block head %}
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{% block title %} AcreatMailing {% endblock title %}</title>
{% block js_head %}
<script type="text/javascript" src="{{ asset('/bundles/front/components/MDBootstrap/js/jquery-3.1.1.min.js') }}"></script>
{% endblock js_head %}
{% block stylesheet %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.0/css/font-awesome.min.css">
<link href="{{ asset('/bundles/front/css/style.min.css') }}" rel="stylesheet" />
{% endblock stylesheet %}
{% endblock head %}
</head>
<body>
<div id="body">
<div class="header">
<div class="row">
<div class="col-1">
<button class="hamburger">☰</button>
</div>
<div class="col-4 offset-1">
{%- block breadcrumb -%}{%- endblock -%}
</div>
<div class="col-6">
<ul class="list-inline pull-right downMenu inline">
<li class="nav-item dropdown btn-group">
<a class="nav-link" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="false"> {% if is_granted("IS_AUTHENTICATED_REMEMBERED") %} <img src="{{ asset('/Image/contact.png') }}" class="img-circle" width="50" height="50"> {% else %} {{ 'acreat.mailing.nav.account'|trans }} {% endif %}</a>
<div class="dropdown-menu top dropdown" no-escape aria-labelledby="dropdownMenu1">
<div class="card">
<div class="card-block">
<div class="container-fuild">
<div class="row">
<div class="col-3">
<img src="{{ asset('/Image/contact.png') }}" class="img-circle" width="100" height="112">
</div>
<div class="col-9">
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
<span class="dropdown-item"><b>{{app.user.username}}</b></span>
<span class="dropdown-item">{{app.user.email}}</span>
{{ 'acreat.mailing.nav.myaccount'|trans }}
{{ 'acreat.mailing.nav.changepassword'|trans }}
{% if is_granted('ROLE_PREVIOUS_ADMIN') %}
{{'acreat.mailing.admin.impersonalisation'|trans}}
{% endif %}
</div>
</div>
<div class="card-footer text-center">
{{ 'acreat.mailing.nav.logout'|trans }}
{% else %}
{{ 'acreat.mailing.nav.login'|trans }}
</div>
{% endif %}
</div>
</div>
</div>
</li>
</ul>
<div class="search d-inline inline pull-right">
</i>
<form class="form-inline waves-effect waves-light" id="form">
<input class="form-control tags inline" id="search" type="text" placeholder="Search" onkeydown="keyDown()">
</form>
</div>
<div class="inline pull-right spanSearch">
<h5>{% block badge_research %}{% endblock %}</h5>
</div>
</div>
</div>
</div>
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
{% block navbar %}
<div class="sidebar blue-grey darken-4 no-escape" id="navbar">
<div class="user-box no-escape">
<a class="logo no-escape" href="/" title="Retour à l'accueil">
<img src ="https://www.acreat.com/sites/acreat.com/themes/acreat/images/logo.png" class="img-fluid text-center no-escape"></img>
</a>
<h5 class="text-center">{{ 'acreat.mailing.title.website'|trans }}</h5>
</div>
<div class="list-group panel no-escape" aria-expanded="true">
<i class="fa fa-dashboard margin-right"></i> <span>{{ 'acreat.mailing.nav.dashboard'|trans }}</span>
<i class="fa fa-tasks margin-right"></i><span>{{ 'acreat.mailing.nav.inbox'|trans }}<i class="fa fa-angle-down" id="wrapperArrow"></i></span>
<div class="collapse show no-escape" id="menu0">
<a href="/message/template/{{app.user.id}}" class="list-group-item no-escape" id="addmessage" data-parent="#sidebar" aria-expanded="true">
<span>{{ 'acreat.mailing.nav.addmessage'|trans }}</span>
</a>
{%- set numberNotSent = doctrine.createQueryBuilder().select('COUNT(u.id)').from('CoreBundle:Message', 'u').where("u.status !='COMPLETED'")
.andWhere("u.account = " ~ app.user.id).andWhere("u.status !='SUBMITTED'").getQuery().getResult() -%}
<a href="/message/viewNotSent" class="list-group-item no-escape" data-parent="#sidebar" id="viewNotSent" aria-expanded="true">
<span class="fixed-witdh">{{ 'acreat.mailing.nav.messagenotsent'|trans }}</span>
<span class="badge badge-primary badge-pill">{{ numberNotSent[0][1] }}</span>
</a>
{%- set numberSent = doctrine.createQueryBuilder().select('COUNT(u.id)').from('CoreBundle:Message', 'u').where("u.status ='COMPLETED'")
.andWhere("u.account = " ~ app.user.id).getQuery().getResult() -%}
<a href="/message/viewSent" class="list-group-item no-escape" id="viewSent" data-parent="#sidebar" aria-expanded="true">
<span class="fixed-witdh">{{ 'acreat.mailing.nav.messagesent'|trans }}</span>
<span class="badge badge-primary badge-pill">{{ numberSent[0][1] }}</span>
</a>
<a href="/message/viewDraft" class="list-group-item no-escape" id="draft" data-parent="#sidebar" aria-expanded="true">
<span>{{ 'acreat.mailing.nav.draft'|trans }}</span>
</a>
</div>
<i class="fa fa-list margin-right"></i> <span>{{ 'acreat.mailing.nav.mailinglist'|trans }}</span>
</i> <span>{{ 'acreat.mailing.nav.member'|trans }}</span>
{%- if is_granted('ROLE_ADMIN') -%}
<div id="adminBottom" class="no-escape">
<i class="fa fa-envelope margin-right"></i> <span >{{ 'acreat.mailing.nav.administration'|trans }}<i class="fa fa-angle-down" id="wrapperArrow2"></i></span>
<div class="collapse show no-escape" id="menu4">
{{ 'acreat.mailing.nav.administrationlist'|trans }}
{{ 'acreat.mailing.nav.administrationaccount'|trans }}
{{ 'acreat.mailing.nav.administrationnewsletter'|trans }}
{{ 'acreat.mailing.nav.administrationparameters'|trans }}
</div>
</div>
{%- endif -%}
</div>
</div>
{% endblock navbar %}
{%- endif -%}
<div id="content">
{% block body %}
{%- if app.user == false -%}
<main class="col-12 col-md-12 col-xs-12 col-lg-12 col-xl-12">
{%- else -%}
<main class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12 ">
{%- endif -%}
{% block flashmessage %}
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="alert alert-success" role="alert">
{{ flashMessage }}
</div>
{% endfor %}
{% for flashMessage in app.session.flashbag.get('fail') %}
<div class="alert alert-danger" role="alert">
{{ flashMessage }}
</div>
{% endfor %}
{% for flashMessage in app.session.flashbag.get('success') %}
<div class="alert alert-success" role="alert">
{{ flashMessage }}
</div>
{% endfor %}
{% endblock flashmessage %}
{% block main %}
<section></section>
{%- block confirmation -%}{%- endblock -%}
{% endblock main %}
{% block fos_user_content %}
{% endblock fos_user_content%}
</main>
{% endblock body %}
</div>
</div>
</body>
{% block footer %}
{% block footer_javascript %}
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
<!-- Bootstrap tooltips -->
<script type="text/javascript" src="{{ asset('/bundles/front/components/MDBootstrap/js/tether.min.js') }}"></script>
<script type="text/javascript" src="{{asset('bundles/front/components/moment/min/moment.min.js') }}"></script>
<!-- Bootstrap core JavaScript -->
<script type="text/javascript" src="{{ asset('/bundles/front/components/MDBootstrap/js/bootstrap.min.js') }}"></script>
<!-- MDB core JavaScript -->
<script type="text/javascript" src="{{ asset('/bundles/front/components/MDBootstrap/js/mdb.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('/bundles/front/components/jquery-ui/jquery-ui.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('/bundles/front/js/libraries.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('/bundles/front/js/acreatmailingfront.min.js') }}"></script>
{% endblock footer_javascript %}
{% endblock footer %}
</html>
The sidebar is inside the {% block navbar %}.
Thanks all in advance.
You can use twig's if inside the class definition of each menu item.
If the current path matches the menu item's path, then print " active " inside the class html attribute.
I found the solution with one of my teamates. I used javascript and jquery to set cookies for the menu. And then if the cookie is set i add/remove the class for my menu. Thanks all by the way.

Customize SonataAdminBundle base_edit_form.html.twig

I would like to show the map in the form generated by Sonata Admin Bundle
This is my formMapper,
class PlaceInfoAdmin extends Admin
{
public function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('lati')
->add('longi')
->add('name')
I am using ivory google map API.
Simplifying what I want to do,
put this code at the last of template used by PlaceInfoAdmin
{{ ivory_google_api([
data.map,
data.form.field.vars['autocomplete']
])}}
put this code between rendered the cide of longi and name.
{{ ivory_google_map(data.map) }}
Now I research the twig files and found out maybe form is rendered by base_edit_form.html.twig,
However where should I alter?? or How can I find this twig is called by PlaceInfoAdmin?? (not by another ****Admin class)
{% block form %}
{{ sonata_block_render_event('sonata.admin.edit.form.top', { 'admin': admin, 'object': object }) }}
{% set url = admin.id(object) is not null ? 'edit' : 'create' %}
{% if not admin.hasRoute(url)%}
<div>
{{ "form_not_available"|trans({}, "SonataAdminBundle") }}
</div>
{% else %}
<form
{% if sonata_admin.adminPool.getOption('form_type') == 'horizontal' %}class="form-horizontal"{% endif %}
role="form"
action="{% block sonata_form_action_url %}{{ admin.generateUrl(url, {'id': admin.id(object), 'uniqid': admin.uniqid, 'subclass': app.request.get('subclass')}) }}{% endblock %}"
{% if form.vars.multipart %} enctype="multipart/form-data"{% endif %}
method="POST"
{% if not sonata_admin.adminPool.getOption('html5_validate') %}novalidate="novalidate"{% endif %}
{% block sonata_form_attributes %}{% endblock %}
>
{{ include('SonataAdminBundle:Helper:render_form_dismissable_errors.html.twig') }}
{% block sonata_pre_fieldsets %}
<div class="row">
{% endblock %}
{% block sonata_tab_content %}
{% set has_tab = ((admin.formtabs|length == 1 and admin.formtabs|keys[0] != 'default') or admin.formtabs|length > 1 ) %}
<div class="col-md-12">
{% if has_tab %}
<div class="nav-tabs-custom">
<ul class="nav nav-tabs" role="tablist">
{% for name, form_tab in admin.formtabs %}
<li{% if loop.index == 1 %} class="active"{% endif %}><i class="fa fa-exclamation-circle has-errors hide" aria-hidden="true"></i> {{ name|trans({}, form_tab.translation_domain ?: admin.translationDomain) }}</li>
{% endfor %}
</ul>
<div class="tab-content">
{% for code, form_tab in admin.formtabs %}
<div class="tab-pane fade{% if loop.first %} in active{% endif %}" id="tab_{{ admin.uniqid }}_{{ loop.index }}">
<div class="box-body container-fluid">
<div class="sonata-ba-collapsed-fields">
{% if form_tab.description != false %}
<p>{{ form_tab.description|raw }}</p>
{% endif %}
{{ form_helper.render_groups(admin, form, form_tab['groups'], has_tab) }}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% else %}
{{ form_helper.render_groups(admin, form, admin.formtabs['default'].groups, has_tab) }}
{% endif %}
</div>
{% endblock %}
{% block sonata_post_fieldsets %}
</div>
{% endblock %}
{{ form_rest(form) }}
{% block formactions %}
<div class="sonata-ba-form-actions well well-small form-actions">
{% block sonata_form_actions %}
{% if app.request.isxmlhttprequest %}
{% if admin.id(object) is not null %}
<button type="submit" class="btn btn-success" name="btn_update"><i class="fa fa-save" aria-hidden="true"></i> {{ 'btn_update'|trans({}, 'SonataAdminBundle') }}</button>
{% else %}
<button type="submit" class="btn btn-success" name="btn_create"><i class="fa fa-plus-circle" aria-hidden="true"></i> {{ 'btn_create'|trans({}, 'SonataAdminBundle') }}</button>
{% endif %}
{% else %}
{% if admin.supportsPreviewMode %}
<button class="btn btn-info persist-preview" name="btn_preview" type="submit">
<i class="fa fa-eye" aria-hidden="true"></i>
{{ 'btn_preview'|trans({}, 'SonataAdminBundle') }}
</button>
{% endif %}
{% if admin.id(object) is not null %}
<button type="submit" class="btn btn-success" name="btn_update_and_edit"><i class="fa fa-save" aria-hidden="true"></i> {{ 'btn_update_and_edit_again'|trans({}, 'SonataAdminBundle') }}</button>
{% if admin.hasroute('list') and admin.isGranted('LIST') %}
<button type="submit" class="btn btn-success" name="btn_update_and_list"><i class="fa fa-save"></i> <i class="fa fa-list" aria-hidden="true"></i> {{ 'btn_update_and_return_to_list'|trans({}, 'SonataAdminBundle') }}</button>
{% endif %}
{% if admin.hasroute('delete') and admin.isGranted('DELETE', object) %}
{{ 'delete_or'|trans({}, 'SonataAdminBundle') }}
<a class="btn btn-danger" href="{{ admin.generateObjectUrl('delete', object) }}"><i class="fa fa-minus-circle" aria-hidden="true"></i> {{ 'link_delete'|trans({}, 'SonataAdminBundle') }}</a>
{% endif %}
{% if admin.isAclEnabled() and admin.hasroute('acl') and admin.isGranted('MASTER', object) %}
<a class="btn btn-info" href="{{ admin.generateObjectUrl('acl', object) }}"><i class="fa fa-users" aria-hidden="true"></i> {{ 'link_edit_acl'|trans({}, 'SonataAdminBundle') }}</a>
{% endif %}
{% else %}
{% if admin.hasroute('edit') and admin.isGranted('EDIT') %}
<button class="btn btn-success" type="submit" name="btn_create_and_edit"><i class="fa fa-save" aria-hidden="true"></i> {{ 'btn_create_and_edit_again'|trans({}, 'SonataAdminBundle') }}</button>
{% endif %}
{% if admin.hasroute('list') and admin.isGranted('LIST') %}
<button type="submit" class="btn btn-success" name="btn_create_and_list"><i class="fa fa-save"></i> <i class="fa fa-list" aria-hidden="true"></i> {{ 'btn_create_and_return_to_list'|trans({}, 'SonataAdminBundle') }}</button>
{% endif %}
<button class="btn btn-success" type="submit" name="btn_create_and_create"><i class="fa fa-plus-circle" aria-hidden="true"></i> {{ 'btn_create_and_create_a_new_one'|trans({}, 'SonataAdminBundle') }}</button>
{% endif %}
{% endif %}
{% endblock %}
</div>
{% endblock formactions %}
</form>
{% endif%}
{{ sonata_block_render_event('sonata.admin.edit.form.bottom', { 'admin': admin, 'object': object }) }}
{% endblock %}
{% endblock %}
Ho
Create a template that extends base_edit.html.twig:
{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}
{% block form %}
{# your custom code #}
{{ parent() }}
{% endblock %}
Then to make sure only the admin you want uses that template pass it in the definition of your admin service with a setTemplate call:
librinfo_crm.admin.contact:
class: Librinfo\CRMBundle\Admin\ContactAdmin
arguments: [~, Librinfo\CRMBundle\Entity\Contact, SonataAdminBundle:CRUD]
tags:
- name: sonata.admin
manager_type: orm
group: Customers Relationship Management
label: librinfo.crm.contact_admin.label
label_translator_strategy: blast_core.label.strategy.librinfo
calls:
- [ setTemplate, [edit, LibrinfoCRMBundle:OrganismAdmin:edit.html.twig]]

Resources