Fat Free Framework: how create dynamic menu with submenu - php

I have this table
id children voce alias pubblicato
11 NULL Chi Siamo chi-siamo 1
12 11 Chi Siamo - Sub chi-siamo-sub 1
So the id 12 is children (submenu) of 11.
With this block i can print the first level of a menu
<repeat group="{{ #result }}" key="{{ #ikey }}" value="{{ #voce }}">
<li>{{ trim(#voce.voce) }}</li>
</repeat>
(result is result of query SQL).
Of course i need to obtain that in my scheme menu will be (pseudo // bootstrap html code)
<li>ID 11 menu
<ul class="dropdown-menu">
<li>Id 12 menu</li>
</ul>
So, in (very!) pseudo code
if (children is not null) {
don't echo </li>
echo <ul class="dropdown">
echo voce where children == parent
}
Thank you very much.
PS If you think that my table need to be edit, don't worry, tell me your best solution!

i did this the following way:
// load page tree
$pages = $model->find();
$pageTree = array();
$pagesByID = array();
foreach($pages as $index => $page)
$pagesByID[$page->_id] = $page->cast();
// reorder to tree
foreach ($pagesByID as &$value)
if ($parent = $value['pid'])
$pagesByID[$parent]['childs'][] = &$value;
else
$pageTree[] = &$value;
$pageTree is now a multi-dimensional array, with child keys, if that page has some childs.

Related

how to create <ul> thing for each 10 <li> created?

I need to create every 10 records of the new <ul> to store the rest.
The idea is that every 10 <li> he creates another <ul> block that will contain 10 more and so on.
What is returned from the bank in blade:
As I'm trying to do with the following result now:
Can someone help me?
Via array_chunk() you can split your array into chunks of 10 items (or less if it's the last chunk).
#php
$chunks = array_chunk($category->recursiveChildren, 10);
#endphp
#foreach($chunks as $chunk)
<ul>
#foreach($chunk as $child)
<li>{{ $child }}</li>
#endforeach
</ul>
#endforeach

how to make navigation dropdown menu in Pyro CMS

I have file "header.html" in partial folder, here my code
<ul class="sf-menu" id="mainMenu">
{{ shoesmart:showMenu group="header" indent="tab"}}
<li>{{ name }}
{{ if children }}
<ul>
{{ children }}
<li>{{ name }}</li>
{{ /children }}
</ul>
{{ endif }}
</li>
{{/shoesmart:showMenu}}
</ul>
and I have file "shoesmart.php" in plugins folder, here my code :
function showMenu()
{
$return = '';
$menu_list = $this->db->select('*,CONCAT(pua.type,"/",pua.keyword) as path',false)
->from('menu mn')
->join('product_url_alias pua','mn.url_alias_id=pua.url_alias_id','LEFT')
->where('status',1)
->get()
->result_array();
foreach ($menu_list as $result) {
$return[] = array(
'name' => $result['name'],
'url' => BASE_URL.'home/'.$result['path']
);
}
return $return;
}
and my table name in database is "default_menu" that have structure:
menu_id url_alias_id name status parent_id
1 868 Men 1 0
2 869 woman 1 0
but when I refresh in browser, just show main menu, its mean that the submenu didn't show. Should I change my code ? or I also add new table for submenu in my database ?So please help me .. I have deadline project tomorrow T.T

PHP - "n" number of children in a list

This question is in relation to: Group by in Laravel 5
Essentially, what I have have is a series of "Groups" and each group can have a as many child groups as they want. So it could look something like this:
Group 1
Group 1 Child
Group 1's child
Group 1 1's Child
Group 2
At the moment, I am only able to display the group, and their children, using:
<ul>
#foreach($contents as $content)
<li>{{$content->title}}</li>
#if($content->children->count() > 0)
<ul>
#foreach($content->children as $childContent)
<li>{{$childContent->title}}</li>
#endforeach
</ul>
#endif
#endforeach
</ul>
If I want to add more layers of children, I have to code this, with another if statement as well as a foreach statement. Obviously this is not practical when a group has n^3,... number of children.
Is there a dynamic, while-loop approach to solving this problem? Any help would be greatly appreciated!!
What you need is a recursive partial - a one that would load itself as long as there are some more group levels to be displayed.
// list_group.blade.php
<li>
{{ $content->title }}
#if($content->children->count() > 0)
<ul>
#foreach($content->children as $childContent)
#include('list_group', array('content' => $childContent))
#endforeach
</ul>
#endif
</li>
//in your template
<ul>
#foreach($contents as $content)
#include('list_group', array('content' => $content))
#endforeach
</ul>

blade templates recursive includes

I have an array of items that represent the file and dir structure of a directory on the server.
The $items array is constructed like this:
Array
(
[folder1] => Array
(
[folder1_1] => Array
(
[0] => filenameX.txt
[1] => filenameY.txt
)
)
[pages] => Array
(
)
[0] => filename.txt
[1] => filename1.txt
)
what we want, is essentially <ul> with <li> for every node.
the resulting HTML should be something like
folder1/
folder1_1/
filenameX.txt
filenameY.txt
pages/
filename_1.txt
filename_2.txt
Now, my question has to do with nested includes with laravel's blade templating engine.
I have a view list.blade.php with the following contents
<div class="listing">
#include('submenu', array('items', $items))
</div>
and I pass it the array like this:
View::make('list')->with('items', $items)
the included template (submenu.blade.php) has the following:
<ul>
#foreach($items as $key=>$value)
#if (is_array($value))
<li>{{$key}}/
#include('submenu', array('items', $value))
</li>
#else
<li>{{$value}}</li>
#endif
#endforeach
</ul>
I #include the same template from within itself but with the new data, in case the $value is an array (directory)
First of all, is this at all possible?
If not, is there another way to achive the desired result?
TIA,
Yes, this is indeed possible.
However, there's an issue in your includes, you have:
#include('submenu', array('items', $value))
It should be:
#include('submenu', array('items' => $value))
It's worth noting also another hidden blade statment, #each. You can use this instead of looping through the array yourself, something like this:
<ul>
#each('item.detail', $items, 'item')
</ul>
Then you create a new blade file named item.detail and pop what you previously had in your loop in that file. It helps to clean up your view from having more and more nested loops.
The data for the item when you are inside your new blade file will be held in the third parameter, in this case $item
Instead of using array, use an eloquent collection. Instead of using #include, use \View::make. It cleans up the code a bit. Here is an example drop down menu for the Foundation 5 framework, using an eloquent model with parent/child relationship:
My model has a parent->child relationship
public function children() {
return $this->hasMany('Category', 'parent_id');
}
I generate my results like so in my controller
$categories = \Category::where('parent_id', '=', '0')->with('children')->get();
Blade template: _partials.dd-menu.blade.php
<ul class="{{$class}}">
#foreach($items as $item)
<?php
$active = $item->id == \Input::get('category') ? 'active' : '';
$hdd = $item->children->count() ? 'has-dropdown' : '';
?>
<li class="{{$hdd}} {{$active}}">
{{$item->name}}
#if ($item->children->count())
{{ View::make('_partials.dd-menu')->withItems($item->children)->withClass('dropdown')}}
#endif
</li>
#endforeach
In your parent blade:
<nav class="top-bar" data-topbar role="navigation">
<ul class="title-area">
<li class="name">
<h1>Categories</h1>
</li>
<!-- Remove the class "menu-icon" to get rid of menu icon. Take out "Menu" to just have icon alone -->
<li class="toggle-topbar menu-icon"><span>Menu</span></li>
</ul>
<section class="top-bar-section">
<!-- Right Nav Section -->
{{ View::make('_partials.dd-menu')->withItems($categories)->withClass('right')}}
</section>
</nav>

How to store multiple level ul list in a MySQL database?

I have a long, at least 5 levels <ul> list i have listed from a mysql database. The user has the opportunity, to sort the items, drop one item from one list to another, rename them, or delete. Then save it.
I am using PHP for listing, and Javascript/Jquery for rearranging the items.
My question is whats the best way to split the ul li elements into an array? It's important to have the parent id of every element.
Very simplified sample code:
Parent item name
<ul data-level='0'>
<li>
Child item name
<ul data-level='1'>
<li>2nd level item 1</li>
<li>2nd level item 2</li>
<li>2nd level item 3</li>
<li>2nd level item 4</li>
</ul>
</li>
</ul>
As the result, '2nd level item 2' should have it's parent 'Child item name' (it's id is stored in a hidden input field next to it's name).
The list can be any levels, as the user can add additional levels too. The code must handle a 15 levels list too.
I was thinking about getting the value of a hidden input placed in every <li> element via javascript. the JQuery is capable of getting the number of children. But that doesn't seem to be the best solution.
IMHO when submit button clicked, your jquery can iterate the list and create JSON object (that each member has parent value, 0 for root) and send it behind with AJAX.
Here is a possible solution:
HTML:
Parent item name
<ul class="0" id="level_0_count_0" data-level='0'>
<li>
Child item name
<ul class="1" id="level_1_count_0" data-level='1'>
<li>ul 0 2nd level item 1pppppppp</li>
<li>ul 0 2nd level item 2pppppppp</li>
<li>ul 0 2nd level item 3pppppppp</li>
<li>
ul 0 2nd level item 4
<ul class="2" id="level_2_count_0" data-level='1'>
<li>ul 2 3nd level item 1cccccccc</li>
<li>ul 2 3nd level item 2cccccccc</li>
<li>ul 2 3nd level item 3cccccccc</li>
<li>ul 2 3nd level item 4cccccccc</li>
</ul>
</li>
</ul>
</li>
<li>
Child item name
<ul class="1" id="level_1_count_1" data-level='1'>
<li>ul 1 2nd level item 1</li>
<li>ul 1 2nd level item 2</li>
<li>ul 1 2nd level item 3</li>
<li>ul 1 2nd level item 4</li>
</ul>
</li>
JavaScript:
var $j = jQuery.noConflict();
$j(document).ready(function() {
var temp = new Array();
find_ul(0, temp);
});
function find_ul(parent_class, new_object_, level_count){
if( $j('.' + parent_class + ' > li > ul').length == 0){
return new_object_;
}else{
var current_objs = $j('.' + parent_class + ' > li > ul');
var i = 0;
parent_class++;
$j.each(current_objs, function() {
var current_ul_id = '';
var object_lis = $j('ul#level_' + parent_class + '_count_' + i + ' > li');
var b = 0;
var tempora = new Array();
var current_ul_id = $j(this).attr('id');
alert(current_ul_id);
$j.each(object_lis, function() {
tempora[b] = $j(this).html();
b++;
alert($j(this).html());
});
new_object_[i] = {ul_id: current_ul_id, lis:tempora};
i++;
});
}
find_ul(parent_class, new_object_);
}
You can see / test it out at:
http://jsfiddle.net/BsDpY/4/
This would generate an array with levels for each layer of ul/li
so it will first go through the first level (the parents) then go through its child ULs..
Hope that helps.

Categories