Собственно основные события происходят по созданию сего аккордеона происходят в контроллере - entity подстанций в данном случае, но это не принципиально в каком. И в шаблоне, который у меня включаемый, потому-что общий для нескольких видов других шаблонов. По нажатию по ссылке на аккордеоне в контенте шаблона должна выводиться таблица с подстанциями. Загвоздка в том, что после обновления страницы надо воспроизвести аккордеон в том виде в каком он был развернут пользователем. Код из контроллера подстанций:
............
protected $pos;
protected $em;
public function init() {
$this->em = $this->getDoctrine()
->getManager();
$this->pos = $this->em->getRepository('BpBundle:Po')
->findAll();
}
protected function getPo($po_id)
{
$em = $this->getDoctrine()
->getManager();
$po = $em->getRepository('BpBundle:Po')->find($po_id);
if (!$po) {
throw $this->createNotFoundException('Не найдено ПО.');
}
return $po;
}
protected function getGP($gp_id)
{
$em = $this->getDoctrine()
->getManager();
$gp = $em->getRepository('BpBundle:GroupsPodst')->find($gp_id);
if (!$gp) {
throw $this->createNotFoundException('Не найдено ПО.');
}
return $gp;
}
..........
public function indexAction($po_id, $is_po)
{
$this->init();
// $em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('BpBundle:Podst');
if ($is_po) {
$po = $this->getPo($po_id);
$queryBuilder = $repository->createQueryBuilder('p')
->leftJoin('p.groupPodst', 'g')
->leftJoin('g.po', 'po')
->where('po = :po')
->orderBy('p.name')
->setParameter('po', $po);
$podsts = $queryBuilder->getQuery()->getResult();
} else {
$gp = $this->getGP($po_id);
$po = $this->getPo($gp->getPo()->getId());
$podsts = $repository->findBy(array('groupPodst' => $gp),array('name' => 'ASC'));
}
........
return $this->render('BpBundle:Podst:index.html.twig', array(
'podsts' => $podsts, 'po' => $is_po?$po:$gp,
'pos' => $this->pos, 'is_po' => $is_po, 'dostup' => $ok,
));
}
............
Смотрим функцию indexAction($po_id, $is_po), в которой формируются данные для шаблона. Тут $is_po - сигнализирует нажата ли ссылка ПО - тогда надо выводить все подстанции ПО, если нет, то подстанции относящиеся к выбранной группе. Но главное, что важно для нашего аккордеона - мы для него передали в шаблон массив объектов $pos - то есть все ПО.
А теперь рассмотрим шаблон, который у нас сделан на twig.
{% extends '::base.html.twig' %}
{% block sidebar %}
<div class="bs-docs-sidebar">
{# Po accordion #}
<div class="accordion" id="accordion1">
{% for po in pos %}
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle btn btn-inverse" data-toggle="collapse" data-parent="#accordion1" href="http://demiware.ru/#collapse{{po.id}}">
{{po.name}} <i class=" icon-chevron-down icon-white"></i>
</a>
</div>
<div id="collapse{{po.id}}" class="accordion-body collapse">
<div class="accordion-inner">
<div class="btn-group btn-group-vertical" data_toggle="radio-button">
<a id="b1_{{po.id}}" type="button" class="inv sbar btn btn-inverse" href="http://demiware.ru/{{ path('po_edit', { 'id': po.id }) }}">
Редактировать ПО <i class="icon-chevron-right icon-white"></i> </a>
<a id="b2_{{po.id}}" type="button" class="inv sbar btn btn-inverse" href="http://demiware.ru/{{ path('podst', { 'po_id': po.id, 'is_po': 1 }) }}">
Все подстанции <i class="icon-chevron-right icon-white"></i> </a>
</div>
<br>
<div class="btn-group btn-group-vertical" data_toggle="radio-button">
{% for gp in po.gps %}
<a id="b_{{gp.id}}" class="sbar accordion-toggle btn btn-small btn-primary" href="http://demiware.ru/{{ path('podst', { 'po_id': gp.id, 'is_po': 0 }) }}" >
{{gp.name}} <i class="icon-chevron-right icon-white"></i>
</a>
{% else %}
<p>в {{po.name}} нет групп подстанций...</p>
{% endfor %}
</div>
</div>
</div>
</div>
{% else %}
<p>таблица Po пуста...</p>
{% endfor %}
</div>
</div>
{% endblock %}
{% block javascripts %}
<script src="http://demiware.ru/{{ asset('js/bp.js') }}"></script>
{% endblock %}
Первой строкой он расширяется базовым шаблоном, в котором хранятся все подключения основных CSS, главное меню, шапка, подвал и прочее. В свою очередь этот шаблон сам расширяет уже шаблоны в которых выводятся таблицы с подстанциями и другие некоторые. Цикл вывода содержимого аккордеона разбирать не будем, он понятен. Обратим внимание, что за скрипт подключен внизу в файле bp.js, в этом файле есть код касающийся данного аккордеона. Именно этот ява-скрипт позволяет сохранять его состояние в куки и выделять активный пункт.
$(document).ready(function() {
..........................
//////////////////////Играем на аккордеоне//////////////////////////////////
var last=$.cookie('activeAccordionGroup');
var pth=window.location.pathname; //alert(pth);
if (last!==null && !(pth=="/" || pth=="/app_dev.php/")) {
//remove default collapse settings
$("#accordion1 .collapse").removeClass('in');
//show the last visible group
$("#"+last).collapse("show");
}
last=$.cookie('activeButton');
if (last!==null) {
//$("a.sbar").removeClass('btn-info');
$("#"+last).removeClass('btn-inverse btn-primary');
$("#"+last).addClass('btn-info');
}
//when a group is shown, save it as the active accordion group
$("#accordion1 .collapse").on('show', function() {
var active=$(this).attr('id');
$.cookie('activeAccordionGroup', active, {
expires: 7,
path: '/'
});
});
$("a.sbar").on('click', function() {
var last=$.cookie('activeButton');
if (last!==null) {
$("#"+last).removeClass('btn-info');
if ($("#"+last).hasClass('inv')) {
$("#"+last).addClass('btn-inverse');
}
else {
$("#"+last).addClass('btn-primary');
}
}
var active=$(this).attr('id');
$(this).removeClass('btn-inverse btn-primary');
$(this).addClass('btn-info');
$.cookie('activeButton', active, {
expires: 7,
path: '/'
});
});
........
});

