首页 文章

如何使用带有Codeigniter的jQuery Nestable插件创建子级菜单?

提问于
浏览
11

我正在使用 jQuery Nestable pluginCodeigniter3 为网站创建5个级别的菜单,这是一个很好的解决方案,用户可以单调和删除以更改菜单项的级别和位置 . 但是我的下面的功能只能创建第一级菜单,当我更改为菜单项的子级别(2,3,4,5)时,它对我不起作用 .

Issue 我无法将菜单项从第一级更改为另一级 . 我无法将菜单项反转回 Parent ,如果我已将其更改为任何 parentchildren . 无论Jquery Nestable如何努力工作 .

以下功能用于将菜单项更新为依赖于Menus列的数据库,如: idParent_idm_order .

此函数将通过 foreacharray_key_exists 检查 $List 数组内部,如下所述:

  • 使用$ this-> get_child($ this-> input-> post('list'))从 form 获取数组数据;

  • 使用 Foreacharray_key_exists 函数检查任何 childrent$List 数组,如果找到任何 children ,它将更新到数据库,如下面的CI函数 .

  • 并且 if ($parent_id != $item['id']) 不会为父级的当前 id 更新 parent_id .

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);
        }
    }
}

这个Jquery Nestable Plugin和Ajax函数用于将任何表单数据发送到服务器 .

<script>
        $(document).ready(function () {

            var updateOutput = function (e) {
                var list = e.length ? e : $(e.target), output = list.data('output');
                $.ajax({
                    method: "POST",
                    url: "savelist",
                    data: {
                        list: list.nestable('serialize')
                    }, success: function (data) { //, textStatus, jqXHR
                        console.log(list.nestable('serialize'));
                    }
                }).fail(function (jqXHR, textStatus, errorThrown) {
                    alert(" Unable to save new list order: " + errorThrown);
                });
            };
            $('#nestable').nestable({
                group: 1,
                maxDepth: 7,
            }).on('change', updateOutput);
        });
    </script>

我怎么只创建一个表来存储所有菜单项 . 并且我在 PHP 中设置条件以检查 ParentChildren 当菜单 id equalParent_id 这是我的表格结构

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 ;

最后我得到了菜单编辑器,如下图所示,我只能更改一个级别的菜单 .

enter image description here

1 回答

  • 6

    我有与你的相同的要求和锻炼,看看我的代码几乎与你的相同,

    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 .= "<li class='dd-item' data-id='".$p['id']."'><div class='dd-handle'>".$p['title']."</div>".$inner_li."</li>";
    
            }
    
            $ol = "<ol class='dd-list'>".$li."</ol>";
    
            return $ol;
        }
    

    View set_menu_priority_table.php:

    <?php
    if (isset($product)) {    
        $entity = $this->input->post("entity");
        $entity = $entity['id'];
        if (count($product) > 0) {
            ?>
            <div class="row-fluid" style="margin-bottom: 10px;">
                <button class="btn btn-success btn-sm" tabindex="4" id="save">
                    <i class="fa fa-check"></i> Save
                </button>
                <p class="pull-right" style="margin-bottom: 10px;"><?php if ($entity == "product") { ?><a href="javascript:void(0)" id="show_category" class="text-success" style="margin-right:10px;font-weight: bold;text-decoration: underline">Go to Category Priority</a><?php } ?><span class="label label-info ">Drag Menu to set Priority.</span></p>            
                <div class="clear"></div>
            </div>
            <div class="dd" id="product_list">
                <input type="hidden" id="entity_type" name="entity" value="<?php echo $entity ?>" />    
                <?php echo $li; ?>
            </div>
        <?php } else { ?>        
            <p><span class="label label-warning">No <?php echo ($entity == "product") ? "product" : "category"; ?> found.</span><?php if ($entity == "product") { ?><a href="javascript:void(0)" id="show_category" class="text-success" style="margin-left:15px;font-weight: bold;text-decoration: underline">Go to Category Priority</a><?php } ?></p>            
            <?php
        }
    } else {
        ?>
        <p class="label label-info">Please select Category to Set Priority within the Category.</p>
    <?php } ?>
    
    <script type="text/javascript">
    $("#save").off("click").on("click", function() {
                var product_data = $("#product_list").nestable("serialize");
                var data = {product_data: product_data, entity: $("#entity_type").val()};
                if ($.bbq.getState("product_category") !== undefined) {
                    data['product_category'] = $.bbq.getState("product_category");
                }
                ajax_call({
                    url: '<?php echo site_url("admin/menu/update_menu_priority");?>',
                    type: "post",
                    dataType: "json",
                    data: data,
                    beforeSend: function() { },
                    success: function(result) {
                        if (result['status'] == "success") {
                            alert("Priority Updated!");
                        } 
                });
            });
    </script>
    

    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;
        }
    

    谢谢,我希望这对你有所帮助 .

相关问题