通过 $.fn.tree.defaults 重写默认的 defaults。
树(tree)在网页中以树形结构显示分层数据。它向用户提供展开、折叠、拖拽、编辑和异步加载功能。
image树的数据格式(Tree Data Format)
每个节点可以包括下列属性:
id:节点的 id,它对于加载远程数据很重要。 --对应id
text:要显示的节点文本。----对应name
state:节点状态,'open' 或 'closed',默认是 'open'。当设置为 'closed' 时,该节点有子节点,并且将从远程站点加载它们。
checked:指示节点是否被选中。
attributes:给一个节点添加的自定义属性。
children:定义了一些子节点的节点数组。
实例:我们需要这个结构的json
[{
"id":1,
"text":"Folder1",
"iconCls":"icon-save",
"children":[{
"text":"File1",
"checked":true
},{
"text":"Books",
"state":"open",
"attributes":{
"url":"/demo/book/abc",
"price":100
},
"children":[{
"text":"PhotoShop",
"checked":true
},{
"id": 8,
"text":"Sub Bookds",
"state":"closed"
}]
}]
},{
"text":"Languages",
"state":"closed",
"children":[{
"text":"Java"
},{
"text":"C#"
}]
}]
用法比较简单
树(tree)定义在 <ul> 元素中。该标记可定义叶节点和子节点。节点将是 ul 列表内的 <li> 元素。下面演示了将被用于制作嵌套在 ul 元素内的树节点的元素。
ul id="tt" class="easyui-tree">
<li>
<span>Folder</span>
<ul>
<li>
<span>Sub Folder 1</span>
<ul>
<li><span><a href="#">File 11</a></span></li>
<li><span>File 12</span></li>
<li><span>File 13</span></li>
</ul>
</li>
<li><span>File 2</span></li>
<li><span>File 3</span></li>
</ul>
</li>
<li><span>File21</span></li>
</ul>
树(Tree)也可以在一个空的 <ul> 元素中定义,可使用 javascript 加载数据。
<ul id="tt"></ul>
$('#tt').tree({
url:'tree_data.json'
});
其中 url:'tree_data.json' 文档里是写死的获取的是本地的json文件 我们可以写映射地址,获取数据库的信息
使用 loadFilter 来处理来自 ASP.NET web 服务的 json 数据。
$('#tt').tree({
url: ...,
loadFilter: function(data){
if (data.d){
return data.d;
} else {
return data;
}
}
});
data 就是从后台返回的数据
具体可以查看Easyui Tree树中文文档:http://www.jeasyui.net/plugins/185.html
数据库 选用的是 tb_item_cat
CREATE TABLE `tb_item_cat` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '类目ID',
`parent_id` bigint(20) DEFAULT NULL COMMENT '父类目ID=0时,代表的是一级的类目',
`name` varchar(50) DEFAULT NULL COMMENT '类目名称',
`status` int(1) DEFAULT '1' COMMENT '状态。可选值:1(正常),2(删除)',
`sort_order` int(4) DEFAULT NULL COMMENT '排列序号,表示同级类目的展现次序,如数值相等则按名称次序排列。取值范围:大于零的整数',
`is_parent` tinyint(1) DEFAULT '1' COMMENT '该类目是否为父类目,1为true,0为false',
`created` datetime DEFAULT NULL COMMENT '创建时间',
`updated` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`,`status`) USING BTREE,
KEY `sort_order` (`sort_order`)
) ENGINE=InnoDB AUTO_INCREMENT=1183 DEFAULT CHARSET=utf8 COMMENT='商品类目';
image.png
流程
1.通过parent_id 查询分类的列表
在item-add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>
<div style="padding:10px 10px 10px 10px">
<form id="itemAddForm" class="itemForm" method="post">
<table cellpadding="5">
<tr>
<td>商品类目:</td>
<td>
<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">选择类目</a>
<input type="hidden" name="cid" style="width: 280px;"></input>
</td>
</tr>
<tr>
<td>商品标题:</td>
<td><input class="easyui-textbox" type="text" name="title" data-options="required:true" style="width: 280px;"></input></td>
</tr>
<tr>
<td>商品卖点:</td>
<td><input class="easyui-textbox" name="sellPoint" data-options="multiline:true,validType:'length[0,150]'" style="height:60px;width: 280px;"></input></td>
</tr>
<tr>
<td>商品价格:</td>
<td><input class="easyui-numberbox" type="text" name="priceView" data-options="min:1,max:99999999,precision:2,required:true" />
<input type="hidden" name="price"/>
</td>
</tr>
<tr>
<td>库存数量:</td>
<td><input class="easyui-numberbox" type="text" name="num" data-options="min:1,max:99999999,precision:0,required:true" /></td>
</tr>
<tr>
<td>条形码:</td>
<td>
<input class="easyui-textbox" type="text" name="barcode" data-options="validType:'length[1,30]'" />
</td>
</tr>
<tr>
<td>商品图片:</td>
<td>
<a href="javascript:void(0)" class="easyui-linkbutton picFileUpload">上传图片</a>
<input type="hidden" name="image"/>
</td>
</tr>
<tr>
<td>商品描述:</td>
<td>
<textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea>
</td>
</tr>
<tr class="params hide">
<td>商品规格:</td>
<td>
</td>
</tr>
</table>
<input type="hidden" name="itemParams"/>
</form>
<div style="padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm()">重置</a>
</div>
</div>
<script type="text/javascript">
var itemAddEditor ;
//页面初始化完毕后执行此方法
$(function(){
//创建富文本编辑器
itemAddEditor = TAOTAO.createEditor("#itemAddForm [name=desc]");
//初始化类目选择和图片上传器
TAOTAO.init({fun:function(node){
//根据商品的分类id取商品 的规格模板,生成规格信息。第四天内容。
//TAOTAO.changeItemParam(node, "itemAddForm");
}});
});
//提交表单
function submitForm(){
//有效性验证
if(!$('#itemAddForm').form('validate')){
$.messager.alert('提示','表单还未填写完成!');
return ;
}
//取商品价格,单位为“分”
$("#itemAddForm [name=price]").val(eval($("#itemAddForm [name=priceView]").val()) * 100);
//同步文本框中的商品描述
itemAddEditor.sync();
//取商品的规格
/*
var paramJson = [];
$("#itemAddForm .params li").each(function(i,e){
var trs = $(e).find("tr");
var group = trs.eq(0).text();
var ps = [];
for(var i = 1;i<trs.length;i++){
var tr = trs.eq(i);
ps.push({
"k" : $.trim(tr.find("td").eq(0).find("span").text()),
"v" : $.trim(tr.find("input").val())
});
}
paramJson.push({
"group" : group,
"params": ps
});
});
//把json对象转换成字符串
paramJson = JSON.stringify(paramJson);
$("#itemAddForm [name=itemParams]").val(paramJson);
*/
//ajax的post方式提交表单
//$("#itemAddForm").serialize()将表单序列号为key-value形式的字符串
$.post("/item/save",$("#itemAddForm").serialize(), function(data){
if(data.status == 200){
$.messager.alert('提示','新增商品成功!');
}
});
}
function clearForm(){
$('#itemAddForm').form('reset');
itemAddEditor.html('');
}
</script>
在JS中 工具类 common.js
Date.prototype.format = function(format){
var o = {
"M+" : this.getMonth()+1, //month
"d+" : this.getDate(), //day
"h+" : this.getHours(), //hour
"m+" : this.getMinutes(), //minute
"s+" : this.getSeconds(), //second
"q+" : Math.floor((this.getMonth()+3)/3), //quarter
"S" : this.getMilliseconds() //millisecond
};
if(/(y+)/.test(format)){
format = format.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(format)){
format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
}
}
return format;
};
var TT = TAOTAO = {
// 编辑器参数
kingEditorParams : {
//指定上传文件参数名称
filePostName : "uploadFile",
//指定上传文件请求的url。
uploadJson : '/pic/upload',
//上传类型,分别为image、flash、media、file
dir : "image"
},
// 格式化时间
formatDateTime : function(val,row){
var now = new Date(val);
return now.format("yyyy-MM-dd hh:mm:ss");
},
// 格式化连接
formatUrl : function(val,row){
if(val){
return "<a href='"+val+"' target='_blank'>查看</a>";
}
return "";
},
// 格式化价格
formatPrice : function(val,row){
return (val/1000).toFixed(2);
},
// 格式化商品的状态
formatItemStatus : function formatStatus(val,row){
if (val == 1){
return '正常';
} else if(val == 2){
return '<span style="color:red;">下架</span>';
} else {
return '未知';
}
},
init : function(data){
// 初始化图片上传组件
this.initPicUpload(data);
// 初始化选择类目组件
this.initItemCat(data);
},
// 初始化图片上传组件
initPicUpload : function(data){
$(".picFileUpload").each(function(i,e){
var _ele = $(e);
_ele.siblings("div.pics").remove();
_ele.after('\
<div class="pics">\
<ul></ul>\
</div>');
// 回显图片
if(data && data.pics){
var imgs = data.pics.split(",");
for(var i in imgs){
if($.trim(imgs[i]).length > 0){
_ele.siblings(".pics").find("ul").append("<li><a href='"+imgs[i]+"' target='_blank'><img src='"+imgs[i]+"' width='80' height='50' /></a></li>");
}
}
}
//给“上传图片按钮”绑定click事件
$(e).click(function(){
var form = $(this).parentsUntil("form").parent("form");
//打开图片上传窗口(实现多图片上传的功能multiimage)
KindEditor.editor(TT.kingEditorParams).loadPlugin('multiimage',function(){
var editor = this;
editor.plugin.multiImageDialog({
clickFn : function(urlList) {
var imgArray = [];
KindEditor.each(urlList, function(i, data) {
imgArray.push(data.url);
form.find(".pics ul").append("<li><a href='"+data.url+"' target='_blank'><img src='"+data.url+"' width='80' height='50' /></a></li>");
});
form.find("[name=image]").val(imgArray.join(","));
editor.hideDialog();
}
});
});
});
});
},
// 初始化选择类目组件
initItemCat : function(data){
$(".selectItemCat").each(function(i,e){
var _ele = $(e);
if(data && data.cid){
_ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");
}else{
_ele.after("<span style='margin-left:10px;'></span>");
}
_ele.unbind('click').click(function(){
$("<div>").css({padding:"5px"}).html("<ul>")
.window({
width:'500',
height:"450",
modal:true,
closed:true,
iconCls:'icon-save',
title:'选择类目',
onOpen : function(){
var _win = this;
$("ul",_win).tree({
url:'/item/cat/list',
animate:true,
onClick : function(node){
if($(this).tree("isLeaf",node.target)){
// 填写到cid中
_ele.parent().find("[name=cid]").val(node.id);
_ele.next().text(node.text).attr("cid",node.id);
$(_win).window('close');
if(data && data.fun){
data.fun.call(this,node);
}
}
}
});
},
onClose : function(){
$(this).window("destroy");
}
}).window('open');
});
});
},
createEditor : function(select){
return KindEditor.create(select, TT.kingEditorParams);
},
/**
* 创建一个窗口,关闭窗口后销毁该窗口对象。<br/>
*
* 默认:<br/>
* width : 80% <br/>
* height : 80% <br/>
* title : (空字符串) <br/>
*
* 参数:<br/>
* width : <br/>
* height : <br/>
* title : <br/>
* url : 必填参数 <br/>
* onLoad : function 加载完窗口内容后执行<br/>
*
*
*/
createWindow : function(params){
$("<div>").css({padding:"5px"}).window({
width : params.width?params.width:"80%",
height : params.height?params.height:"80%",
modal:true,
title : params.title?params.title:" ",
href : params.url,
onClose : function(){
$(this).window("destroy");
},
onLoad : function(){
if(params.onLoad){
params.onLoad.call(this);
}
}
}).window("open");
},
closeCurrentWindow : function(){
$(".panel-tool-close").click();
},
changeItemParam : function(node,formId){
$.getJSON("/item/param/query/itemcatid/" + node.id,function(data){
if(data.status == 200 && data.data){
$("#"+formId+" .params").show();
var paramData = JSON.parse(data.data.paramData);
var html = "<ul>";
for(var i in paramData){
var pd = paramData[i];
html+="<li><table>";
html+="<tr><td colspan=\"2\" class=\"group\">"+pd.group+"</td></tr>";
for(var j in pd.params){
var ps = pd.params[j];
html+="<tr><td class=\"param\"><span>"+ps+"</span>: </td><td><input autocomplete=\"off\" type=\"text\"/></td></tr>";
}
html+="</li></table>";
}
html+= "</ul>";
$("#"+formId+" .params td").eq(1).html(html);
}else{
$("#"+formId+" .params").hide();
$("#"+formId+" .params td").eq(1).empty();
}
});
},
getSelectionsIds : function (select){
var list = $(select);
var sels = list.datagrid("getSelections");
var ids = [];
for(var i in sels){
ids.push(sels[i].id);
}
ids = ids.join(",");
return ids;
},
/**
* 初始化单图片上传组件 <br/>
* 选择器为:.onePicUpload <br/>
* 上传完成后会设置input内容以及在input后面追加<img>
*/
initOnePicUpload : function(){
$(".onePicUpload").click(function(){
var _self = $(this);
KindEditor.editor(TT.kingEditorParams).loadPlugin('image', function() {
this.plugin.imageDialog({
showRemote : false,
clickFn : function(url, title, width, height, border, align) {
var input = _self.siblings("input");
input.parent().find("img").remove();
input.val(url);
input.after("<a href='"+url+"' target='_blank'><img src='"+url+"' width='80' height='50'/></a>");
this.hideDialog();
}
});
});
});
}
};
其中
// 初始化选择类目组件
initItemCat : function(data){
$(".selectItemCat").each(function(i,e){
var _ele = $(e);
if(data && data.cid){
_ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");
}else{
_ele.after("<span style='margin-left:10px;'></span>");
}
_ele.unbind('click').click(function(){
$("<div>").css({padding:"5px"}).html("<ul>")
.window({
width:'500',
height:"450",
modal:true,
closed:true,
iconCls:'icon-save',
title:'选择类目',
onOpen : function(){
var _win = this;
$("ul",_win).tree({
url:'/item/cat/list',
animate:true,
onClick : function(node){
if($(this).tree("isLeaf",node.target)){
// 填写到cid中
_ele.parent().find("[name=cid]").val(node.id);
_ele.next().text(node.text).attr("cid",node.id);
$(_win).window('close');
if(data && data.fun){
data.fun.call(this,node);
}
}
}
});
},
onClose : function(){
$(this).window("destroy");
}
}).window('open');
});
});
},
createEditor : function(select){
return KindEditor.create(select, TT.kingEditorParams);
},
这个部分用到的异步的ajax 我们做的目的是 点击后弹出的窗口 跟后台数据库获取数据
有url 的映射地址 我们就可以写controller
在数据库里 写一下sql语句 查询 parent_id =1 的类目
image.png
对应com.foreknow.mapper包下 TbItemMapper.xml 的实现类 sql 写法
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select
<include refid="Base_Column_List" />
from tb_item_cat
where id = #{id,jdbcType=BIGINT}
</select>
json 为了转格式 在foreknow-common 下 com.foreknow.common.pojo包
创建 EUTreeNdode.java
package com.foreknow.common.pojo;
/**
树的数据格式(Tree Data Format)
每个节点可以包括下列属性:
id:节点的 id,它对于加载远程数据很重要。
text:要显示的节点文本。
state:节点状态,'open' 或 'closed',默认是 'open'。当设置为 'closed' 时,该节点有子节点,并且将从远程站点加载它们。
* @author Administrator
*
*/
public class EUTreeNdode {
private long id;
private String text;
private String state;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
然后写业务层 service ItemCatService.java
package com.foreknow.service;
import java.util.List;
import com.foreknow.common.pojo.EUTreeNdode;
public interface ItemCatService {
/**
* 根据patentId查询分类
*
* @param patentId
* @return
*/
public List<EUTreeNdode> getCatList(long patentId);
}
返回值是EUTreeNdode.java 对应的Json 属性
我根据id 查出来的是多条数据,而且 我们的json 格式里没有List集合 所以跟之前的分页查询 rows 和total 不一样 我们这次返回值是 List<EUTreeNdode>
然后写实现类ItemCatServiceImpl.java
package com.foreknow.service.impl;
/**
* 树形
*/
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.foreknow.common.pojo.EUTreeNdode;
import com.foreknow.mapper.TbItemCatMapper;
import com.foreknow.pojo.TbItemCat;
import com.foreknow.pojo.TbItemCatExample;
import com.foreknow.pojo.TbItemCatExample.Criteria;
import com.foreknow.service.ItemCatService;
@Service
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
private TbItemCatMapper tbItemCatMapper;
@Override
public List<EUTreeNdode> getCatList(long parentId) {
TbItemCatExample example = new TbItemCatExample();
// Criteria 根据条件查询 封装好的方法 parent_id
Criteria criteria = example.createCriteria();
criteria.andParentIdEqualTo(parentId);
List<TbItemCat> list = tbItemCatMapper.selectByExample(example);
//我们返回的是list 创建一个list
List<EUTreeNdode> resultList = new ArrayList<>();
//对原有的 list 进行便利 没便利一次 就拿到一个TbItemCat cat
for (TbItemCat cat : list) {
EUTreeNdode node = new EUTreeNdode();
//要把list里赋值 保存到resultList 里
node.setId(cat.getId());
node.setText(cat.getName());
//三元运算符? 两种状态
node.setState(cat.getIsParent()?"closed":"open");
resultList.add(node);
}
return resultList;
}
}
方法在com.foreknow.pojo 用自动生成工具生成的
TbItemCat.java 和TbItemCatExample.java 条件
其中TbItemCatExample.java 中 image.png我们给的条件不是id 是 parent_id
TbItemCat.java中 private Boolean isParent; 属性 能获取到parent boolen类型
最后写ItemCatController.java 映射地址 对应 comment.js 后台的取json的
package com.foreknow.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.foreknow.common.pojo.EUTreeNdode;
import com.foreknow.service.ItemCatService;
@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
@RequestMapping("/list")
@ResponseBody
//restful 判断一下 如果要是没拿到的话 我们加一个默认值 是0
public List<EUTreeNdode> getCatList(@RequestParam(value="id",defaultValue="0") long parentId) {
List<EUTreeNdode> list = itemCatService.getCatList(parentId);
return list;
}
}
网友评论