Pieduriens Posted October 3, 2013 Report Posted October 3, 2013 Labvakar. Cīnos ar funkciju, kas veido Nestable List no array. Pašlaik ir izveidots arrays no kura mēģinu būvēt menu, bet loģiskajā shēmā tieku tikai līdz 2lvl menu items. Cenšos rakt tālāk, bet zem 2lvl sub netieku. Kur un kā likt nākamos blokus? DB: name |id|url| position | parent_id --------------------------------------------------------------------- PHP 1 url 100 0 CodeIgniter 4 url 100 1 HTML 10 url 100 0 CSS 11 url 100 10 Inline 12 url 100 11 Python 2 url 101 12 PHP: public function create_menu() { $this->db->order_by('position', 'asc'); $query = $this->db->get('navigation'); $output = ''; $i = 0; foreach ($query->result_array() as $menuss){ $i++; $menu[$i]['id'] = $menuss['id']; $menu[$i]['key'] = $menuss['parent_id']; $menu[$i]['name'] = $menuss['name']; $menu[$i]['url'] = $menuss['url']; $menu[$i]['position'] = $menuss['position']; } foreach ($menu as $item) { $output .= '<li data-id="'.$item['id'].'" class="dd-item">'; if ($item['key'] == 0) // root category { $output .= '<div class="dd-handle">'.$item['name'].'</div>'; } else{ ############SUB############### $output .= '<ol class="dd-list"><li data-id="'.$item['id'].'" class="dd-item">'; $output .= '<div class="dd-handle">'.$item['name'].'</div>'; $output .= '</li></ol>'; ############SUB############### } $output .= '</li>'; } return $output; } Paldies par ieteikumiem ;) Pieduriens. Quote
101111 Posted October 3, 2013 Report Posted October 3, 2013 (edited) Pārveido sarakstu koka struktūrā $allItems = $query->result_array() foreach ($allItems as $key => $value) { $allItems[$key]['children'] = array(); } $addChildrens = function($item) use ($allItems, & $addChildrens) { foreach ($allItems as $i) { if ($i['parent_id'] == $item['id']) { $i['children'][] = $addChildrens($i); } } return $item; }; $tree = array(); foreach ($allItems as $i) { if ($i['parent_id'] == 0) { $tree[] = $addChildrens($i); } } Edited October 3, 2013 by 101111 Quote
Pieduriens Posted October 3, 2013 Author Report Posted October 3, 2013 To: 101111 Paldies par ieteikumu. Taču neteikšu ka saprotu kā tālāk šo izmantot. Īpaši mulsina rinda: $addChildrens = function($item) use ($allItems, & $addChildrens) { Quote
codez Posted October 3, 2013 Report Posted October 3, 2013 (edited) 1. pārveido datus, tā, lai tie ir pieejami pēc id un lai katrs ieraksts satur visus child elementu id (metode set). 2. izmanto vienkāršu rekursīvu metodi, kurai padod kuri id ir jāizvada un tā attiecīgi izsauc pati sevi ar visiem apakš id un tā, kamēr vien id ir (metode show). $level tiek izmantots tīri noformējumam. http://codepad.org/UzR7dTlJ <?php $data = array( array("id"=>1,"name"=>"CSS", pid=> 6), array("id"=>3,"name"=>"PHP", pid=> 0), array("id"=>6,"name"=>"HTML", pid=> 0), array("id"=>8,"name"=>"Controllers", pid=> 10), array("id"=>10,"name"=>"Kohana", pid=> 3), array("id"=>12,"name"=>"Models", pid=> 10) ); Class Menu{ public $items=array(); public $root=array(); public function set($data){ foreach($data as $item){ $this->items[$item['id']]=$item; $this->items[$item['id']]['childs']=array(); } foreach($data as $item){ if($item['pid']==0){ array_push($this->root,$item['id']); } else { array_push($this->items[$item['pid']]['childs'],$item['id']); } } } function show($ids,$level=0){ foreach($ids as $id){ echo str_repeat(".",$level*3).$this->items[$id]['name']."\n"; $this->show($this->items[$id]['childs'],$level+1); } } } $menu = new Menu(); $menu->set($data); $menu->show($menu->root); Edited October 3, 2013 by codez Quote
Pieduriens Posted October 3, 2013 Author Report Posted October 3, 2013 Paldies Codez. Izskatās diezgan cerīgi, tik tieku pie A PHP Error was encountered Severity: Notice Message: Use of undefined constant pid - assumed 'pid' Quote
Pieduriens Posted October 6, 2013 Author Report Posted October 6, 2013 (edited) Ok, kā atsevišķa klase ārpus CI sistēmas viss Codez koks strādā. Taču pievienojot Codez Menu klasi CI sistēmas library, ar echo rezultāti izvadās pirm html taga, ( ar return nestrādā Cik saprotu ir jāizveido $outputs ar un tad jāatgriež, taču tādā gadijumā tieku tikai pie: <ol class="dd-list"> PHPHTML </ol> Library Menu Clase: Class Menu{ public $item=array(); public $root=array(); public function set($data){ foreach($data as $item){ $this->items[$item['id']]=$item; $this->items[$item['id']]['childs']=array(); } foreach($data as $item){ if($item['pid']==0){ array_push($this->root,$item['id']); } else { array_push($this->items[$item['pid']]['childs'],$item['id']); } } } function show($ids,$level=0){ $output = ''; foreach($ids as $id){ $output .= str_repeat('<ol class="dd-list"><li class="dd-item"><div class="dd-handle">',$level).$this->items[$id]['name'].str_repeat('</div></li></ol>',$level); $this->show($this->items[$id]['childs'],$level+1); } return $output; } } Controlieris: public function index(){ $this->load->library('menu'); // <-- Codez Klase $a = $this->navigation_model->render_menu_array(); $b = $this->menu->set($a); $this->data['menu'] = $this->menu->show($this->menu->root); $this->render_page('admin/navigation'); } Ko daru nepareizi? Paldies. Edited October 6, 2013 by Pieduriens Quote
codez Posted October 6, 2013 Report Posted October 6, 2013 (edited) Show funkcija izvada rezultātum nevis to atgriež. Savukārt tev vajag, lai funkcija atgriež rezultātu, kuru tālāk padot templeitam, tātad tik tālu doma pareiza. Tālāk vajag saprast kā strādā rekursija. Metode show atgriež menu html noteikta id elementiem. Kad metode show pati sevī izsauc pati sevi, tā atgriež menu htmlu, kuŗš ir submenu konkrētajā brīdī apstrādātajam id. Tātad arī tā atgrieztais html kods ir jāiekļauj: http://codepad.org/jz2CGd2f function show($ids,$level=0){ if (count($ids)==0) return ""; $output = ''; $output .= str_repeat(" ",$level*4).'<ul>'."\n"; foreach($ids as $id){ $output .= str_repeat(" ",$level*4+2).'<li>'."\n"; $output .= str_repeat(" ",$level*4+4).$this->items[$id]['name']."\n"; $output .= $this->show($this->items[$id]['childs'],$level+1); $output .= str_repeat(" ",$level*4+2).'<\li>'."\n"; } $output .= str_repeat(" ",$level*4).'</ul>'."\n"; return $output; } P.S. Protams reālā kodā tos str_repeat un "\n" var mest ārā. Edited October 6, 2013 by codez Quote
Pieduriens Posted October 6, 2013 Author Report Posted October 6, 2013 Ok tiktāl taka būtu. Taču kādēļ klāt nācis $levelam: *4, un *4+2 ? Reāli jūtos mazliet apjucis.. Vēlos šo izmantot, lai varu ubūvēt nestable list, bet izskatās ka tur style strutūra ir savādāka: <li data-id="1" class="dd-item"><button type="button" data-action="collapse">Collapse</button><button type="button" data-action="expand" style="display: none;">Expand</button> <div class="dd-handle">Item 1</div> <ol class="dd-list"><li data-id="11" class="dd-item"> <div class="dd-handle">Item 11</div> </li></ol></li> <li data-id="2" class="dd-item"><button type="button" data-action="collapse">Collapse</button><button type="button" data-action="expand" style="display: none;">Expand</button> <div class="dd-handle">Item 2</div> <ol class="dd-list"> <li data-id="3" class="dd-item"><button type="button" data-action="collapse">Collapse</button><button type="button" data-action="expand" style="display: none;">Expand</button> <div class="dd-handle">Item 3</div> <ol class="dd-list"><li data-id="9" class="dd-item"> <div class="dd-handle">Item 9</div> </li></ol></li> </ol> </li> <li data-id="5" class="dd-item"><button type="button" data-action="collapse">Collapse</button><button type="button" data-action="expand" style="display: none;">Expand</button> <div class="dd-handle">Item 5</div> <ol class="dd-list"> <li data-id="6" class="dd-item"><button type="button" data-action="collapse">Collapse</button><button type="button" data-action="expand" style="display: none;">Expand</button> <div class="dd-handle">Item 6</div> <ol class="dd-list"><li data-id="7" class="dd-item"><button type="button" data-action="collapse">Collapse</button><button type="button" data-action="expand" style="display: none;">Expand</button> <div class="dd-handle">Item 7</div> <ol class="dd-list"><li data-id="8" class="dd-item"><button type="button" data-action="collapse">Collapse</button><button type="button" data-action="expand" style="display: none;">Expand</button> <div class="dd-handle">Item 8</div> <ol class="dd-list"><li data-id="10" class="dd-item"> <div class="dd-handle">Item 10</div> </li></ol></li></ol></li></ol></li> </ol> </li> Quote
codez Posted October 6, 2013 Report Posted October 6, 2013 str_repeat ir tikai tāpēc, lai html izvads būtu skārtots pa rindām, ja tas nav vajadzīgs, bez tā var iztikt un viss būs vienā rindā: http://codepad.org/rSgPeS0O function show($ids,$level=0){ if (count($ids)==0) return ""; $output = '<ul>'; foreach($ids as $id){ $output .= '<li>'; $output .= $this->items[$id]['name']; $output .= $this->show($this->items[$id]['childs'],$level+1); $output .= '<\li>'; } $output .= '</ul>'; return $output; } Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.