Форум программистов, компьютерный форум, киберфорум
PHP: Laravel
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568

Acordeon Side Menu в Laravel

01.09.2023, 13:35. Показов 1379. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пытаюсь перевести сайт с Joomla на Laravel. Вроде особых сложностей не было. Но споткнулся на боковом меню. В сайте на joomla использовал модуль типа http://joomla4ever.ru/extensio... -menu.html
Пример его работы тут https://rednord.md/index.php/r... e-la-retea
Для меню под laravel взял за основу это https://www.nicesnippets.com/b... l-treeview и это http://dle-net.ru/index.php?newsid=979
Подрехтовал немного стили и меню стало похоже на то которое на сайте Joomla.
Но проблема в том, что меню работает только по клику на элемент. Когда открывается собственно страница суб меню, само меню перезагружается и субменю закрывается. Вопрос в том как сделать так, чтобы субменю всех уровней оставалось открыто после клика по элементу субменю и загрузки соответствующей ему страницы сайта.
Blade у меня выглядить так:
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
                                <div id='cssmenu' class="cssmenu">
                                    <ul>
                                        @if(!$allMenus->isEmpty())
                                            <div class="cssmenusp">
                                                {{ $page->article_category->name }}
                                            </div>
                                            @foreach($allMenus->sortBy('position') as $menu)
                                                @if($menu->name->name == "Right Menu")
                                                    @if($menu->name->name == "Right Menu" and $menu->category->name == $page->article_category->name)
                                                        @if(count($menu->childs))
                                                            @if($menu->article_id == $oneMenu->article->id)
                                                                @php $active = 'active' @endphp
                                                            @else
                                                                @php $active = '' @endphp
                                                            @endif
                                                            <li class='has-sub {{ $active }}' dt="{{ $menu->id }}"><a id="{{ $menu->id }}" href='#' ><span>{{ $menu->title }}</span></a>
                                                                @if(count($menu->childs))
                                                                    @include('menu.manageChild1',['childs' => $menu->childs])
                                                                @endif
                                                            </li>
                                                        @else
                                                            @if($menu->article_id == $oneMenu->article->id)
                                                                @php $active = 'active' @endphp
                                                            @else
                                                                @php $active = '' @endphp
                                                            @endif
                                                            <li class='{{ $active }}'><a href='{{ URL::to('/') }}/pages/{{ $menu->article->slug.'/'.$menu->article->id }}'><span>{{ $menu->title }}</span></a>
                                                        @endif
                                                    @endif
                                                @endif
                                            @endforeach
                                        @endif
                                    </ul>
                                </div>
manageChild1 выглядит так:
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<ul>
    @foreach($childs->sortBy('order_id') as $child)
        @if($child->article_id == $oneMenu->article->id)
            @php $active = 'active'; @endphp
        @else
            @php $active = '' @endphp
        @endif
        <li class='{{ $active }}'><a de="{{ $child->article_id }}" test="{{ $child->parent_id }}" href='{{ URL::to('/') }}/pages/{{ $child->article->slug.'/'.$child->article->id }}'><span>{{ $child->title }}</span></a>
            @if(count($child->childs))
            <li class='has-sub'><a href='#'><span>{{ $child->title }}</span></a>
                @include('menu.manageChild1',['childs' => $child->childs])
            </li>
            @endif
        </li>
    @endforeach
</ul>
 
И скрипт:
[JS]    <script>
        $(doc[/JS]
JavaScript Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ument).ready(function () {
            $('#cssmenu li.has-sub > a').on('click', function(){
                $(this).removeAttr('href');
                var element = $(this).parent('li');
                if (element.hasClass('open')) {
                    element.removeClass('open');
                    element.find('li').removeClass('open');
                    element.find('ul').slideUp();
                }
                else {
                    element.addClass('open');
                    element.children('ul').slideDown();
                    element.siblings('li').children('ul').slideUp();
                    element.siblings('li').removeClass('open');
                    element.siblings('li').find('li').removeClass('open');
                    element.siblings('li').find('ul').slideUp();
                }
            });
            $('#cssmenu>ul>li.has-sub>a').append('<span class="holder"></span>');
        });
Из контроллера в blade поступают все необходимые коллекции и переменные.
Вроде все работает. Но... не понимаю как заставить меню оставаться открытым при клике на ссылку субменю или суб суб .. и т.д. меню и загрузке соответствующей страницы сайта.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.09.2023, 13:35
Ответы с готовыми решениями:

Laravel menu
Парни всем привет! Пытаюсь работать с Laravel menu используя Lavary. Подскажи как сделать так что бы в одном из моих пунктов меню выпадали...

Конфликт между Navigation Drawer и Side Menu
Доброе время суток, форумчане! Нужна ваша помощь! SOS!:help: Дела в том, что я создал классический навигационное меню (Navigation...

Ремонт Холодильник Акаi ARL2522MS side-by-side, доза фреона 600а
Холодильник AKAI side-by-side ARL 2522MS морозилка-180л/холодилка-341л.Серийный номер-BCOTDOE0300BA7790094 подскажите норму заправки...

17
 Аватар для sad67man
2481 / 1406 / 665
Регистрация: 23.08.2015
Сообщений: 3,546
01.09.2023, 15:29
VlGuvin, Я бы разбилл на 2 этапа. Сначала сформировать данные для вывода, потом уже подставить в html. Для формирования данных можно выделить отдельный класс. Меню может состоять не только из одной таблицы. Поэтому разные менюшки удобнее подгонять под единый формат.

В таком случае и шаблон html будет более чистым, он не будет перегружен излишней логикой, можно будет проще подменять и модифицировать шаблон. Ну и больше маневра для формирования. В вашем случае можно собрать id-шники заранее по parent-ам активного пункта меню и делать проверку на in_array - но это частный случай. Можно сделать и более универсальный подхзод - рекурсивно обходить массивы и помечать активные пункты.
0
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
01.09.2023, 17:14  [ТС]
Сначала сформировать данные для вывода
$allMenus - это и есть коллекция всего меню.
рекурсивно обходить массивы и помечать активные пункты
Это уже сделано и работает.
PHP Скопировано
1
2
3
4
5
6
7
...
        @if($child->article_id == $oneMenu->article->id)
            @php $active = 'active'; @endphp
        @else
            @php $active = '' @endphp
        @endif
...
Ативные пункты подсвечиваются другим цветом. Причем в субменю, суб суб и так далее тоже.
собрать id-шники заранее по parent-ам активного пункта
Допустим собрал. Главный вопрос. Как технически заставить раскрыться субменю и последующие дочерние при загрузке страницы соответствующей пункту субменю или суб суб. В данном случае все раскрывается только по клику на меню, субменю, суб суб и так далее.
Тоесть пункт субменю или суб суб я выбираю вручную кликом. Затем клик на нужный пунк и хочу, чтобы при загрузке страницы соответствующей этому пункту все осталось развернутым (раскрытым). А оно все закрывается.
0
 Аватар для sad67man
2481 / 1406 / 665
Регистрация: 23.08.2015
Сообщений: 3,546
01.09.2023, 18:18
VlGuvin, Смотрите в инспекторе браузера что происходит с html когда вы раскрываете меню.
Нужно поставить класс open на li и style="display: block" на ul
0
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
01.09.2023, 20:32  [ТС]
Нужно поставить класс open на li и style="display: block" на ul
Нужно попробовать это сделать для элементов меню имеющих подменю. Не уверен, что сработает...
В данном случае кода, все нужное добавляется в скрипте при клике на элемент меню имеющий подменю. Но это в ручном режиме.
JavaScript Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    <script>
        $(document).ready(function () {
            $('#cssmenu li.has-sub > a').on('click', function(){
                $(this).removeAttr('href');
                var element = $(this).parent('li');
                if (element.hasClass('open')) {
                    element.removeClass('open');
                    element.find('li').removeClass('open');
                    element.find('ul').slideUp();
                }
                else {
                    element.addClass('open');
                    element.children('ul').slideDown();
                    element.siblings('li').children('ul').slideUp();
                    element.siblings('li').removeClass('open');
                    element.siblings('li').find('li').removeClass('open');
                    element.siblings('li').find('ul').slideUp();
                }
            });
 
            $('#cssmenu>ul>li.has-sub>a').append('<span class="holder"></span>');
        });
Я пытаюсь использовать это для раскрытия всех имеющихся подменю при загрузке страницы. Если подменю один то при загрузке страницы достаточно выполнить функцию типа:
JavaScript Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
        function myFunction () {
            console.log( "OnLoad!" );
            $(document).ready(function () {
            var element = $('#cssmenu>ul>li.has-sub>a').parent('li');
                element.addClass('open');
                // element.children('ul').slideToggle();
                element.children('ul').slideDown();
                element.siblings('li').children('ul').slideUp();
                element.siblings('li').removeClass('open');
                element.siblings('li').find('li').removeClass('open');
                element.siblings('li').find('ul').slideUp();
            });
        }
 
        myFunction();
 
    </script>
Но если в подменю еще подменю и так далее, то не знаю что делать, чтобы раскрыть меню со всеми подменю при клике, к примеру на, на последний элемент в подменю и переходе на соответствующую страницу.

Добавлено через 5 минут
Нужно поставить класс open на li и style="display: block" на ul
Это работает. Спасибо.
Теперь нужно понять как это добавлять (не добавлять) в нужные места html при загрузке страницы.
0
 Аватар для sad67man
2481 / 1406 / 665
Регистрация: 23.08.2015
Сообщений: 3,546
01.09.2023, 21:01
Цитата Сообщение от VlGuvin Посмотреть сообщение
$allMenus - это и есть коллекция всего меню.
Вы видимо не поняли. Я предлагаю разделить на 2 этапа. Для начала сформировать массив данных в таком виде

PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
$rightMenu = [
    [
        'label' => 'Различные CMS',
        'is_active' => true,
        'items' => [
            [
                'label' => 'WordPress',
                'is_active' => false,
                'items' => [
                    [
                        'label' => 'Релизы',
                        'is_active' => false,
                        'url' => '/pages/alias/id'
                    ],
                    [
                        'label' => 'Шаблоны',
                        'is_active' => false,
                        'url' => '/pages/alias/id'
                    ],
                    [
                        'label' => 'Плагины',
                        'is_active' => false,
                        'url' => '/pages/alias/id'
                    ],
                ],
            ],
            [
                'label' => 'Joomla',
                'is_active' => true,
                'items' => [
                    [
                        'label' => 'Joomla релизы',
                        'is_active' => false,
                        'url' => '/pages/alias/id'
                    ],
                    [
                        'label' => 'Joomla шаблоны',
                        'is_active' => true,
                        'url' => '/pages/alias/id'
                    ],
                    [
                        'label' => 'Joomla модули',
                        'is_active' => false,
                        'url' => '/pages/alias/id'
                    ],
                ],
            ]
        ],
    ]
];
Как видите, если у нас активный пункт меню 'Joomla шаблоны' - то нам необходимо пометить активными пунктами родителей вверх по дереву, т. е. 'Joomla' и 'Различные CMS'

Для этого вы можете сделать все ТООЖЕ самое, что и в шаблоне, только формировать массив, и в конце еще активировать родителей. К примеру.

PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class MenuRightTransformer
{
    private $allMenus;
    private $oneMenu;
    private $page;
 
    public function __construct($allMenus, $oneMenu, $page)
    {
        $this->allMenus = $allMenus;
        $this->oneMenu = $oneMenu;
        $this->page = $page;
    }
 
    public function getData(): array
    {
        $data = [];
 
        foreach ($this->allMenus->sortBy('position') as $menu) {
            if ($menu->name->name == "Right Menu") {
                if ($menu->name->name == "Right Menu" and $menu->category->name == $this->page->article_category->name) {
                    $data[] = $this->transformItem($menu);
                }
            }
        }
 
        $this->activateItems($data);
 
        return $data['items'];
    }
 
    private function transformItem($menu)
    {
        $item = [
            'label' => $menu->title,
            'is_active' => $menu->article_id == $this->oneMenu->article->id,
            'url' => $menu->article ? URL::to('/')  . '/pages/' . $menu->article->slug.'/'.$menu->article->id : '',
            'items' => [],
        ];
 
        foreach ($menu->childs->sortBy('order_id') as $child) {
            $item['items'] = $this->transformItem($child);
        }
 
        return $item;
    }
 
    private function activateItems(& $items): bool
    {
        $result = false;
        foreach ($items as &$item) {
            if (!empty($item['items'])) {
                $item['is_active'] = $this->activateItems($item['items']);
            }
            $result = $result || !empty($item['is_active']);
        }
 
        return $result;
    }
}
Вызов

PHP Скопировано
1
$rightMenu = (new MenuRightTransformer($allMenus, $oneMenu, $page))->getData();
Далее уже подставить данные в шаблон не составит труда.

PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
<div id='cssmenu' class="cssmenu">
    <ul>
        @if(!empty($rightMenu)
            <div class="cssmenusp">
                {{ $page->article_category->name }}
            </div>
            @foreach($rightMenu as $menu)
                @include('menu.item', ['menu' => $menu])
            @endforeach
        @endif
    </ul>
</div>
menu.item
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@if(!empty($menu['items']))
    <li class="has-sub {{ $menu['is_active'] ? 'open' : '' }}">
        <span>{{ $menu['label'] }}</span>
        <ul {{ $menu['is_active'] ? 'style="display: block;"' : '' }}>
            @foreach($menu['items'] as $child)
                @include('menu.item', ['menu' => $child])
            @endforeach
        </ul>
    </li>
@else
    <li {{ $menu['is_active'] ? 'class="active"' : '' }}>
        <a href='{{ $menu['url'] }}'>
            <span>{{ $menu['label']] }}</span>
        </a>
    </li>
@endif
Добавлено через 5 минут
Чуток подправил. Не будем углубляться, как это вообще правильно делать. Попробуем допилить ваш вариант)

Добавлено через 4 минуты
VlGuvin, Единственное что я blade плохо знаю. Там подправите если что.
1
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
01.09.2023, 21:18  [ТС]
Спасибо. В общих чертах понял. Нужно будет еще разобраться. Наверное Ваш вариант правильный.
Но я пытаюсь уже допилить что имеется. Вроде должно сработать.
Это основной html (blade.php)
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    <div id='cssmenu' class="cssmenu">
        <ul>
            @if(!$allMenus->isEmpty())
                <div class="cssmenusp">
                    {{ $page->article_category->name }}
                </div>
                @foreach($allMenus->sortBy('position') as $menu)
                    @if($menu->name->name == "Right Menu")
                        @if($menu->name->name == "Right Menu" and $menu->category->name == $page->article_category->name)
                            @if(count($menu->childs))
{{--                                @php $open = "open"; $block = "block"; @endphp--}}
                                @if($menu->article_id == $oneMenu->article->id)
                                    @php $active = 'active'; $open = "open"; $block = "block"; @endphp
                                @else
                                    @php $active = ''; $open = ""; $block = ""; @endphp
                                @endif
{{--                                <li class='has-sub {{ $test }} {{ $active }}' dt="{{ $menu->id }}"><a href='#'><span>{{ $menu->title }}</span></a>--}}
                                <li class='has-sub {{ $open }} {{ $active }}' dt="{{ $menu->id }}"><a id="{{ $menu->id }}" href='#'><span>{{ $menu->title }}</span></a>
                                    @if(count($menu->childs))
                                        @include('menu.manageChild1',['childs' => $menu->childs, 'block' => $block])
                                    @endif
                                </li>
                            @else
                                @if($menu->article_id == $oneMenu->article->id)
                                    @php $active = 'active' @endphp
                                @else
                                    @php $active = '' @endphp
                                @endif
                                <li class='{{ $active }}'><a href='{{ URL::to('/') }}/pages/{{ $menu->article->slug.'/'.$menu->article->id }}'><span>{{ $menu->title }}</span></a>
                            @endif
                        @endif
                    @endif
                @endforeach
            @endif
        </ul>
    </div>
Это вставка типа menu.manageChild1
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<ul style="display:{{ $block }}">
    @foreach($childs->sortBy('order_id') as $child)
        @if(count($child->childs))
{{--            @php $open = "open"; $block = "block"; @endphp--}}
            @if($child->article_id == $oneMenu->article->id)
                @php $active = 'active'; $open = "open"; $block = "block"; @endphp
            @else
                @php $active = ''; $open = ""; $block = ""; @endphp
            @endif
            <li class='has-sub {{ $open }} {{ $active }}'><a de="{{ $child->article_id }}" test="{{ $child->parent_id }}" href='{{ URL::to('/') }}/pages/{{ $child->article->slug.'/'.$child->article->id }}'><span>{{ $child->title }}</span></a>
                @if(count($child->childs))
                    @include('menu.manageChild1',['childs' => $child->childs, 'block' => $block])
                @endif
            </li>
        @else
            @if($child->article_id == $oneMenu->article->id)
                @php $active = 'active'; @endphp
            @else
                @php $active = '' @endphp
            @endif
            <li class='{{ $active }}'><a href='{{ URL::to('/') }}/pages/{{ $child->article->slug.'/'.$child->article->id }}'><span>{{ $child->title }}</span></a>
        @endif
    @endforeach
</ul>
В принципе открывается. Нужно еще разобраться как открывать когда элемент меню имеет подменю и не открывать когда не имеет.
0
 Аватар для sad67man
2481 / 1406 / 665
Регистрация: 23.08.2015
Сообщений: 3,546
01.09.2023, 21:36
Цитата Сообщение от VlGuvin Посмотреть сообщение
Но я пытаюсь уже допилить что имеется. Вроде должно сработать.
Я вам пытаюсь объяснить, что так сделать не получится. Так как после формирования данных - нужно их еще модифицировать перед подстановкой в html.

Цитата Сообщение от VlGuvin Посмотреть сообщение
Спасибо. В общих чертах понял.
Ничего вы не поняли
0
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
02.09.2023, 20:25  [ТС]
Таки да. Непосредственно в blade активировать нужные елементы меню оставив другие неактивными в цикле не получается.
Не придумал способа как в обратном порядке обнаруживать нужных родителей если они есть.
Пытаюсь пойти Вашим путем.
Ругается на return
PHP Скопировано
1
$data['items'];
в public function getData(): array
PHP Скопировано
1
2
ErrorException
Undefined index: items
Если возвращать просто
PHP Скопировано
1
return $data;
получается такой результат (картинка)
Далее стопорится в item.blade.php с ошибкой
Illegal string offset 'is_active' (View: C:\MyDesigns7\PhpPrj\PhpStormPrj\Laravel RedNord\resources\views\menu\item.blade. php)
Миниатюры
Acordeon Side Menu в Laravel   Acordeon Side Menu в Laravel  
0
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
02.09.2023, 22:26  [ТС]
Обратил внимание, что в blade не работает конструкция с bool типа {{ $menu['is_active'] ? 'open' : '' }}

Добавлено через 21 минуту
Хотя... работает, вроде.
0
 Аватар для sad67man
2481 / 1406 / 665
Регистрация: 23.08.2015
Сообщений: 3,546
02.09.2023, 23:10
VlGuvin, Вижу, что массив криво сформировался. тут ошибка
Цитата Сообщение от sad67man Посмотреть сообщение
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    private function transformItem($menu)
    {
        $item = [
            'label' => $menu->title,
            'is_active' => $menu->article_id == $this->oneMenu->article->id,
            'url' => $menu->article ? URL::to('/')  . '/pages/' . $menu->article->slug.'/'.$menu->article->id : '',
            'items' => [],
        ];
 
        foreach ($menu->childs->sortBy('order_id') as $child) {
            $item['items'] = $this->transformItem($child);
        }
 
        return $item;
    }
Вот так правльно

PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    private function transformItem($menu)
    {
        $item = [
            'label' => $menu->title,
            'is_active' => $menu->article_id == $this->oneMenu->article->id,
            'url' => $menu->article ? URL::to('/')  . '/pages/' . $menu->article->slug.'/'.$menu->article->id : '',
            'items' => [],
        ];
 
        foreach ($menu->childs->sortBy('order_id') as $child) {
            $item['items'][] = $this->transformItem($child);
        }
 
        return $item;
    }
1
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
03.09.2023, 09:37  [ТС]
private function transformItem($menu) откорректировал на $item['items'][]
Если в public function getData(): array
PHP Скопировано
1
2
3
4
...
//        return $data['items'];
        return $data;
...
то
PHP Скопировано
1
$rightMenu = (new MenuRightTransformer($allMenus, $oneMenu, $page))->getData();
выглядит так (картинка)
Миниатюры
Acordeon Side Menu в Laravel  
1
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
03.09.2023, 10:27  [ТС]
Получилось. Спасибо. Немного подправил blade
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@if(!empty($menu['items']))
    <li class="has-sub {{ $menu['is_active'] ? 'open' : '' }}">
        <a href='#'><span>{{ $menu['label'] }}</span></a>
        <ul style="display: {{ $menu['is_active'] ? 'block;' : '' }}">
            @foreach($menu['items'] as $child)
                @include('menu.item', ['menu' => $child])
            @endforeach
        </ul>
    </li>
@else
    <li class="{{ $menu['is_active'] ? 'active' : '' }}">
        <a href='{{ $menu['url'] }}'>
            <span>{{ $menu['label'] }}</span>
        </a>
    </li>
@endif
Выглядит это так (картинка)
Меню раскрывается при загрузке страницы сответствующей пункту из суб суб меню
Миниатюры
Acordeon Side Menu в Laravel  
0
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
03.09.2023, 10:31  [ТС]
Таи да. Я все надеялся, что можно непосредственно в blade определить родителей суб суб элемента. Но...
0
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
06.09.2023, 14:16  [ТС]
PHP Скопировано
1
          $rightMenu = (new MenuRightTransformer($allMenus, $oneMenu, $page))->getData();
По ходу подумал что если $rightMenu имеет структуру с активными подменю то из него можно получить набор линков для breadcrambs (линки активных элементов меню) Пробую так
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
            $data = array();
            foreach ($rightMenu as $menu) {
               $this->bread($menu, $data);
            }
... 
    public function bread($menu, $data){
        if(!empty($menu['items'])) {
            if ($menu['is_active'] == true) {
                array_push($data, $menu['url']);
            }
            foreach ($menu['items'] as $child) {
                $this->bread($child, $data);
            }
             return $data;
        }
        return $data;
    }
Надеюсь в $data получить url_ы активных элементов меню. Но не получаю. Не пойму почему...
0
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
17.04.2024, 20:17  [ТС]
Премного благодарен sad67man за помощь по формированию бокового меню.
Продолжая тему с боковым меню пытаюсь создать линки для breadcrambs (линки активных элементов меню).
PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class MenuRightTransformer
{
    private $allMenus;
    private $oneMenu;
    private $page;
    private $locale;
 
    public function __construct($allMenus, $oneMenu, $page, $locale)
    {
        $this->allMenus = $allMenus;
        $this->oneMenu = $oneMenu;
        $this->page = $page;
        $this->locale = $locale;
    }
 
    public function getData(): array
    {
        $data = [];
 
        foreach ($this->allMenus->sortBy('position') as $menu) {
            if ($menu->name->name == "Right Menu") {
                if ($menu->category->name == $this->page->article_category->name) {
                    $url_temp = "";
                    $data[] = $this->transformItem($menu, $this->locale, $url_temp);
                }
            }
        }
 
        $this->activateItems($data);
 
        return $data;
   }
 
    private function transformItem($menu, $locale, $url_temp)
    {
        $url = $menu->article ? URL::to('/') . '/' . $menu->article->slug : '';
        $item = [
            'label' => $menu->title,
            'is_active' => $menu->article_id == $this->oneMenu->article->id,
            'url' => $url_temp ? $url_temp : $url,
            'on_off' => $menu->on_off,
            'article_id' => $menu->article_id,
            'items' => [],
        ];
 
        if($menu->childs->count()) {
            $ch = "";
            foreach ($menu->childs->sortBy('order_id') as $child) {
                $ch .= '/'.$child->article->slug;
                $url_temp = $item['url'] . $ch;
                $item['items'] [] = $this->transformItem($child, $locale, $url_temp);
                $ch = "";
            }
        }
 
        return $item;
    }
 
    private function activateItems(& $items): bool
    {
        $result = false;
        foreach ($items as $key => &$item) {
            if (!empty($item['items'])) {
                $item['is_active'] = $this->activateItems($item['items']);
            }
            $result = $result || !empty($item['is_active']);
        }
 
        return $result;
    }
}
Линки breadcrambs получились ( 'url' => $url_temp ? $url_temp : $url,). Выглядит примерно так (картинка 1)
Но когда я пытаюсь пойти по ссылке предпоследнего линка меню закрывается (картинка 2)
Должно быть открытое с подсветкой активных пунтов (картинка 3)
Меню закрывается (все результати метода activateItems false) только когда ссылка на пункт меню имеющий в своем составе подменю и сам пункт является поменю от предыдущего. Все работает правильно если переход по ссылке на пункт меню не имеющий подменю.
Также все работает верно для первого уровня подменю (картинка 4)

Подскажите пожалуйста как нужно модифицировать private function activateItems(& $items): bool чтобы меню оствалось открытое при переходе на пункт имеющий в своем составе подменю ($item['is_active'] был true для всех активных пунктов).
Миниатюры
Acordeon Side Menu в Laravel   Acordeon Side Menu в Laravel   Acordeon Side Menu в Laravel  

Acordeon Side Menu в Laravel  
0
 Аватар для sad67man
2481 / 1406 / 665
Регистрация: 23.08.2015
Сообщений: 3,546
17.04.2024, 21:21
Лучший ответ Сообщение было отмечено gogolik как решение

Решение

PHP Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
    private function activateItems(& $items): bool
    {
        $result = false;
        foreach ($items as $key => &$item) {
            if (!empty($item['items'])) {
                $item['is_active'] = $this->activateItems($item['items']) || $item['is_active'];
            }
            $result = $result || !empty($item['is_active']);
        }
 
        return $result;
    }
1
-13 / 6 / 6
Регистрация: 04.08.2015
Сообщений: 568
18.04.2024, 11:22  [ТС]
Таки да. Работает. Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.04.2024, 11:22
Помогаю со студенческими работами здесь

Ремонт Х-к Teka NF660i side by side нет регулировки температуры в морозильнике
Не знаю,чей это клон,надо направление поиска неисправности узнать для того,чтобы холодильщика отправить на сабж В холодильной камере...

Холодильник BOSCH KFU 5750/03 (side by side), Подобрать компрессор
Вечер добрый. Подскажите какой компрессор должен стоять на Холодильнике BOSCH KFU 5750/03 (side by side), R-134a 170гр, или аналог не очень...

Как используется coLinux? Что значит соиспользование Linux и Windows side by side
Я не про выбор ОС при загрузке bios, Topologilinux, например, по англовике устанавливается на виндовс

Посоветуйте простую сборку Low-Side & High-Side
Добрый день, может кто посоветовать простую транзисторную сборку для форсунок и для коммутаторов зажигания? Без наворотов и всяких приблуд....

Whirlpool Side by Side S25D RSS33-A/G Version 8586 168 10010, нестабильная работа силовой платы
Доброго времени суток всем ! Проблема в следующем : нет фиксации реле запуска компрессора на силовой плате. Изначально клиент обратился с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Агрегаты и сущности в DDD микросервисах
Javaican 10.04.2025
Разработка современных программных систем часто приводит на распутье: монолит или микросервисы? Даже при выборе микросервисной архитектуры многие команды сталкиваются с проблемой правильного. . .
Многопоточность в C#: Task и параллельное программирование
UnmanagedCoder 10.04.2025
Современные процессоры уже давно перестали наращивать тактовую частоту в пользу увеличения количества ядер. Это создало интересную ситуацию: разработчики, привыкшие к последовательному. . .
Линейное решение нелинейной задачи. Формулы от LM по моему решению пока не проверял. В итоговой её формуле видно её заблуждение.
Hrethgir 10.04.2025
В продолжение Эта LM дала ответ похожий на нормальный. В комментриях мой комментарий - похоже она ошиблась с выведением итоговой формулы, но остальные проверю. Assistant qwen2. 5-14b-instruct . . . .
Переменные в Python
py-thonny 10.04.2025
Переменная в программировании — это символическое имя, связанное с областью памяти, в которой хранится значение. Она позволяет получать доступ к данным через понятные человеку идентификаторы, а не. . .
Многопоточность в C#: Task и асинхронные операции
UnmanagedCoder 10.04.2025
Многопоточность позволяет выполнять несколько операций одновременно, что важно для решения двух основных задач: повышения скорости выполнения вычислительно-сложных операций и сохранения отзывчивости. . .
Линейное решение не линейной задачи (емкость вычислений в сравнении с традиционными решениями пока не определена).
Hrethgir 10.04.2025
В рамках предстоящих вычислений пришлось (да, я тоже знаю про корень числа, и про степеня, и прочие теоремы, но. . . ) найти способ нахождения отношения двух углов. . . .
Запуск контейнеров Docker на ARM64
Mr. Docker 09.04.2025
Появление таких решений, как Apple M1/ M2, AWS Graviton, Ampere Altra и Raspberry Pi, сделало использование ARM-систем обыденностью для многих разработчиков и DevOps-инженеров. При этом Docker,. . .
Vue SFC компонент на PHP с Fusion
Jason-Webb 09.04.2025
PHP на сервере и JavaScript на клиенте — классическое сочетание, которое, несмотря на свою эффективность, создает определенный когнитивный диссонанс при разработке. В этом контексте появляются. . .
TypeScript vs JavaScript: Отличия и когда что использовать
Reangularity 09.04.2025
JavaScript появился в 1995 году как творение Брендана Эйха и быстро стал основой интерактивности в вебе. За свою историю он прошел путь от простого языка для манипуляций с DOM до полноценной. . .
Подключение Kafka к Elasticsearch
Codd 09.04.2025
Apache Kafka и Elasticsearch — две мощные технологии, которые при совместном использовании создают эффективную платформу для обработки и анализа данных в реальном времени. Kafka, выступая в роли. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер