Count content of columns in table symfony2/twig/doctrine - php

So I have this table created with a crud in my symfony2 project. The table displays different products with each their own price. I would like to have a output with the total value of all products at the bottom of the table.
index.html.twig of entity "waarde"
{% extends '::base.html.twig' %}
{% block body -%}
<h1>Waarde voorraad</h1>
<table class="records_list">
<thead>
<tr>
<th>Product</th>
<th>Type</th>
<th>Fabriek</th>
<th>Aantal</th>
<th>Prijs</th>
<th>Inkoop Waarde</th>
<th>Verkoop Waarde</th>
<th>Locatie</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td>{{ entity.getProduct().getNaam() }}</td>
<td>{{ entity.getProduct().getType() }}</td>
<td>{{ entity.getProduct().getFabriek() }}</td>
<td>{{ entity.aantal }}</td>
<td>{{ entity.getProduct().getInkoopprijs() }}</td>
<td>{{ entity.getProduct().getInkoopprijs() * entity.aantal }}</td>
<td>{{ entity.getProduct().getVerkoopprijs() * entity.aantal }}</td>
<td>{{ entity.getLocatie().getLocatienaam() }}</td>
<td>
<ul>
<li>
show
</li>
<li>
edit
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a href="{{ path('waarde_new') }}">
Create a new entry
</a>
</li>
</ul>
{% endblock %}
I have a association between the entities "Product" and "Waarde"(=value).
<td>{{ entity.getProduct().getInkoopprijs() }}</td>
The code above returns the price of a product. I already have done a simple code to calculate the value of a single product by this code ("aantal" = quantity/amount of products)
<td>{{ entity.getProduct().getInkoopprijs() * entity.aantal }}</td>

{% set sum = 0 %}
{% for entity in entities %}
{% set sum = sum + (entity.getProduct().getInkoopprijs() * entity.aantal) %}
{% endfor %}
Total price: {{ sum }}

Related

Tables side by side

How can I put two arrays side by side using twig ?
This is my input
{% for key, item in CompareArray %}
{% for x in item %}
<tr>
{% if key =='last' %}
<td> last</td>
{% endif %}
{% if key == 'primary' %}
<td> primary</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
The desired output
table,td{
border: 1px solid black;
padding: 1px;
}
<table>
<tr>
<td> last.val1 </td>
<td> last.val2 </td>
<td> last.val3 </td>
<td> #### </td>
<td> primary.val1 </td>
<td> primary.val2 </td>
<td> primary.val3 </td>
</tr>
<tr>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
</tr>
<table>
Based on the shared information I see a couple of possible solutions.
But first confirm if I understand correctly what you're trying to achieve.
You want to have table where the item information of the last group is displayed first with a separator column and then the item information of the primary group on the left? And as seen in the screen shot of the array the number of items in the group isn't even necessarily the same?
First think to consider would be should we create two different tables one for primary group and one for last and style them through css to look as if they're in they are side by side.
{% for groupKey, items in CompareArray %}
<table>
{% for item in items %}
<tr>
<td>{{ groupKey }}.{{ item.prop1 }}</td>
<td>{{ groupKey }}.{{ item.prop2 }}</td>
<td>{{ groupKey }}.{{ item.prop3 }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
Second solution would be a complicated use of attribute this means that both arrays have to have same keys. Here you'd iterate over the largest group and then add the corresponding value from the other group. I'm using some macros to better separate the logic. The block named myTemplate is the code you'd insert where you wanted the data to be displayed.
{% block myTemplate %}
{% if CompareArray.last|length > CompareArray.primary|length %}
{{ _self.lastIsLonger(CompareArray.last, CompareArray.primary) }}
{% else %}
{{ _self.primaryIsLonger(CompareArray.last, CompareArray.primary) }}
{% endif %}
{% endblock %}
{% macro lastIsLonger(lastGroup, primaryGroup) %}
{% set primaryLenght = primaryGroup|length %}
<table>
{% for k,item in lastGroup %}
<tr>
{{ _self.buildElementData(item) }}
<td> #### </td>
{{ _self.buildElementData(loop.index <= primaryLenght ? attribute(primaryGroup, k) : {}) }}
</tr>
{% endfor %}
</table>
{% endmacro %}
{% macro primaryIsLonger(lastGroup, primaryGroup) %}
{% set lastGroupLength = lastGroup|length %}
<table>
{% for k,item in primaryGroup %}
<tr>
{{ _self.buildElementData(loop.index <= lastGroupLength ? attribute(lastGroup, k) : {}) }}
<td> #### </td>
{{ _self.buildElementData(item) }}
</tr>
{% endfor %}
</table>
{% endmacro %}
{% macro buildElementData(item) %}
<td>{{ item.prop1 ?? '' }}</td>
<td>{{ item.prop2 ?? '' }}</td>
<td>{{ item.prop3 ?? '' }}</td>
{% endmacro %}
If I understand what you're doing I think a third solution I think would be best. That is that from the PHP side you matched which items you wanted to compare so the data you'd insert would look something like this:
[
[
'last' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
'primary' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
], [
'last' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
'primary' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
]
];
This way you're not relying on dirty tricks and do most of the logic where it belongs. The corresponding generation template generation is thus much more pleasing.
{% block myTemplate %}
<table>
{% for row in CompareArray %}
<tr>
{{ _self.buildElementData(row.last ?? {}) }}
<td> #### </td>
{{ _self.buildElementData(row.primary ?? {}) }}
</tr>
{% endfor %}
</table>
{% endblock %}
{% macro buildElementData(item) %}
<td>{{ item.prop1 ?? '' }}</td>
<td>{{ item.prop2 ?? '' }}</td>
<td>{{ item.prop3 ?? '' }}</td>
{% endmacro %}

get fields of an object with twig

I have a problem on a personal project and need your help.
I have an entity bien, users can list all bien entities from the database in a table with all the fields of the entity. I'd like to make an administration page where people with proper access can choose the fields to display on this listing.
I created a system with a JSON file ("field" => <boolean>). I can get the admin choice and create the appropriate JSON, however there is a problem when I try to display the list with only the fields that are set to true. I wanted to display it with something like this: (you can see the former way to display the table which is now commented)
{% for bien in biens %}
<tr>
{% for categorie, affichage in donnee %}
{% if affichage %}
<td>{{ bien.{{ categorie }}}}</td>
{% endif %}
{% endfor %}
{# former way #}
<td>{{ bien.id }}</td>
<td>{{ bien.titre }}</td>
<td>{{ bien.description }}</td>
<td>{{ bien.type }}</td>
<td>{{ bien.surfaceHabitable }}</td>
<td>{{ bien.nombrePiece }}</td>
<td>{{ bien.nombreEtage }}</td>
<td>{% if bien.sousSol %}Yes{% else %}No{% endif %}</td>
<td>{{ bien.prix }}</td>
<td>{{ bien.honoraire }}</td>
<td>{{ bien.charge }}</td>
<td>{{ bien.adresse }}</td>
<td>{{ bien.codePostal }}</td>
<td>{{ bien.ville }}</td>#}
<td>
<ul>
<li>
Voir
</li>
<li>
Editer
</li>
</ul>
</td>
{# end former way #}
</tr>
{% endfor %}
But I have an error on the line
<td>{{ bien.{{ categorie }}}}</td>
Expected name or number.
I think I am not making it the right way (I also tried {{ bien.categorie }}without goodthe proper result).
Thank you for your help ;)

translate tabledata in twig

I fill my table with data in this way
<tbody>
{% for post in posts %}
<tr>
<td>{{ post.title }}</td>
<td>{{ post.status }}</td>
</tr>
{% endfor %}
</tbody>
I need translate values from status, but it does not work. post.status has only 2 values in database PO_DRAFT and PO_ACCEPT and I need it translate. Is it possible?
I tried in this way but it is wrong
<td>{% trans %}{{ post.status }}{% endtrans %}</td>
Twig's i18n documentation mentions a trans filter, so maybe this would work?
{{ post.status | trans }}

Twig doesn't approximate number

I have a strange situation. My code is :
{% set total_amount=0 %}
{% for result in a_result %}
<tr>
<td>{% set total_amount=total_amount+("%.2f"|format(result.tva*result.prix_ht)) %}
{{ "%.2f"|format(result.tva*result.prix_ht) }}
</td>
/tr>
{% endfor %}
<tr>
<td colspan="5">Total</td>
<td>{{ total_amount }}</td>
</tr>
As result I have :
15.98, 25.49, 25.49
And Total = 65 but total should be equal with 65.96. I don't understand where is the problem. Can you help me please ?
I suggest you to use the round and number_format filter as follow:
{% set total_amount=0 %}
{% for result in a_result %}
{% set value = (result.tva* result.prix_ht)|round(2) %}
{% set total_amount=total_amount+value %}
<tr>
<td>
{{ value|number_format(2, '.', ',') }}
</td>
/tr>
{% endfor %}
<tr>
<td colspan="5">Total</td>
<td>{{ total_amount|number_format(2, '.', ',') }}</td>
</tr>
A running example with sample data in this twigfiddle files
Hope this help

How can I order my table's columns using a keyword?

My column is currently {article, formation , tous article , tous formation, notif, offre}. I want to make it in this order {article, tous articles , espace&nbsp, formation , tous formation , &nbsp, notif , offre}
This is my code, the td is named: ban.page
<table id="liste-offresemploi" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th width="5">#</th>
<th>Titre 1</th>
<th>Type</th>
<th>Page</th>
<th>pagetest</th>
<th width="20">Statut</th>
<th>URL</th>
<th width="5"></th>
<th width="5" class="header"></th>
</tr>
</thead>
<tbody>
{% if nb_bannieres > 0 %}
{% for bann in bannieres %}
<tr>
<td>{{ bann.idbanniereinterne }}</td>
<td>{{ bann.titre }}</td>
<td>{% if bann.type == 2 %} Publicité {% else %} {% if bann.type == 1 %} Structure {% endif %} {% endif %}</td>
<td id="tri">{{bann.page }}</td>
<td>{% if bann.page == "articles" %} 0 {% else %} {% if bann.page == "toutarticles" %} 1 {% endif %} {% endif %} </td>
<td><a href="#?" class="toogleactif" name="banniereinterne-{{ bann.idbanniereinterne }}" rel="{% if bann.actif %}0{% else %}1{% endif %}">
{% if bann.actif %}
<button class="btn btn-success actifjs">Actif</button>
{% else %}
<button class="btn btn-warning actifjs">Non Actif</button>
{% endif %}
</a>
</td>
<td>{{ bann.url }}</td>
<td><span class="glyphicon glyphicon-edit btnadmin btnedit" title="Editer" rel="table_banniereinterne|id_{{ bann.idbanniereinterne }}"></span></td>
<td><span class="glyphicon glyphicon-trash btnadmin deladmin" title="Supprimer" rel="{{ bann.idbanniereinterne }}|banniereinterne|0"></span></td>
</tr>
An easy solution is to add in your entity a field order (type int) and give the order value
Category | Order
------------ | ------
article | 2
formation | 3
tous article | 1
And then order in your query by this Order column ASC and you will get
tous article
article
formation

Categories