Symfony 2 - Update database on click - php

I try to update the 'archive' value of the database when I click on a check box. After searching the site and google, I managed to do it.
However, by adding a second article, it only works for the first one. If you ever have ideas, I will be grateful!
Thank you
I have fosjsroutingbundle installed.
Here is my controller :
public function archiveAction($id, Request $request)
{
if ($request->isXmlHttpRequest()) {
$em = $this->getDoctrine()->getManager();
$glasse = $em->getRepository('SosMontagesBundle:Glasse')->find($id);
$glasseArchiveStat = $glasse->getArchive();
if ($glasseArchiveStat == false) {
$glasse->setArchive(true);
$em->flush();
} else {
$glasse->setArchive(false);
$em->flush();
}
return new Response('d');
}
}
My route :
sos_montage_archive:
path: /admin/archive/{id}
defaults: { _controller: SosMontagesBundle:Admin:archive }
requirements:
id: \d+
options:
expose: true
My view :
{% extends '#SosMontages/layout.html.twig' %}
{% block content %}
<div class="col-md-6 col-md-offset-3">
<h2>Liste des lunettes</h2>
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Marque - Model</th>
<th>Description</th>
<th>Archive</th>
<th>Ordre</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for article in pagination %}
<tr {% if loop.index is odd %}class="color"{% endif %}>
<td>{{ article.id }}</td>
<td>{{ article.name ~ ' - ' ~ article.brand }}</td>
<td>{{ article.content }}</td>
{% if article.archive == false %}
<td><input type="checkbox" name="{{ article.id }}" id="archive"></td>
{% else %}
<td><input type="checkbox" name="{{ article.id }}" id="archive" checked></td>
{% endif %}
<td></td>
<td><i class="fa fa-pencil fa-2x" aria-hidden="true"></i>
<i class="fa fa-trash-o fa-2x" aria-hidden="true"></i></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="navigation">
{{ knp_pagination_render(pagination) }}
</div>
</div>
{% endblock %}
{% block javascript %}
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
<script>
$(document).ready(function () {
$("#archive").click(function () {
var id = $("#archive").attr('name');
var DATA = 'sentValue=' + id;
$.ajax({
type: "POST",
url: Routing.generate('sos_montage_archive', { id: id }),
data: DATA,
cache: false,
success: function (data) {
alert("database has been updated");
}
});
});
});
</script>
{% endblock %}

Your click listenner on your checkbox may not be correct. You should use a change listener while it's a checkbox. Change your click function in js to change:
$('#archive').change(function() {
if($(this).is(":checked")) {
//'checked' event code
return;
}
//'unchecked' event code
});
However you also have two checkboxes and only one id. This might create weird bugs. Changing your ids to #archive1 and #archive2 may fix your code.

You have to fix your HTML and differentiate your #archive id selector.
You can do that by using loop.index for example:
id="archive{{ loop.index }}" //output : archive1, archive2...
Twig doc :
http://twig.sensiolabs.org/doc/2.x/tags/for.html#the-loop-variable

Related

Method for Object does not exist?

I am new to symfony2 I'm trying to create a search function and got this
error 'Method "ediTransaction" for object "Matrix\MatrixEdiBundle\Entity\Edi997SegmentInError" does not exist in MatrixEdiBundle:Matrix:rejectedTrans.html.twig at line 58'
is it what problem is it? Anyone?
Repository
class Edi997DetailsRepository extends EntityRepository{
public function getDetails($gsNumber, $senderId, $receiverId, $page = 1, $limit = 5 ){
$em = $this->getEntityManager();
$query = $em->createQuery(
'SELECT partial a.{id, ak301, ak401},
partial b.{errorCode, condition},
partial c.{edi997DetailId, errorCodeId, noOfTrans},
partial d.{ediTransactionId, senderId, receiverId, gsNumber, isaNumber, fileName}
FROM MatrixEdiBundle:Edi997SegmentInError a
JOIN a.ediAk403ErrorCodes b
JOIN a.edi997Details c
JOIN c.ediTransaction d
WHERE d.gsNumber LIKE :gsNumber
AND d.senderId LIKE :senderId
AND d.receiverId LIKE :receiverId
AND c.errorCodeId != 1
AND d.flag = 1')
->setParameter('gsNumber', "%$gsNumber%")
->setParameter('senderId', "%$senderId%")
->setParameter('receiverId', "%$receiverId%")
->setFirstResult(($page-1)*$limit)
->setMaxResults($limit);
$paginator = new Paginator($query, $fetchJoinCollection = false );
$paginator->setUseOutputWalkers(false);
return $paginator;
}
}
Twig :
{% if transaction != null %}
{% for trans in transaction %}
<tr>
<td style="width: 11%;">
{{ render(controller('MatrixEdiBundle:Matrix:getTradingPartnerName', {'timexID' : trans.ediTransaction.receiverId, 'customerID' : trans.ediTransaction.senderId})) }}
</td>
{%
set result=render(controller('MatrixEdiBundle:Matrix:getFile', {'fileName' : trans.ediTransaction.fileName, 'senderId': trans.ediTransaction.receiverId , 'receiverId' : trans.ediTransaction.senderId }))|split('+', 4)
%}
<td style="width: 10%;">{{ result[0] }}</td>
<td style="width: 40%;">{{ result[3] }}<br><br>
{% if trans.errorCodeId == 2 %}
<span style="background-color: yellow;">Accepted but <br/>errors were <br/>noted</span><br/>
{% elseif trans.errorCodeId == 3 %}
<span style="background-color: yellow;">Partially<br/> Accepted</span><br/><br/>
{{ trans.acceptedTrans }} Accepted,<br/>
{{ trans.noOfTrans - trans.acceptedTrans }} Rejected
{% else %}
<span style="background-color: yellow;">Rejected</span>
{% endif %}
<br/>
{%
set error=render(controller('MatrixEdiBundle:Matrix:getError', {'id': trans.edi997DetailId }))|split('+')
%}
<span>
<p style="white-space: normal;">
{% if error[0] != "0" %}
{{ error[0] }}{{ "%02d"|format(error[1]) }}<br/>
{{ error[2] }}
{% else %}
Errors were not specified in 997 file
{% endif %}
</p>
</span>
</td>
<td style="width: 10%;">{{ result[2] }}</td>
<td style="width: 7%;">{{ result[1] }}</td>
<td style="width: 5%;">{{ trans.noOfTrans }}</td>
<td style="width: 7%;">{{ trans.ediTransaction.receiverId }}</td>
<td style="width: 8%;">{{ trans.ediTransaction.senderId }}</td>
<td>
<center><i class="fa fa-trash o" style="color:#1975A3;"></i></center>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="15" class="alignment result"> No Result Found </td>
</tr>
{% endif %}
The answer is in the error.
In your Edi997SegmentInError entity object, there is no ediTransaction method.
Probable causes:
The method doesn't exist in any object
The method exists in an
object, just not the one you're accessing
Looking at your repository method, that seems to be in your Edi997Details entity.
Presumably you'd access it via {{trans.edi997Details.ediTransaction.receiverId}} - but I'm really guessing there - you have to follow your object hierarchy correctly in twig. If you're not sure exactly which object you're accessing, try using {{dump(trans)}} to see what you have.

jQuery function in TWIG layout doesn't work properly

I am trying to create simple "admin" page for my blog. For now I want to create some "dynamic" behaviour which will lock/unlock user. Then I want to replace single table row with another, taken from json. I wrote a simple function but unfortunatelly it is not working properly...
When I use constant value for user id (just for tests) it works, but only for ONE row. Other buttons do nothig. Then I tried to send id to my function as a parameter but now it says it doesn't exist in my TWIG (what is true).
I want to make it work, because reloading all page when you only locked one user or did another single action, is not a good idea.
How can I make my function work in a good way?
SCRIPT
$(document).ready(function(){
$(".LockUserButton").click(function(id){
$(this).closest("tr").toggleClass('locked progress-bar-striped');
$.ajax({
type: 'POST',
url: "{{ path('lock_ajax', {'id': id }) }}",
data: { user_id: "{{ user.id }}" },
dataType: 'json',
success: function () {
$(this).closest("tr").toggleClass('locked progress-bar-striped');
}
});
});
});
TWIG
<div class="table-content">
{% for u in users %}
{% if u.locked %}
<tr id="tableRow" class="locked progress-bar-striped">
{% else %}
<tr id="tableRow" class="">
{% endif %}
{% if u.roles[0] == 'ROLE_SUPER_ADMIN' %}
<td id="roles">
<h4><span class="glyphicon glyphicon-star admin-star" data-toggle="tooltip" data-placement="right" title="{{ u.roles[0] }}"></span></h4>
</td>
<td>{{ u.username }}</td>
<td>{{ u.email }}</td>
<td>
<span class="glyphicon glyphicon-lock admin-lock" data-toggle="tooltip" data-placement="right" title="Cannot modyfi this user!"></span>
</td>
<td>
<span class="glyphicon glyphicon-lock admin-lock" data-toggle="tooltip" data-placement="right" title="Cannot modyfi this user!"></span>
</td>
{% else %}
<td id="roles">
<h4><span class="glyphicon glyphicon-star-empty user-star" data-toggle="tooltip" data-placement="right" title="{{ u.roles[0] }}"></span></h4>
</td>
<td>{{ u.username }}</td>
<td>{{ u.email }}</td>
<td>
<div class="btn btn-custom LockUserButton">LOCK USER WITHOUT RELOADING</div>
</td>
<td>
<a href="/profile/admin/delete_user/{{ u.id }}" onclick="return confirm('{{ 'user.deleting'|trans }}')">
<div class="btn btn-custom hvr-grow">
<span class="glyphicon glyphicon-trash"></span>
</div>
</a>
</td>
{% endif %}
</tr>
{% endfor %}
</div>
CONTROLLER ACTION
/**
* #Route("/profile/ajax/{id}", name="lock_ajax")
*/
public function ajaxLock($id, Request $request)
{
$entityManager = $this->getDoctrine()->getManager();
$user = $entityManager->getRepository('AppBundle:User')->find($id);
if($user->isLocked()){
$user->setLocked(false);
}else{
$user->setLocked(true);
}
$entityManager->persist($user);
$entityManager->flush();
$result = array();
$result[0] = $user;
return new JsonResponse($result);
}
Thanks to Artamiel I have finally figure it out! Here's the solition for my case:
1) I have added data-id="{{ u.id }}" attribute to my button. Now i have access to my entity ID.
2) I have modify a little my script:
$(document).ready(function(){
$(".LockUserButton").click(function(){
//get user id from twig layout
var user = $(this).data("id");
//ajax request
$.ajax({
type: 'POST',
url: "/profile/ajax/"+user,
data: { user_id: "user" },
dataType: 'json',
context: this,
success: function () {
//i've wrote some function to toggle html
$(this).toggleText('{{ 'user.unlocked'|trans }}', '{{ 'user.locked'|trans }}');
//find table row and toggle classes when button clicked and request ok
$(this).closest("tr").toggleClass('locked progress-bar-striped');
},
error: function(){
alert("Error!");
}
});
});
});

How to implement Ajax in Symfony2

I have a basic but functional search mechanism in my Symfony2 project.This will query and display back to the user the data using Doctrine2 LIKE expression.But I want to make more 'dynamic' and more 'user-friendly' by adding Ajax functionality.I added some Ajax code in my controller, but I don't know how to make it work.The image loader is just 'spinning' without displaying the results.
//controller
public function searcAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$query = $this->getRequest()->get('query');
if(!$query) {
if(!$request->isXmlHttpRequest()) {
return $this->redirect($this->generateUrl('voters_list'));
} else {
return new Response('No results.');
}
}
$city = $em->getRepository('DuterteBundle:City')->findCity($query);
if($request->isXmlHttpRequest()) {
if('*' == $query || !$city || $query == '') {
return new Response('No results.');
}
//display a another page
return $this->render('DuterteBundle:City:list1.html.twig', array('city' => $city));
}
return $this->render('DuterteBundle:City:search.html.twig', array('city' => $city));
}
// routing
search:
path: /search
defaults: { _controller:DuterteBundle:City:Searc }
requirements:
//search.html.twig
{% extends '::base.html.twig' %}
{% block body %}
<div id="city">
{% include 'DuterteBundle:City:list1.html.twig' with {'city': city} %}
</div>
{% endblock %}
//list1.html.twig
{% block body %}
<div class="page-header">
<h4>City/Municipality/Town and Its Corresponding Numbers of Voters</h4>
</div>
<table class="table table-hover table-bordered table-condensed">
<thead>
<tr>
<th>City</th>
<th>Votes</th>
<th>Percent</th>
</tr>
</thead>
<tbody>
{% for city in city %}
<tr>
<td>{{ city }}</td>
<td>{{ number_votes_city(city.id) }}</td>
<td></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
My search form is embedded in navbar in the main layout.
<div class="col-sm-3 col-md-3" id="search">
<form class="navbar-form" role="search" action ="{{ path('search')}}" method ="post">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search city/town" name="query" value="{{ app.request.get('query') }}" id="search_keywords">
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="fa fa-search"></i></button>
<img id="loader" src="{{ asset('bundles/duterte/images/loader.gif') }}" style="vertical-align: middle; display: none" />
</div>
</div>
</form>
//repository
public function findCity($city)
{
return $this
->createQueryBuilder('c')
->select('c')
->where('c.name LIKE :name_city')
->setParameter('name_city', '%'.$city.'%')
->orderBy('c.name', 'ASC')
->getQuery()
->getResult()
;
}
and finally the js file
$(document).ready(function()
{
$('.search input[type="submit"]').hide();
$('#search_keywords').keyup(function(key)
{
if(this.value.length >= 3 || this.value == '') {
$('#loader').show();
$('#city').load(
$(this).parent('form').attr('action'),
{ query: this.value ? this.value + '*' : this.value },
function() {
$('#loader').hide();
}
);
}
});
});
Any help is appreciated
The same functionality, but a different approach. Listen to the keyup event on the search box
and then make ajax calls to a controller that returns the list of matched results as json. Check the response and
based on the status of the response, hide the existing listing and replace its contents with the markup returned in the
json response for the AJAX call.
Here, the example is for search in user listing.
Table markup on the twig file
<div id="user-list-div">
<table class="records_list" id="user-list">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Username</th>
<th>Password</th>
<th>Salt</th>
<th>Email</th>
<th>Isactive</th>
<th>Createdat</th>
<th>Updatedat</th>
<th>Isbillableuser</th>
<th>Isdeleted</th>
<th>Actions</th>
</tr>
</thead>
<tbody id = "user-table">
{% for entity in entities %}
<tr>
<td>{{ entity.id }}</td>
<td>{{ entity.name }}</td>
<td>{{ entity.username }}</td>
<td>{{ entity.password }}</td>
<td>{{ entity.salt }}</td>
<td>{{ entity.email }}</td>
<td>{{ entity.isActive }}</td>
<td>{% if entity.createdAt %}{{ entity.createdAt|date('Y-m-d H:i:s') }}{% endif %}</td>
<td>{% if entity.updatedAt %}{{ entity.updatedAt|date('Y-m-d H:i:s') }}{% endif %}</td>
<td>{{ entity.isBillableUser }}</td>
<td>{{ entity.isDeleted }}</td>
<td>
<ul>
<li>
show
</li>
<li>
edit
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
Search form markup
<div class="col-lg-6">
<div class="input-group">
<input type="text" class="form-control" id="search-field">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
</div>
</div>
javascript part
<script>
$(function(){
console.log('desperate for');
var searchField = $('#search-field');
var userTable = $('#user-table');
var userListDiv = $('#user-list-div');
searchField.keyup(function(evt){
console.log($(this).val());
$.ajax({
url: '{{ path('admin_user_search') }}',
method: "POST",
data: "id=" + $(this).val() ,
dataType: 'html',
success: function(result, request) {
var parsedData =JSON.parse(result);
console.log(parsedData);
if(parsedData.status ==='success'){
console.log('hete');
userListDiv.empty();
userListDiv.html(parsedData.data);
}else{
//handle no result case
}
}
});
});
});
</script>
ajax_template.html.twig file
The same table markup as given above
controller action
public function searchuserAction(){
$em = $this->getDoctrine()->getManager();
$request = $this->get('request');
$searchParameter = $request->request->get('id');
//call repository function
$entities = $em->getRepository('LBCoreBundle:User')->findUsersForname($searchParameter);
$status = 'error';
$html = '';
if($entities){
$data = $this->render('LBCoreBundle:User:ajax_template.html.twig', array(
'entities' => $entities,
));
$status = 'success';
$html = $data->getContent();
}
$jsonArray = array(
'status' => $status,
'data' => $html,
);
$response = new Response(json_encode($jsonArray));
$response->headers->set('Content-Type', 'application/json; charset=utf-8');
return $response;
}
Respository function
public function findUsersForname($name){
$em = $this->getEntityManager();
$query = $em->createQuery("SELECT e FROM LBCoreBundle:User e
WHERE e.username LIKE '%$name%'");
$entities = $query->getResult();
return $entities;
}

Search Function in Symfony2 is not working

I am working on a project using symfony framework. I just want to make a simple search function wherein it can search all the entities that contain with what the user inputted. When I tried to run my code, its not working it keeps on redirecting to my no found result even if their is a related files to be found with.
Here is my controller:
public function searchAction(Request $request){
$request = $this->getRequest();
$data = $request->request->get('search');
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT a,b,c
FROM SampleBundle:transactionDetail a
JOIN a.transaction b
JOIN b.documentRelated c
WHERE a.pNumber LIKE :data
AND b.senderId LIKE :data
AND b.receiverId LIKE :data
AND b.transactDate LIKE :data
AND a.amountPaid LIKE :data')
->setParameter('data',$data);
$res = $query->getResult();
if($res == null){
return $this->render('SampleBundle:Sample:noresult.html.twig');
}
return $this->render('SampleBundle:Sample:search.html.twig', array('res' => $res));
}
and for my search.html.twig
{% extends '::layout.html.twig' %}
{% block pageTitle %} Related Files Found{% endblock %}
{% block body %}
div class="table-responsive margins" >
<table class="table table-condensed table-striped table-bordered table-hover no-margin">
<thead>
<tr style="height: 40px; ">
<th>Transaction Date</th>
<th>Sender ID</th>
<th>Receiver ID</th>
<th>P Number</th>
<th>Amount Paid</th>
</tr>
</thead>
<tbody>
<tr>
{% for res in res %}
{% for other in res.transaction %}
<td >{{res.transaction.transactDate|date('YMd')}} {{res.ediTransaction.transactionDate|date('H:i')}}</td>
<td>{{res.transaction.senderId}}</td>
<td >{{res.transaction.receiverId}}</td>
{% if other.pNumber != null %}
<td style="word-break: break-all">{{other.pNumber}}</td>
{% else %}
<td>N/A</td>
{% endif %}
{% if other.amountPaid != null %}
<td style="word-break: break-all">{{other.amountPaid}}</td>
{% else %}
<td>N/A</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block javascripts %}
{% javascripts
'bundles/sampledoc/js/jQuery.js'
'bundles/sampledoc/js/bootstrap.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
my form for searching:
<form action="{{path('sample_search')}}" method="POST">
<div class="form-group input-group">
<input type="text" name="search" class="form-control" placeholder="Search" style="width: 200px; float: right;" >
<span class="input-group-btn"><button class="btn btn-default" type="submit" style="margin-right: 20px;"><i class="fa fa-search"></i></button></span>
</div>
</form>
Can somebody help me with this one? thanks in advance.
Data can't equal all your criteria. If you AND everything in your query data has to match all fields, so you will probably return no results.
Try something like:
WHERE a.pNumber LIKE :data
OR b.senderId LIKE :data
OR b.receiverId LIKE :data
OR b.transactDate LIKE :data
OR a.amountPaid LIKE :data')
->setParameter('data', "%$data%");
And look at the generated SQL with
$query->getSQL()
This way you can actually test your query directly on the DB.
Assuming $data is an associative array holding all the goodies, I do not think you can just hand it to setParameter() the way you are doing. You need to break it down more specifically, for each of those "LIKE" clauses.
Completely untested but I suspect you are looking for something like:
`
WHERE a.pNumber LIKE :pNumber
AND b.senderId LIKE :senderId
AND b.receiverId LIKE :recieveId
AND b.transactDate LIKE :transactDate
AND a.amountPaid LIKE :amountPaid')
->setParameters(array(
'pNumber' => $data['pNumber'],
'receiverId' => $data['receiverId'],
'transactDate' => $data['transactDate'],
'amountPaid' => $data['amountPaid'],
));
`

Symfony2: use flush() or persist() to optimize data handling

Im working with Symfony (const version="2.5.10") and using XAMPP with PHP version of 5.5.19
My problem is I keep on getting out of memory error. Because I think I query thousand of data (rows) in the database. For info, I have a lot of data in the database. I want to use flush() or anything that could be use to optimize my data handling.
Here is my code in my indexAction controller:
public function indexAction(){
$em = $this->getDoctrine()->getManager();
$po = $em->getRepository('MatrixEdiBundle:EdiTransactionDetail')->findDocs('850');
return $this->render('MatrixEdiBundle:Matrix:index.html.twig', array('po' => $po));
}
index.html.twig
{% extends '::layout.html.twig' %}
{# {% include 'MatrixEdiBundle:Matrix:header.html.twig'%} #}
{% block body %}
<div class="content">
</br>
<table id="datTable" class="table table-bordered table-condensed table-hover">
<thead>
<th colspan="8">Edi Matrix</th>
<tr>
<th>Po Numbers</th>
<th>Trading Partner Id</th>
<th>PO 855 Acknowledgement</th>
<th>PO 997 Acknowledgement</th>
<th>Advance Shipment Notice</th>
<th>Invoice</th>
<th>Purchase Order Change</th>
<th>Order Status</th>
</tr>
</thead>
<tbody>
{% for tran in po %}
<tr>
<td><a href="{{ path('matrix_edi_showpo', {'po_num': tran.poNumber}) }}"data-toggle="modal" data-target="#myModal">{{tran.poNumber}}</td>
<td>{{tran.ediTransaction.senderId}}</td>
<td><a href="{{ path('matrix_edi_findAll', {'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'doc_type': 855}) }}"data-toggle="modal"data-target="#myModal">
{{ render(controller('MatrixEdiBundle:Matrix:matrix', {
'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'reciever_id': tran. ediTransaction.receiverId, 'doc_type': 855, 'gs_number': tran.ediTransaction.gsNumber })) }}</a>
</td>
<td><a href="{{ path('matrix_edi_poack', {'gs_number': tran.ediTransaction.gsNumber, 'receiver_id': tran.ediTransaction.receiverId, 'sender_id': tran.ediTransaction.senderId}) }}"data-toggle="modal"data-target="#myModal">
{{ render(controller('MatrixEdiBundle:Matrix:matrix', {
'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'reciever_id': tran. ediTransaction.receiverId, 'doc_type': 997, 'gs_number': tran.ediTransaction.gsNumber })) }}</a>
</td>
<td><a href="{{ path('matrix_edi_findAll', {'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'doc_type': 856}) }}"data-toggle="modal"data-target="#myModal">{{ render(controller('MatrixEdiBundle:Matrix:matrix', {
'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'reciever_id': tran.ediTransaction.receiverId, 'doc_type': 856, 'gs_number': tran.ediTransaction.gsNumber }))}}</a>
</td>
<td>{{ render(controller('MatrixEdiBundle:Matrix:matrix', {'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'reciever_id': tran.ediTransaction.receiverId, 'doc_type': 810, 'gs_number': tran.ediTransaction.gsNumber})) }}
</td>
<td>{{ render(controller('MatrixEdiBundle:Matrix:matrix', {'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'reciever_id': tran.ediTransaction.receiverId, 'doc_type':860, 'gs_number': tran.ediTransaction.gsNumber})) }}
</td>
<td><a href="{{ path('matrix_edi_findAll', {'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'doc_type': 870}) }}"data-toggle="modal"data-target="#myModal">{{ render(controller('MatrixEdiBundle:Matrix:matrix', {
'po_num': tran.poNumber, 'sender_id': tran.ediTransaction.senderId, 'reciever_id': tran.ediTransaction.receiverId, 'doc_type': 870, 'gs_number': tran.ediTransaction.gsNumber
})) }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false" >
<div class="modal-dialog">
<div class="modal-content" style="width: 650px;">
<div class="modal-header" style="background-color: #2d6ca2; color: white;">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true" style="color: white;">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel" >Details</h4>
</div>
<div class="modal-body">
Loading, please wait......
<div class="bootstrap-table">
<div class="fixed-table-container" style="height: 299px; padding-bottom: 37px;">
<div class="fixed-table-body">
<div class="fixed-table-loading" style="top: 27px; display: none;">Loading, please wait…</div>
</div>
<div class="fixed-table-pagination"></div>
</div>
</div><div class="clearfix"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal" >Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% endblock %}
{% block javascripts %}
{% javascripts
'bundles/matrixdoc/js/jQuery.js'
'bundles/matrixdoc/js/jquery.dataTables.min.js'
'bundles/matrixdoc/js/dataTables.bootstrap.js'
'bundles/matrixdoc/js/bootstrap.js'
%}
<script src="{{ asset_url }}"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#datTable').dataTable( {
"scrollY": "400px",
"scrollCollapse": true,
"pagingType": "simple",
});
$('body').on('hidden.bs.modal', '.modal', function () {
$(this).removeData('bs.modal');
});
$(document).on("hidden.bs.modal", function (e) {
$(e.target).removeData("bs.modal").find(".modal-content").empty();
});
});
</script>
{% endjavascripts %}
{% endblock %}
You should use pagination getting your data with limits and coupled with partial to get your needed fields if you don't need everything.
http://zrashwani.com/pagination-optimization-symfony2-doctrine/#.VV1av_mSwbg
for partial in DQL , simple example for user:
//partial_fields is an array, which can be passed like this $repo->getPartialUser($user_id, array('field1', 'field2', 'etc..');
public function getPartialUser($id, $partial_fields){
$qb = $this->_em->createQueryBuilder()
->select('partial u.{'.implode(',',$partial_fields).'}')
->from('AcmeUserBundle:User', 'u')
->where('u.id = :id')
->setParameter('id', $id);
$result = $qb->getQuery()->getOneOrNullResult();
return $result;
}
EDIT EXAMPLE CODE :
i will give you an example but you will probably still need to adapt it to your code or maybe it will work out of the box.
First you need a new twig with simple piece of code to show pages numbers for navigation below the table (note that i will not use datatables paginator but we will keep it for table layout rendering) :
pager.html.twig
<div class="pagination">
<div class="pagination-buttons">
{% if pagination.page>1 %}
<a href="{{ path(pagination.route,
pagination.route_params|merge({'page': 1})) }}"><<</a>
<a href="{{ path(pagination.route,
pagination.route_params|merge({'page': pagination.page-1})) }}"><</a>
{% endif %}
{#display p numbers only from p-4 to p+4 but don't go <1 or >pages_count#}
{% for p in range(max(pagination.page-4, 1),
min(pagination.page+4, pagination.pages_count)) %}
<a{% if p == pagination.page %} class="current-page"{% endif %}
href="{{ path(pagination.route,
pagination.route_params|merge({'page': p})) }}">{{ p }}</a>
{% endfor %}
{% if pagination.page<pagination.pages_count %}
<a href="{{ path(pagination.route,
pagination.route_params|merge({'page': pagination.page+1})) }}">></a>
<a href="{{ path(pagination.route,
pagination.route_params|merge({'page': pagination.pages_count})) }}">>></a>
{% endif %}
</div>
</div>
EdiTransactionDetailRepository:
add a function with your field that you use in your table :
public function getPagedDocs($page = 1, $limit = 50)
{
$qb = $this->_em->createQueryBuilder()
->select('partial d.{field1,field2 , etc..},
partial et.{field1,field2, etc..}'
))//select doc fields and second partial for your join select edittransaction fields if you have other joins add another partial etc..
->from('YourBundle:DocsEntity', 'd')
->innerJoin('d.ediTransaction', 'et')//not sure which join you need i have no clue but i believe you will want an inner one since you will want a doc to have a ediTransaction because i didn't see any checks in your twig for it if null.
->setFirstResult(($page - 1) * $limit)
->setMaxResults($limit);
$paginator = new Paginator($qb, $fetchJoinCollection = false);//for more performance fetchjoincollection to false if you have joined tables
$paginator->setUseOutputWalkers(false);//for more performance set to false for more information http://www.doctrine-project.org/jira/browse/DDC-2890
return $paginator;
}
PS: Change limit to how many records you want to show in each page depending on the load of data you have make it lower if it is slow for 50 this is depend on how much data each row have.
Next the indexAction in your controller :
public function indexAction($page){
$em = $this->getDoctrine()->getManager();
$po = $em->getRepository('MatrixEdiBundle:EdiTransactionDetail')->getPagedDocs($page, 50);
$count = $po->count();
$pagination = array(
'page' => $page,
'route' => 'docs_index_route_name', //i dont know which name you have but it should be the route name of this indexAction
'route_params' => array()
);
if ($max_records > 0)
$pagination['pages_count'] = max(ceil($count / $max_records), 1);
return $this->render('MatrixEdiBundle:Matrix:index.html.twig', array('po' => $po,
'pagination' => $pagination
));
}
Routing:
You need to modify the route of your indexAction as we added a parameter page you need to add it for the route too :
index_docs:
pattern: /index/{page}
defaults: { _controller: "YourBundle:Controller:index", page: 1 }
NOTE : you will need to change the names and stuff i dont know you controller names and bundles so normally you will only need to add /{page} to the pattern and , page:1 to your _controller config which is the default value.
Last thing to do is your index.html.twig which need to include our pager.html.twig
include this piece of code after you close your table :
{% if po|length > 0 and pagination['pages_count'] is defined and pagination['pages_count'] > 0 %}
{#---------Pager----------#}
<div style="text-align:center;">
{% include 'YourBundle:EntityDoc:pager.html.twig' %}
</div>
{% endif %}
NOTE : The include is the path to the file where you create the pager.html.twig i assume you are familiar with how this works.
So if i didn't forget anything this should work out of the box , it should enhance greatly your performance but i am afraid that your render controller there for each row may still be problematic. But try this solution first and see, it depends what you put inside those controllers.

Categories