Get the id of an element of a GROUP_CONCAT? - php

I made a query to group all the Audits belonging to a specific Area, like in the next query.
SELECT id_Area as idArea, area.Name as area_name, GROUP_CONCAT(id_Audit) as Audits
FROM helios.fsa_audits
LEFT JOIN helios.fsa_areas area USING (id_Area)
WHERE id_Auditor='4'
GROUP BY id_Area;
As result I get this:
I made this to get a datatable in the view like this:
But What I need is to get the id of the Audit at the moment of click each button in the Auditorias.
I'm working with symfony, and I render the datatable like this:
<table aria-describedby="dataTable_info" cellspacing="0" class="table table-hover dataTable" id="dataTable" role="grid" style="width:100%;" width="100%">
<thead>
<tr>
<th>Areas</th>
<th>Auditorias</th>
</tr>
</thead>
<tbody>
{% for audit in auditsByArea %}
<tr>
<td>{{ audit.area_name }}</td>
<td>
{% for i in 1..4 %}
<input class ="auditBtn mx-2" value="{{'W' ~ i }}" href="" data-id="{{ audit.Audits }}" data-area="{{ audit.area_name }}"id="auditBtn" name="auditBtn" type='text' readonly data-toggle="modal" data-target="#auditModal"></input>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
But it does not put the one id per button(Audit), it assigns all the id's in all the buttons:
data-id="10,11,12,13"
Any idea or suggestion about how to get it?

I'm not in symfony but you should explode your group_concat result
my_array = explode({{ audit.Audits }});
then in you loop refer to the content on the array
<td>
{% for i in 1..4 %}
<input class ="auditBtn mx-2" value="{{'W' ~ i }}" href="" data-id="{{ my_array[i] }}" data-area="{{ audit.area_name }}"id="auditBtn" name="auditBtn" type='text' readonly data-toggle="modal" data-target="#auditModal"></input>
{% endfor %}
</td>

Related

KNP Pagination: How to use javascript to get paginated page contents match a given page

A project has a page that allows edit of a Meal entity. Meal has a ManyToMany relationship with a Food entity. The edit page shows a list of food already selected for the meal, along with a KNP paginated list of foods available. When an available food is clicked on the script rewrites the list of selected foods as well as rewrites the list of available foods. So far so good.
What happens, though, is the script builds the available list from the bottom up. So, for instance, if an item on page 3 is selected, the page selector will show page 3 as active but the contents of the page is that of page 1. I'd like instead to either make page 1 active or the page contents be appropriate to the active page number.
If this makes sense, here's some relevant code. (Note: It may be obvious that I'm not fluent in javascript.)
add-food.js (key variable is pageNumber):
$('td').on('click', function (e) {
foodId = $(e.currentTarget).data('foodid');
mealId = $("#mealid").data("mealid");
var pageNumber = $('li.active').first().text().trim();
var pageLimit = $("#mealid").data("pagelimit");
$packet = JSON.stringify([foodId, mealId]);
$.post('http://diet/meal/' + mealId + '/addFoodToMeal', $packet, function (response) {
editFoods = $.parseJSON(response);
var readyToEat = $.parseJSON(editFoods[0]);
var pantry = $.parseJSON(editFoods[1]);
var table = document.getElementById('ready_foods')
$('#ready_foods tr:not(:first)').remove();
$.each(readyToEat, function(key, food) {
var row = table.insertRow(-1);
var cell = row.insertCell(0);
cell.innerHTML = food;
})
var table = document.getElementById('pantry')
$('#pantry tr:not(:first)').remove();
$.each(pantry.slice(0, pageLimit), function(key, array) {
food = array.split(",");
foodId = food[0];
foodName = food[1];
var row = table.insertRow(-1);
var cell = row.insertCell(0);
cell.innerHTML = foodName;
cell.setAttribute('data-foodid', foodId);
})
});
});
edit.html.twig:
{% extends 'base.html.twig' %}
{% block title %}Edit Meal{% endblock %}
{% block body %}
<h1>Edit Meal</h1>
<div id="mealid" data-mealid="{{meal.id}}" data-pagelimit="{{ pageLimit }}"></div>
{{ form_start(form, {'attr': {'class': 'js-meal-form'}}) }}
<div class="row">
<div class="col-6">
{{ include('meal/_form.html.twig') }}
<table class="table" id="ready_foods">
<thead>
<tr>
<th>Ready to eat</th>
</tr>
</thead>
<tbody>
{% for food in meal.foods %}
<tr>
<td>{{ food.foodName }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="col-6">
{{ include('food/_foods.html.twig') }}
</div>
</div>
<button class="btn btn-info">{{ button_label|default('Save') }}</button>
{{ form_end(form) }}
back to list
{{ include('meal/_delete_form.html.twig') }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js" defer ></script>
<script>
$(document).ready(function () {
$('.js-datepicker').datepicker({
format: 'yyyy-mm-dd'
});
});
</script>
{{ encore_entry_script_tags('add-food') }}
{% endblock %}
_foods.html.twig (where pagination happens)
{# templates/food/_foods.html.twig #}
<h3>Available foods</h3>
<div class="input-group mb-3">
<input type="text"
name="q"
class="form-control"
value="{{ app.request.query.get('q') }}"
placeholder="Search..."
>
<div class="input-group-append">
<button type="submit"
class="btn btn-outline-secondary">
<span class="fa fa-search"></span>
Search
</button>
</div>
</div>
{% if pagination is not empty %}
<table class="table" id="pantry">
<thead>
<tr>
<th>Click name to add to meal</th>
</tr>
</thead>
<tbody>
{% for food in pagination %}
<tr>
<td data-foodid={{ food.id }}>{{ food.foodName }}</td>
</tr>
{% else %}
<tr>
<td colspan="3">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ knp_pagination_render(pagination) }}
{% endif %}
Turns out there's a simple way to make page 1 of the pagination active - since the first page will be rendered by the script. Two lines:
$('li.active').removeClass('active');
$('li.page-item:nth-of-type(2)').addClass('active');

Symfony Twig datatable

I'm building a Product Information Manager (PIM). Trying to build this with the symfony framework. The problem I'm facing at the moment. I'm showing my product information with datatables with the twig file example below.
{% set title = 'Product List' %}
{% extends 'table.twig' %}
{% block h1_page_header %} Product List {% endblock %}
{% block panel_heading %} Product List {% endblock %}
{% block thead %}
<tr>
<th>ID</th>
<th>Name</th>
<th>SKU</th>
<td>Actions</td>
</tr>
{% endblock %}
{% block tbody %}
{% for product in products %}
<tr>
<td>
{{ product.id }}
</td>
<td>
{{ product.name }}
</td>
<td>
SKU
</td>
<td>
<a href="{{ path('app_product_getproduct', {'id': product.id}) }}" class="btn btn-success btn-sm" >
<span class="glyphicon glyphicon-pencil"></span>
</a>
<a href="{{ path('app_product_delete', {'id': product.id}) }}" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?')">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
{% endfor %}
The problem I have now is that my database has now almost 60-70K. But my product/list/ page is not rendering due to the 70K product which I want to show in datatables. It works fine for few 2-4k Products but above this it does not render.
I did a research and found out that I can resolve my issue with server side processing. But the question I have is there a better solution / alternative to achieve my goal?
Even if server-side processing will help, some navigators may struggle to render all those elements at once. From a user point of view, that not interesting nether. Nobody will ever scroll through all the 70k products. Users are lazy :)
You should implement pagination, search-bar and filters to render a easy readable short list.
If you like JS you can implement a more elegant solution, like an infinite scroll.

PHP, symfony list data in table

This is a project for school!!!
Let's say that I want to store and show working hours in an HTML table.
I want something like, 'if' the date from DB which user added is equal to the date from the weekly calendar than show me an EDIT button else show me an ADD button?
I want to show Add for the rest of the users who didn't create any data in DB.
<table class="table" id="week">
<thead>
<tr>
<th scope="col">users</th>
{% for day in days %}
<th class="{{ day|date("D-d") }}">
<span>{{ day|date("D") }}</span>
<span>{{ day|date("d") }}</span>
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for user in users %}
<tr class="days">
<th scope="row">{{ users.username }}</th>
{% for day in days %}
<td id="my_cell {{ day|date("d-m") }}">
{% for time in findTime %}
{% if d|date("d-m-Y") == time.date|date('d-m-Y') and users.id == time.getUser().id %}
{{ time.timeFrom|date("H:i") }} - {{ time.timeTo|date("H:i") }}
{% endif %}
{% endfor %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
I am currently using DB doctrine ORM on symfony 3.4v
I don't have an idea how to solve this problem, I tried with different array function in PHP but I did not find solutions.
Thank you for understanding.

Get key name of array value in twig for loop

I'm trying to have twig to output the key name(column name from mysql data).
What I want to do is basicly: <a class="listquestions" href="#" id="{{ key }}"...
Current codebase:
<table id="listquestions" class="table table-striped table-bordered table-hover" cellspacing="0" width="100%">
<thead>
<tr>
{% for key, answer in answers[0] %}
<th>{{ key }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for key,answer in answers %}
<tr>
<td>{{ answer.a_id }}</td>
<td>
<a class="listquestions" href="#" data-name="a_text" data-type="text" data-pk="{{ answer.a_id }}" data-url="{{ path_for('qa.edit') }}" data-title="enter attribute name">
{{ answer.a_text }}
</a>
</td>
<td>
<a class="listquestions" href="#" data-name="a_attribute_name" data-type="text" data-pk="{{ answer.a_id }}" data-url="{{ path_for('qa.edit') }}" data-title="enter attribute name">
{{ answer.a_attribute_name}}
</a>
</td>
</tr>
{% endfor %}
</tbody>
PHP function var_export($data,true) outputs:
array (
0 =>
array (
'a_id' => '1',
'a_text' => 'text',
'a_attribute_name' => 'attr',
),
1 =>
array (
'a_id' => '2',
'a_text' => 'text',
'a_attribute_name' => 'attr',
),
2 =>
array (
'a_id' => '3',
'a_text' => 'text',
'a_attribute_name' => 'attr',
),
)
I tried adding a TwigExtension that does key($answer.a_text) but key() does not work with twig for-loops.
So what am I missing? I can output the key name inside <thead> as you see but I'd like to do this with the second for-loop.
<table id="listquestions" class="table table-striped table-bordered table-hover" cellspacing="0" width="100%">
<thead>
<tr>
{% for key, answer in answers[0] %}
<th>{{ key }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for key,answer in answers %}
{% for field, value in answer %}
<tr>
{% if field == 'a_id' %}
<td>{{ answer.a_id }}</td>
{% else %}
<td>
<a class="listquestions" href="#" data-name="{{ field }}" data-type="text" data-pk="{{ answer.a_id }}" data-url="path_for('qa.edit')" data-title="enter attribute name">
{{ value }}
</a>
</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>

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