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' οnfοcus='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());
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章