Reputation: 963
UPDATE
Think I may have gone off course here, but I still get the same result with the whole page being displayed in the table.
So I am doing this for both the view and status pages. View is the default page which shows all active alerts. Status is the page that will display the filtered alerts. So each of these pages has a controller
public function viewAction()
{
$repository = $this
->getDoctrine()
->getManager()
->getRepository('NickAlertBundle:Alert');
$alerts = $repository->getAllActiveAlerts();
return $this->render('NickAlertBundle:Page:view.html.twig', array(
'alerts' => $alerts,
));
}
public function getActivatedAction(Request $request)
{
$alertStatus = $request->request->get('status', 'active');
$alerts = $this->getDoctrine()->getRepository('NickAlertBundle:Alert')->getAlertByStatus($alertStatus);
return $this->render('NickAlertBundle:Page:status.html.twig', array("alerts"=>$alerts));
}
Each of these pages then has a route
NickAlertBundle_view:
pattern: /view-alerts
defaults: { _controller: NickAlertBundle:Alert:view }
requirements:
_method: GET
NickAlertBundle_status:
pattern: /view-alerts
defaults: { _controller: NickAlertBundle:Alert:getActivated }
requirements:
_method: POST
NickAlertBundle_view calls the view action and renders the page with all active alerts. NickAlertBundle_status calls the getActivated action.
Both of these views are the same, their content is as follows
{% extends 'NickAlertBundle::layout.html.twig' %}
{% block main %}
<div class="col-md-12">
<section class="panel panel-default">
<header class="panel-heading">
<h3 class="panel-title">View Alerts</h3>
<select name="alerts" id="alerts" data-url="{{ path('NickAlertBundle_status') }}">
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</header>
<div class="panel-body">
<div class="row" id="alert-container">
<table width="100%" cellpadding="0" cellspacing="0" border="0" id="datatable" class="table">
<thead>
<tr>
<th>Id</th>
<th>Search Command</th>
<th>Flight Number</th>
<th>Booking Class</th>
<th>Alert Pseudo</th>
<th>Alert Status</th>
</tr>
</thead>
<tbody>
{% for alert in alerts %}
<tr>
<td>{{ alert[0].id }}</td>
<td>{{ alert[0].searchCommand }}</td>
<td>{{ alert.flight_number }}</td>
<td>{{ alert.classes }}</td>
<td>{{ alert.pseudos }}</td>
<td>{{ alert[0].alertStatus }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</section>
</div>
{% endblock %}
So the data url should call the status route. Both of the views have this because they should always be able to change the select on either page.
And then the javascript is pretty much the same as you have shown me.
Upvotes: 1
Views: 460
Reputation: 86
To solve the url problem you should put:
NickAlertBundle_view:
pattern: /view-alerts
defaults: { _controller: NickAlertBundle:Alert:view }
methods: [GET]
NickAlertBundle_status:
pattern: /view-alerts
defaults: { _controller: NickAlertBundle:Alert:getActivated }
methods: [POST]
Upvotes: 0
Reputation: 86
The $('#alert-container table tbody').html(data);
line will set the contento of your tbody table from the response that the server return, so you have to have two different files
{% NickAlertBundle:Page:view.html.twig %}
{% extends 'NickAlertBundle::layout.html.twig' %}
{% block main %}
<div class="col-md-12">
<section class="panel panel-default">
<header class="panel-heading">
<h3 class="panel-title">View Alerts</h3>
<select name="alerts" id="alerts" data-url="{{ path('NickAlertBundle_status') }}">
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</header>
<div class="panel-body">
<div class="row" id="alert-container">
<table width="100%" cellpadding="0" cellspacing="0" border="0" id="datatable" class="table">
<thead>
<tr>
<th>Id</th>
<th>Search Command</th>
<th>Flight Number</th>
<th>Booking Class</th>
<th>Alert Pseudo</th>
<th>Alert Status</th>
</tr>
</thead>
<tbody>
{% for alert in alerts %}
<tr>
<td>{{ alert[0].id }}</td>
<td>{{ alert[0].searchCommand }}</td>
<td>{{ alert.flight_number }}</td>
<td>{{ alert.classes }}</td>
<td>{{ alert.pseudos }}</td>
<td>{{ alert[0].alertStatus }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</section>
</div>
{% endblock %}
and
{# NickAlertBundle:Page:status.html.twig #}
{% for alert in alerts %}
<tr>
<td>{{ alert[0].id }}</td>
<td>{{ alert[0].searchCommand }}</td>
<td>{{ alert.flight_number }}</td>
<td>{{ alert.classes }}</td>
<td>{{ alert.pseudos }}</td>
<td>{{ alert[0].alertStatus }}</td>
</tr>
{% endfor %}
Upvotes: 1
Reputation: 86
UPDATED
The problem is basicaly that you are embedding the html response from viewAction when you actually have to put the code for the alerts, for example:
public function getActivatedAction(Request $request)
{
$alertStatus = $request->request->get('status', 'active');
$alerts = $this->getDoctrine()->getRepository('NickAlertBundle:Alert')->findAllByStatus($alertStatus);
return $this->render('NickAlertBundle:Alerts:show.html.twig', array("alerts"=>$alerts));
}
on the NickAlertBundle:Alerts:show.html.twig
{# NickAlertBundle:Alerts:show.html.twig #}
{% for alert in alerts %}
<tr>
<td>{{ alert[0].id }}</td>
<td>{{ alert[0].searchCommand }}</td>
<td>{{ alert.flight_number }}</td>
<td>{{ alert.classes }}</td>
<td>{{ alert.pseudos }}</td>
<td>{{ alert[0].alertStatus }}</td>
</tr>
{% endfor %}
So then in your NickAlertBundle:Page:view.html.twig
:
$('#alerts').change(function(){
$.ajax({
type: "POST",
url: $('#alerts').attr('data-url'), # getActivatedAction route
data:{ status: $(this).val() },
success: function(data){
$('#alert-container table tbody').html(data);
}
});
});
You can add a methond in your Enity Repository File:
# src/Package/AppBundle/Entity/AlertRepository.php
<?php
namespace Package\AppBundle\Entity;
use Doctrine\ORM\EntityRepository;
/**
* AlertRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class AlertRepository extends EntityRepository
{
public function findAllByStatus($status = "active")
{
$qb = $this->createQueryBuilder('a');
$query = $qb
->where(
$qb->expr()->eq('a.alertStatus', $status)
)
->orderBy('a.id', 'DESC')
->getQuery();
return $query->getResult();
}
}
and then in your controller, you can pass a json with the data or html:
<?php
...
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
...
public function getActivatedAction(Request $request)
{
$alertStatus = $request->request->get('status', 'active');
$alerts = $this->getDoctrine()->getRepository('AppBundle:Alert')->findAllByStatus($alertStatus);
// With JSON
$json = alerts->toJson() // your own method
$response = new JsonResponse();
$response->setData($json);
// With HTML
return $this->render('AppBundle:Alerts:show.html.twig', array("alerts"=>$alerts));
}
Now in yor html file you can use ajax to request the alerts:
<select name="alerts" id="alerts">
<option value="active">Actives</option>
<option value="inactive">Inactive</option>
</select>
<div id="alertsList"></div>
<script>
$('#alerts').change(function(){
$.ajax({
type: "POST",
url: "{{ path('alerts_getActivated') }}",
data:{ status: $(this).val() },
success: function(data){
$('#alertsList').html(data); //Using the html response. With json you have to create the style and html here
}
});
});
</script>
If I didn't miss anything it should work.
If I get you wrong, please let me know, and I hope this will help you.
Upvotes: 2