How to create sub level of menus using jQuery Nestable plugin with Codeigniter?

Spread the love

Question Description

I’m using jQuery Nestable plugin with Codeigniter3 to create 5 levels of menus for website which a good solution for user can drab and drop to change the level and position of menus items. However my below function can create only first level of menus and when I change to sub level (2,3,4,5) of menu item it won’t work for me.

Issue I could not change menus item to another level from level one. and I couldn’t reversed menus item back to Parent if I’ve been changed it to be a children of any parent. Whatever Jquery Nestable is working very will.

This below function is using to update menus item to database which depend on
Menus column like :id, Parent_id, m_order.

This function will check up inside of $List array by foreach and array_key_exists as below description:

  1. get array data from form using $this->get_child($this->input->post(‘list’));
  2. Using Foreach and array_key_exists function to check any childrent of $List array and if it found any children it will update to database as below CI function.
  3. And This if ($parent_id != $item[‘id’]) {…} will not update parent_id for current id of parent.

    public function savelist() {
    
        if ($this->input->post('list')) {
            $this->do_update($this->input->post('list'));
        }
    }
    
    public function do_update($list, $parent_id = 0, &$m_order = 0) {
    
        foreach ($list as $item) {
    
            $m_order++;
            $data = array(
                'parent_id' => $parent_id,
                'm_order' => $m_order,
            );
            if ($parent_id != $item['id']) {
    
                $where = array('id' => $item['id']);
                var_dump($data . ':' . $where);
                $this->db->where($where);
                $this->db->update('nav', $data);
            }
            if (array_key_exists("children", $item)) {
                $this->do_update($item["children"], $item["id"], $m_order);
            }
        }
    }
    

This Jquery Nestable Plugin and Ajax function is using to send any form data to server.


How ever I’ve already create only one table to store all the menus item. and I make a conditional in PHP to check up Parent and Children when Menus id equal to Parent_id
Here is my table structure

CREATE TABLE IF NOT EXISTS `nav` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `uid` int(10) NOT NULL,
  `text` varchar(500) NOT NULL,
  `link` text NOT NULL,
  `show_condition` int(5) NOT NULL,
  `parent_id` int(5) NOT NULL,
  `m_order` int(9) NOT NULL,
  `class` varchar(50) NOT NULL,
  `data` varchar(50) NOT NULL,
  `des` text NOT NULL,
  `lang` varchar(50) NOT NULL,
  `accord` int(3) NOT NULL,
  `footer` int(3) NOT NULL,
  `f_sta` int(3) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;

The finally I got the menus editor as below image which let me change only one level os menus.

enter image description here

Practice As Follows

I have the same requirement like yours and workout with that take a look on my code which is almost same as yours,

Here is my Controller:

public function select_menu_priority() {
        $data['product'] = $this->menu_model->select_menu_priority();

        $data['li'] = $this->generate_li($data['product']);

        $this->load->view("set_menu_priority_table", $data);
    }

function generate_li($product,$parent = NULL){

        $li = "";

        $p1 = array_filter($product, function($a)use($parent){ return $a['parent_menu_id'] == $parent; });

        foreach ($p1 as $p){

            $inner_li = "";

            $p2 = array_filter($product,function($a)use($p){ return $a['parent_menu_id'] == $p['id']; });

            if($p2){
                $inner_li = $this->generate_li($product,$p['id']);
            }

            $li .= "
  • ".$p['title']."
    ".$inner_li."
  • "; } $ol = "
      ".$li."
    "; return $ol; }

    View set_menu_priority_table.php:

    input->post("entity");
        $entity = $entity['id'];
        if (count($product) > 0) {
            ?>
            

    Go to Category PriorityDrag Menu to set Priority.

    No found.Go to Category Priority

    Please select Category to Set Priority within the Category.

    For Update That Priority Add function update_menu_priority in Controller:

    public function update_menu_priority() {
                $data = $this->input->post("product_data");
                if (count($data)) {
                    $update = $this->menu_model->update_priority_data($data);
                    if ($update) {
                        $result['status'] = "success";
                    } else {
                        $result['status'] = "error";
                    }
                } else {
                    $result['status'] = "error";
                }
                echo json_encode($result);
    
        }
    

    And at last ad model function for that update_priority_data:

    function update_priority_data($data, $parent = NULL) {
            $i = 1;
            foreach ($data as $d) {
                if (array_key_exists("children", $d)) {
                    $this->update_priority_data($d['children'], $d['id']);
                }
                $update_array = array("priority" => $i, "parent_menu_id" => $parent);
                $update = $this->db->where("id", $d['id'])->update("menu", $update_array);
                $i++;
            }
            return $update;
        }
    

    I hope this would be help full to you,
    thanks.

    Leave a Comment

    This site uses Akismet to reduce spam. Learn how your comment data is processed.