Сегодня 13 мая, понедельник ГлавнаяНовостиО проектеЛичный кабинетПомощьКонтакты Сделать стартовойКарта сайтаНаписать администрации
Поиск по сайту
 
Ваше мнение
Какой рейтинг вас больше интересует?
 
 
 
 
 
Проголосовало: 7273
Кнопка
BlogRider.ru - Каталог блогов Рунета
получить код
Dmitriy
Dmitriy
Голосов: 0
Адрес блога: http://demiware.ru
Добавлен: 2014-01-14 07:07:16
 

Прикручиваем динамический аккордеон от Twitter Bootstrap в проекте Symfony

2014-01-06 19:36:25 (читать в оригинале)

Прикручиваем динамический аккордеон от Twitter Bootstrap в проекте Symfony

Пример привожу из своего проекта - некий WEB-сервис для энергетической компании региона. Имеем Следующие объекты(entity в терминологии Symfony2) 

  • производственные отделения (ПО)
  • относящиеся к ПО группы электроподстанций

Отношения таблиц один ко многим, ну это понятно и все описано в схеме проекта. Задача - сделать аккордеон в левой части страницы, на верхнем уровне которого должны быть ПО, а подпункты - группы подстанций. Если вам нужно больше иерархий ничто не мешает сделать это по аналогии.

Собственно основные события происходят по созданию сего аккордеона происходят в контроллере - 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: '/'
        });
    });
    
........
});
 

Тэги: symfony2, сайтостроение

 


Самый-самый блог
Блогер ЖЖ все стерпит
ЖЖ все стерпит
по количеству голосов (152) в категории «Истории»
Изменения рейтинга
Категория «Истории»
Взлеты Топ 5
Падения Топ 5


Загрузка...Загрузка...
BlogRider.ru не имеет отношения к публикуемым в записях блогов материалам. Все записи
взяты из открытых общедоступных источников и являются собственностью их авторов.