jstree delete \u node()删除子节点

holgip5t  于 2021-06-15  发布在  Mysql
关注(0)|答案(1)|浏览(471)

我已经用jquerytree插件jstree、php和mysql创建了一个treeview,它带有一个contextmenu来创建、重命名和删除节点。treeview的所有节点都依赖于服务器端处理。
这是我的数据库上的表结构:

CREATE TABLE IF NOT EXISTS `treeview_items` (
`id` int(11) NOT NULL,
  `name` varchar(200) NOT NULL,
  `text` varchar(200) NOT NULL,
  `parent_id` varchar(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

这是my index.html上的jstree方法(在div容器中)

$(document).ready(function() {

                    $('#tree-container').jstree({
                        'plugins' : ['dnd', 'state', 'contextmenu', 'json_data' , 'types', 'wholerow', 'theme', 'search', 'sort', 'changed', 'search'],
                        'core' : {
                            'data' : {
                                'url' : 'response.php?operation=get_node',
                                'data' : function (node) {
                                        return { 'id' : node.id };
                                },
                                "dataType" : "json"
                                },
                                'check_callback' : true,
                                'themes' : {
                                    'responsive' : false
                                }
                        },
                        'types': {
                            "child": {
                                "icon": "glyphicon glyphicon-leaf"
                            },
                            "root": {
                                "icon": "glyphicon glyphicon-folder-close"
                            },
                            "default": {
                                "icon": "glyphicon glyphicon-folder-close"
                            }
                        } // , 'contextmenu': {items: context_menu}
                    }).on('create_node.jstree', function (e, data) {
                        $.get('response.php?operation=create_node', {'id' : data.node.parent, 'text' : data.node.text})
                            .done(function (d) {
                                data.instance.set_id(data.node, d.id);
                            })
                            .fail(function () {
                                data.instance.refresh();
                            });
                    }).on('move_node.jstree', function (e, data) {
                        $.get('response.php?operation=move_node', {'id' : data.node.id, 'new_parent_id' : data.node.parent})
                            .done(function (d) {
                                // ...
                                // alert(data.node.parent);
                                data.instance.refresh();
                            })
                            .fail(function () {
                                data.instance.refresh();
                            });
                    }).on('rename_node.jstree', function (e, data) {
                        $.get('response.php?operation=rename_node', {'id' : data.node.id, 'text' : data.node.text})
                            .done(function (d) {
                                // ...
                                data.instance.refresh();
                            })
                            .fail(function () {
                                data.instance.refresh();
                            });
                    }).on('delete_node.jstree', function (e, data) {
                        $.get('response.php?operation=delete_node', {'id' : data.node.id})
                            .done(function (d) {
                                // ...
                                data.instance.refresh();
                            })
                            .fail(function () {
                                data.instance.refresh();
                            });
                    })

                });

这是response.php文件,用于将节点信息更新到mysql数据库中

<?php

// THIS IS AN EXAMPLE DATABASE CONNECTION
$servername = "localhost";
$database = "myDatabase";
$username = "root";
$password = "password";

try { 
    $db = new PDO("mysql:host=$servername;dbname=$database", $username, $password);
    // set the PDO error mode to exception
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    /* echo "Connected successfully"; */
} catch(PDOException $e) {
    /* echo "Connection failed: " . $e->getMessage() . "\n"; */
    header('Location: /public/error_page');
    exit;
}

    $table_name = "`treeview_items`";

    // CREATE, RENAME, DELETE NODE
    if(isset($_GET['operation'])) {

        try {

            $result = null;

            switch($_GET['operation']) {

                case 'get_node':

                    $node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;
                    $sql = "SELECT * FROM " . $table_name;

                    $res = $db->prepare($sql);
                    $res->execute();

                    // Iterate on results row and create new index array of data
                    while($row = $res->fetch(PDO::FETCH_ASSOC)) { 
                        $data[] = $row;
                    }
                    $itemsByReference = array();

                    // Build array of item references:
                    foreach($data as $key => &$item) {
                       $itemsByReference[$item['id']] = &$item;
                       // Children array:
                       $itemsByReference[$item['id']]['children'] = array();
                       // Empty data class (so that json_encode adds "data: {}" ) 
                       $itemsByReference[$item['id']]['data'] = new StdClass();
                    }

                    // Set items as children of the relevant parent item.
                    foreach($data as $key => &$item) {
                        if($item['parent_id'] && isset($itemsByReference[$item['parent_id']])) {
                            $itemsByReference [$item['parent_id']]['children'][] = &$item;
                        }
                    }

                    // Remove items that were added to parents elsewhere:
                    foreach($data as $key => &$item) {
                       if($item['parent_id'] && isset($itemsByReference[$item['parent_id']])) {
                           unset($data[$key]);
                        }
                    }

                    $result = $data;
                    break;

                case 'create_node':

                    $node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : -1;

                    if($node == -1) break;

                    $node_text = isset($_GET['text']) && $_GET['text'] !== '' ? $_GET['text'] : '';
                    $sql = "INSERT INTO " . $table_name . " (`name`, `text`, `parent_id`) VALUES('" . $node_text . "', '" . $node_text . "', '" . $node . "')";

                    $res = $db->prepare($sql);
                    $res->execute();

                    $result = array('id' => $db->lastInsertId());

                    break;

                case 'move_node':

                    $node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : -1;
                    $node_new_parent = isset($_GET['new_parent_id']) && $_GET['new_parent_id'] !== '#' ? (int)$_GET['new_parent_id'] : -1;

                    if($node == -1 || $node_new_parent == -1) break;

                    $sql ="UPDATE " . $table_name . " SET `parent_id` = '" . $node_new_parent . "' WHERE `id` = '" . $node . "'";

                    $res = $db->prepare($sql);
                    $res->execute();

                    break;

                case 'rename_node':

                    $node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;           
                    $node_text = isset($_GET['text']) && $_GET['text'] !== '' ? $_GET['text'] : '';

                    $sql = "UPDATE " . $table_name . " SET `name`='" . $node_text . "',`text`='" . $node_text . "' WHERE `id`= '" . $node . "'";

                    $res = $db->prepare($sql);
                    $res->execute();

                    break;

                case 'delete_node':

                    $node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;

                    $sql ="DELETE FROM " . $table_name . " WHERE `id`= '" . $node ."'";

                    $res = $db->prepare($sql);
                    $res->execute();

                    break;

                default:
                    throw new Exception('Unsupported operation: ' . $_GET['operation']);
                    break;

            }

            header('Content-Type: application/json; charset=utf-8');
            echo json_encode($result);

        } catch (Exception $e) {

            header($_SERVER["SERVER_PROTOCOL"] . ' 500 Server Error');
            header('Status:  500 Server Error');
            echo $e->getMessage();
        }
        die();
    }

?>

例如,我创建了这个树视图结构:
图片1.png
这是phpmyadmin上的树视图结构:
img2.png格式
创建和重命名工作正常,但我有一个问题,如果我删除节点
当我选择节点来删除它时,我的代码只删除选定的节点而不删除子节点。例如,如果我删除节点“folder 5”,我的代码只删除节点“folder 5”,而不删除“folder 6”,当我刷新treeview时,很明显,我没有得到正确的treeview,因为节点“folder 6”的“parent\u id”=18不再存在。
我怎样才能解决这个问题?我将删除选定的节点和所有子节点。
谢谢!对不起,我英语不好

xqkwcwgp

xqkwcwgp1#

您可以添加新案例:

case 'delete_node_with_children':

    $node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;

    $sql = "DELETE FROM {$table_name} WHERE id = :node OR parent_id = :node";

    $res = $db->prepare($sql);
    $res->execute(['node' => $node]);

    break;

或者,作为更好的方法,我建议您使用mysql触发器。
顺便说一句,您应该像在我的代码中那样使用准备好的语句来避免sql注入。更多信息:如何防止php中的sql注入?

相关问题