Pieduriens Posted October 3, 2013 Report Share 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 Link to comment Share on other sites More sharing options...
101111 Posted October 3, 2013 Report Share 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 Link to comment Share on other sites More sharing options...
Pieduriens Posted October 3, 2013 Author Report Share 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 Link to comment Share on other sites More sharing options...
codez Posted October 3, 2013 Report Share 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 Link to comment Share on other sites More sharing options...
Pieduriens Posted October 3, 2013 Author Report Share 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 Link to comment Share on other sites More sharing options...
codez Posted October 3, 2013 Report Share Posted October 3, 2013 $data masīvā pid jāieliek pēdiņās. Quote Link to comment Share on other sites More sharing options...
Pieduriens Posted October 6, 2013 Author Report Share 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 Link to comment Share on other sites More sharing options...
codez Posted October 6, 2013 Report Share 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 Link to comment Share on other sites More sharing options...
Pieduriens Posted October 6, 2013 Author Report Share 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 Link to comment Share on other sites More sharing options...
codez Posted October 6, 2013 Report Share 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 Link to comment Share on other sites More sharing options...
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.