1. 程式人生 > >Ztree,非同步逐級載入資料,連線資料庫增刪改,模糊搜尋

Ztree,非同步逐級載入資料,連線資料庫增刪改,模糊搜尋

需求是需要做一個國家資訊的樹形結構圖,那麼就避免不了使用樹狀結構的外掛,而用的比較多的外掛就是Ztree和Jstree,個人在這裡強烈推薦Ztree,

原因如下:1、Ztree的外掛文件全中文解釋,畢竟是國產外掛,所以對於英語不太好的同學來說,會減少很多麻煩,而Jstree全英文

                    2、Ztree的demo比Jstree更加詳細,更能夠去理解外掛中各種事件,屬性的使用

下面直接放圖:

一、JS頁面;需要引用的ztree的包我就不累贅了,不過推薦一個網站 http://www.bootcdn.cn/    不用下載包,直接複製連結就可以

1)首先是非同步逐級載入資料,即點選一個節點載入一層資料,不點選就不會去查詢該節點下的子節點,優點:後臺程式碼邏輯簡單,只需要將節點ID作為parentId去查即可,缺點就是對於後面的模糊搜尋來說,如果你的某個節點下的資料沒有開啟也就是說沒有去後臺查,那模糊搜尋是搜尋不到該節點下的資料資訊的,比如你沒有開啟湖南省這個節點,湖南省節點下有長沙市這個節點資訊,但是因為你沒有開啟所以不會去後臺查詢,那麼你模糊搜尋長,是不會顯示出湖南省下長沙市的節點資訊的。

<script type="text/javascript">
(function () { //下面的引數如果有不懂的,可以結合文件查詢,很詳細
var setting = {
async: {
enable: true, //是否非同步
url: "geographic/getAllInfo",
autoParam: ["id"], //傳的引數
},
view: {
expandSpeed: "",
addHoverDom: addHoverDom,
removeHoverDom: removeHoverDom,
selectedMulti: false,
showIcon: true,
showLine: true,
fontCss:getFontCss
},
edit: {
enable: true
},
callback: {
onClick: zTreeOnOnClick,
beforeRemove: beforeRemove,
beforeRename: beforeRename
},
data: {
simpleData: {
enable: true,
idKey: "id",
pIdKey: "pId",
rootPId: 0
}
}
};
$(function () {
$.ajax({
type: "POST",
url: "geographic/getAllInfo",
dataType: "json",
success: function (data) {
$.fn.zTree.init($("#geographicInfoTree"), setting, data.data);
}
})
key = $("#key");
key.bind("focus", focusKey)
.bind("blur", blurKey)
.bind("propertychange", searchNode)
.bind("input", searchNode);
});
function zTreeOnOnClick(even, treeId, treeNode) {
var treeObj = $.fn.zTree.getZTreeObj(treeId);
var node = treeObj.getNodeByTId(treeNode.tId);
if (!node.children) {
$.ajax({
type: "POST",
url: "geographic/getAllInfo",
data: {
id: treeNode.id
},
dataType: "json",
success: function (data) {
if (data) {
newNode = treeObj.addNodes(node, data);
}
},
error: function () {
layer.msg('Operation failed!', {icon: 2, time: 2000});
}
});
}
}

2)實現滑鼠放到節點上,就會出現增加,刪除,修改的圖示(用到事件),其中刪除修改按鈕是Ztree自帶的,增加的話需要我們手動去寫按鈕程式碼

function beforeRemove(treeId, treeNode) {
$.ajax({
type: "POST",
url: "geographic/deleteNode",
data: {
id: treeNode.id
},
dataType: "json",
success: function (data) {
if (data === 'success') {
window.parent.layer.close(window.parent.layer.index);
layer.msg('Delete successful!', {icon: 1, time: 1000});
} else {
layer.msg('Delete failed!', {icon: 2, time: 2000});
}
}
})
}
function beforeRename(treeId, treeNode, newName) {
if (!newName) {
layer.msg('The name can not be empty!', {icon: 2, time: 2000});
return false;
}
$.ajax({
type: "post",
url: "geographic/updateInfo",
data: {
id: treeNode.id,
name: newName
},
dataType: "json",
success: function (data) {
if (data == 'success') {
window.parent.layer.close(window.parent.layer.index);
layer.msg('Update successful!', {icon: 1, time: 1000});
} else {
layer.msg('Update failed!', {icon: 2, time: 2000});
}
}
});
}
var newCount = 1;
function addHoverDom(treeId, treeNode) {
var sObj = $("#" + treeNode.tId + "_span");
if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) {
return;
}
var addStr = "<span class='button add' id='addBtn_" + treeNode.tId
+ "' title='add node' onfocus='this.blur();'></span>";
sObj.after(addStr);
var btn = $("#addBtn_" + treeNode.tId);
var id;
if (btn) {
btn.bind("click", function () {
var zTree = $.fn.zTree.getZTreeObj("geographicInfoTree");
var name = "new name" + (newCount++);
$.post(
"geographic/addInfo",
{
id: treeNode.id,
name: name,
},
function(data){
id = data; //需要從後臺返回增加的節點的ID
zTree.addNodes(treeNode, { //增加一個節點後需要將樹重新整理,需用到此方法,資料只需要滿足 zTree 的節點資料必需的屬性即可,具體請參考API  
id:id,
pId: treeNode.id,
name: name
});
}
);
});
return false;
} else {
return false;
}
};
function removeHoverDom(treeId, treeNode) {
$("#addBtn_" + treeNode.tId).unbind().remove();
};


3)模糊搜尋(此處為樓主借鑑http://blog.csdn.net/wangjingna/article/details/50488921)點選開啟連結

 var lastValue = "", nodeList = [], fontCss = {};
    function callNumber(){
        var zTree = $.fn.zTree.getZTreeObj("geographicInfoTree");
        if(nodeList.length){
            zTree.selectNode(nodeList[0],false );
            document.getElementById("key").focus();      
        }else if(nodeList.length === 0){
            zTree.cancelSelectedNode();
        }
        if(document.getElementById("key").value ===""){
            zTree.cancelSelectedNode();
        }
    }
    function focusKey(e) {
        if (key.hasClass("empty")) {
            key.removeClass("empty");
        }
    }
    function blurKey(e) {
        if (key.get(0).value === "") {
            key.addClass("empty");
        }
    }
    function searchNode(e) {
        var zTree = $.fn.zTree.getZTreeObj("geographicInfoTree");
        var value = $.trim(key.get(0).value);
        var keyType = "name";

        if (key.hasClass("empty")) {
            value = "";
        }
        if (lastValue === value) {return;}
        lastValue = value;
        if (value === ""){
            updateNodes(false);
            return;
        }
        updateNodes(false);
        nodeList = zTree.getNodesByParamFuzzy(keyType, value);      
        updateNodes(true);    }    
         unction updateNodes(highlight){ 
       var zTree = $.fn.zTree.getZTreeObj("geographicInfoTree");     
      for( var i=0, l=nodeList.length; i<l; i++) {       
     nodeList[i].highlight = highlight;       
     zTree.expandNode(nodeList[i].getParentNode(), true, false, false);    
        zTree.updateNode(nodeList[i]); 
         }
      }   
      function getFontCss(treeId, treeNode) {     
      return (!!treeNode.highlight) ? {color:"#A60000", "font-weight":"bold"} : {color:"#333", "font-weight":"normal"};   
 }})();

二、controller層

@Controller
@RequestMapping("/geographic")
public class GeographicInfoController extends BaseController {

    @Autowired
private GeographicInfoService geographicInfoService;
@RequestMapping("/addInfo")
    @ResponseBody
public String addInfo(@RequestParam(value = "id", defaultValue = "0") String id,String name) {
       String str = geographicInfoService.addInfo(name, id);
        return str;
}

    @RequestMapping("/updateInfo")
    @ResponseBody
public String updateInfo(GeographicInfoDO geographicInfoDO) {
        boolean flag = geographicInfoService.updateInfo(geographicInfoDO);
        return flag ? "success" : "false";
}

    @RequestMapping(value = "/getAllInfo")
    @ResponseBody
public List getNodeInfo(@RequestParam(value = "id", defaultValue = "0") String id) {
        List<Map<String, Object>> list = geographicInfoService.getChildrenInfo(id);
        return list;
}

    @RequestMapping(value = "/deleteNode")
    @ResponseBody
public String deleteNodeInfo(String id){
        boolean flag =geographicInfoService.deleteNodeInfo(id);
        return flag ? "success" : "false";
}

    @RequestMapping(value = "/getListPage")
    public String getListPage(){
        return "geographicInfo/geographicInfoList";
}
}
三、service層
@Service
public class GrographicServiceImpl implements GeographicInfoService {

    @Autowired
private GrographicInfoDAO grographicInfoDAO;
@Override
public String addInfo(String name, String parent_id) {
        GeographicInfoDO geographicInfoDO = new GeographicInfoDO();
geographicInfoDO.setId(DataBaseUtil.getTimeUUID());   //樓主採用手動新增ID而不是自增加,因為前臺需要返回一個增加節點的ID,這樣很方便,當然還有其他的返回ID方法,可以自行百度
geographicInfoDO.setParentId(parent_id);
geographicInfoDO.setName(name);
geographicInfoDO.setStatus("1");
grographicInfoDAO.save(geographicInfoDO);
       return geographicInfoDO.getId();
}

    @Override
public boolean updateInfo(GeographicInfoDO geographicInfoDO) {
        int acount = grographicInfoDAO.update(geographicInfoDO);
        if(acount > 0){
            return true;
}
        return false;
}

    @Override
public List<Map<String,Object>> getChildrenInfo(String id) { return grographicInfoDAO.findGeographicChildrenByParentId(id); }



    @Override
public boolean deleteNodeInfo(String id) {
        int acount = grographicInfoDAO.delete(id);
        if(acount > 0){
            return true;
}
        return false;
}


}
四、DO層
public class GeographicInfoDO extends BaseDo<String, String> {
    private String parentId;
    private String name;
    private String status;
    public String getStatus() {
        return status;
}

    public void setStatus(String status) {
        this.status = status;
}

    public String getParentId() { return parentId; }

    public void setParentId(String parentId) {
        this.parentId = parentId;
}

    public String getName() {
        return name;
}

    public void setName(String name) {
        this.name = name;
}


}
五、時區
public class DataBaseUtil {
    private static final Logger logger = LoggerFactory.getLogger(DataBaseUtil.class);
    private static final String DATABASE_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String DATABASE_DATE_NOTTIME_FORMAT = "yyyy-MM-dd";
    private static final String DATABASE_SHORT_UUID_FORMAT = "yyMMddHHmmss";
    public DataBaseUtil() {
    }

    public static String getUUID() {
        return StringUtil.replace(UUID.randomUUID().toString(), "-", "");
}

    public static String getTimeUUID() {
        return "K" + (new SimpleDateFormat("yyMMddHHmmss")).format(new Date()) + getStringRandom(7);
}

    public static Date getDateByString(String date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (date != null && date.length() >= "yyyy-MM-dd HH:mm:ss".length()) {
            try {
                return dateFormat.parse(date);
} catch (Exception var3) {
                logger.warn("[databaseUtil] converter to Data error,", var3);
                return null;
}
        } else {
            return null;
}
    }

    public static String getDateStrByDate(Date date) {
        return date != null && !StringUtil.isBlank("yyyy-MM-dd HH:mm:ss") ? (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE)).format(date) : "";
}

    public static String getDateStrByNow() {
        return getDateStrByDate(new Date());
}

    public static Date getDateByStringNotTime(String date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (date != null && date.length() >= "yyyy-MM-dd".length()) {
            try {
                return dateFormat.parse(date);
} catch (Exception var3) {
                logger.warn("[databaseUtil] converter to Data error,", var3);
                return null;
}
        } else {
            return null;
}
    }

    public static String getDateStrNotTimeByDate(Date date) {
        return date != null && !StringUtil.isBlank("yyyy-MM-dd") ? (new SimpleDateFormat("yyyy-MM-dd", Locale.SIMPLIFIED_CHINESE)).format(date) : "";
}

    public static String getDateStrNotTimeByNow() {
        return getDateStrNotTimeByDate(new Date());
}

    public static String getStringRandom(int length) {
        String val = "";
Random random = new Random();
        for(int i = 0; i < length; ++i) {
            val = val + String.valueOf(random.nextInt(10));
}

        return val;
}

    public static void main(String[] args) {
        System.out.println(getTimeUUID());
}
}