# xq-treegrid

一个基于Bootstrap5的树状表格列表，采用异步加载节点的方式，可以在HTML的Table中显示树状数据，并支持添加、更新、删除等操作，同时还可以拖动排序。

## 安装与使用

```bash
npm i xq-treegrid
```

#### typescript方式
在typescript代码中引入xq-treegrid的代码

```ts
import xqTreegrid from 'xq-treegrid';
```

同时还需要在HTML页面代码中引入xq-treegrid的scss代码
<link rel="stylesheet" href="./scss/xq-treegrid.scss">

#### javascript方式

<script type="text/javascript" src="/xq-treegrid/js/xq-treegrid.min.js"></script>
同时还需要在HTML页面代码中引入xq-treegrid的css代码
<link rel="stylesheet" href="/xq-treegrid/xq-treegrid.min.css">

导入后在相应的HTML文件代码中的Table标签添加class="xq-treegrid"的属性就可以自动运行。
如果想要开启看拖动排序，需要以class属性添加“xq-drag”，例如：class="xq-treegrid xq-drag"。
#### 备注说明
在相应的页面还得引入bootstrap的js和css文件。

元素的id规则为：字段名称_id编号

tbody里的tr的属性包括：depth、is_leaf、id、pid、class。

具体情况参考示例代码
#### HTML示例代码
```ts
<form enctype="application/json" method="post">
    <div class="table-responsive">
        <table  class="table table-bordered xq-table-hover xq-table-striped xq-treegrid xq-drag">
        <thead>
            <tr>
                <th style="width:60px;">选择</th>
                <th style="text-align: left;">栏目名称</th>
                <th style="width:60px;">类型</th>
                <th style="width:60px;">状态</th>
                <th style="width:170px;">操作</th>
            </tr>
        </thead>
        <tbody>
            <tr depth="1" is_leaf="0" id="xq_58cb49e77e5239062c000a43" pid="58514b454a495f524f4f5430" class="xq-treegrid-top">
                <td>
                    <input type="checkbox" id="58cb49e77e5239062c000a43[id]" name="58cb49e77e5239062c000a43[id]" value="58cb49e77e5239062c000a43" class="form-check-input">
                </td>
                <td style="text-align:left;">
                    
                    <input type="text" id="name_58cb49e77e5239062c000a43" name="58cb49e77e5239062c000a43[name]" value="栏目1" class="form-control" style="width:200px;" required="1" placeholder="请输入一个标题">
                </td>
                <td>栏目</td>
                <td style="vertical-align: middle;">
                    <div style="width:32px;margin:auto;" class="form-check form-switch">
                        <input class="form-check-input" type="checkbox" id="status_58cb49e77e5239062c000a43" name="58cb49e77e5239062c000a43[status]" checked>
                    </div>
                    
                </td>
                <td>
                    <input type="button" value="复制" class="btn btn-primary btn-sm xq-copy"><input type="button" value="设置" class="btn btn-primary btn-sm xq-edit"><input type="button" value="删除" class="btn btn-danger btn-sm xq-delete">
                </td>
            </tr>
            <tr depth="1" is_leaf="0" id="xq_58d8baa17e52391108000a38" pid="58514b454a495f524f4f5430" class="xq-treegrid-top xqkeji-treegrid-expanded">
                <td>
                    <input type="checkbox" id="58d8baa17e52391108000a38[id]" name="58d8baa17e52391108000a38[id]" value="58d8baa17e52391108000a38" class="form-check-input">
            
                </td>
                <td style="text-align:left;">
                    
                    <input type="text" id="name_58d8baa17e52391108000a38" name="58d8baa17e52391108000a38[name]" value="栏目2" class="form-control" style="width:200px;" required="1" placeholder="请输入一个标题">
                </td>
                <td>栏目</td>
                <td style="vertical-align: middle;">
                    <div style="width:32px;margin:auto;" class="form-check form-switch">
                        <input class="form-check-input" type="checkbox" id="status_58d8baa17e52391108000a38" name="58d8baa17e52391108000a38[status]">
                    </div>
                    
                </td>
                <td>
                    <input type="button" value="复制" class="btn btn-primary btn-sm xq-copy"><input type="button" value="设置" class="btn btn-primary btn-sm xq-edit"><input type="button" value="删除" class="btn btn-danger btn-sm xq-delete">
                </td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td>
                    <input type="checkbox" class="xq-check-all form-check-input">
                    
                </td>
                <td colspan="99" style="text-align:left;">
                    <button  type="button" class="btn btn-primary xq-add" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-trigger="hover" data-bs-html="true" title="没选中时，添加顶级栏目；<br/>有选中时，添加子栏目。">添加</button>
                </td>
            </tr>
        </tfoot>
        </table>
    </div>
</form>	
```
本组件需要自己显示第一层的数据，第二层以上的数据会异步自动加载。

#### 相关的处理接口
###### 加载子节点的数据： /subnode/父节点的id。
返回信息示例：
```json
[
    {
        "id":"58cb49e77e5239062c000001",
        "name": "栏目1-1",
        "depth": 2,
        "is_leaf":1,
        "pid":"58cb49e77e5239062c000a43",
        "status":1,
        "type":1,
        "content":"<td><input type=\"checkbox\" id=\"id_58cb49e77e5239062c000001\" name=\"58cb49e77e5239062c000001[id]\" value=\"58cb49e77e5239062c000001\" class=\"form-check-input\"></td><td style=\"text-align:left;\"><input type=\"text\" id=\"name_58cb49e77e5239062c000001\" name=\"58cb49e77e5239062c000001[name]\" value=\"栏目1-1\" class=\"form-control\" style=\"width:200px;\" required=\"1\" ></td><td>栏目</td><td><div class=\"form-check form-switch\"><input class=\"form-check-input\" type=\"checkbox\" id=\"status_58cb49e77e5239062c000001\" name=\"58cb49e77e5239062c000001[status]\" checked=\"\"></div></td><td><input type=\"button\" value=\"复制\" class=\"btn btn-primary btn-sm xq-copy\"><input type=\"button\" value=\"设置\" class=\"btn btn-primary btn-sm xq-edit\"><input type=\"button\" value=\"删除\" class=\"btn btn-danger btn-sm xq-delete\"></td>"
    }
]
```
###### 添加子节点： /add
post信息：{"pid":""}父节点的id
有选中相应节点后再添加时，添加子节点
没有选中则添加第一层的节点

返回信息示例：
```json
{
    "id":"",
    "name": "",
    "depth": 2,
    "is_leaf":1,
    "pid":"",
    "status":1,
    "type":1,
    "content":""
}

```
需要根据添加时提供的父节点id，动态返回数据。特别是depth、is_leaf、content会影响到显示。

###### 修改数据： /change
post信息：{id: "节点的id", field:"更改的字段名称",value: "最新的值"}
返回信息示例：
```json
{
    "success":true,
    "message": "栏目保存成功.",
    "code": 200
}

```

###### 删除数据： /delete
post信息：{id: "节点的id"}
返回信息示例：
```json
{
    "success":true,
    "message": "删除成功.",
    "code": 200
}

```
###### 移动节点： /move
post信息：
{
  "id": "58d8baa17e52391108000a38", //拖动节点的id
  "pid": "58514b454a495f524f4f5430",//拖动后节点的父节点id
  "nextid": "58cb49e77e5239062c000a43"//拖动后下一个邻居节点的id
}
返回信息示例：
```json
{
    "success":true,
    "message": "栏目移动成功.",
    "code": 200
}

```




