dhtmlxGrid支持tree和grid、grid之间、grid内部进行拖拽,如在grid内部进行拖拽,可以增加一行;在grid之间拖拽,第一个grid的记录删除,第二个grid增加一行记录。如果我想在拖拽之后不是添加一行而是一列,该怎么做呢? 现在有个需求,就是左边有个tree,右边有个grid,将左边tree的一个节点拖到右边grid的表头并动态增加一列。这个怎么做呢? 如果你想快点看到最后的实现方法,你可以直接跳到本文的最后参看源码。 首先看看dhtmlxTree 关于Drag-n-Drop的例子,其中有这样一个例子Custom Drag Out。 上面的例子,右边定义了一个输入框,其id为“sInput”,代码如下:
function maf() { return false; } tree = new dhtmlXTreeObject("treeboxbox_tree", "100%", "100%", 0); tree.setSkin('dhx_skyblue'); tree.setImagePath("../../codebase/imgs/csh_yellowbooks/"); tree.enableDragAndDrop(true); tree.setDragHandler(maf); tree.enableSmartXMLParsing(true); tree.loadXML("../common/tree_05_drag_n_drop.xml"); function s_control() { this._drag = function(sourceHtmlObject, dhtmlObject, targetHtmlObject) { targetHtmlObject.style.backgroundColor = ""; targetHtmlObject.value = sourceHtmlObject.parentObject.label; } this._dragIn = function(htmlObject, shtmlObject) { htmlObject.style.backgroundColor = "#fffacd"; return htmlObject; } this._dragOut = function(htmlObject) { htmlObject.style.backgroundColor = ""; return this; } } var sinput = document.getElementById('sInput'); tree.dragger.addDragLanding(sinput, new s_control);
为了使tree支持拖拽功能,必须添加以下代码:
tree.enableDragAndDrop(true);
为了实现自定义拖拽的输出,添加了以下代码:
tree.dragger.addDragLanding(sinput, new s_control);
从上面的字母意思可以看出,是在tree的拖拽对象dragger对象上添加一个拖拽着地对象,第一个常数是指拖拽到哪一个区域,第二个常数定义拖拽的三个方法:
this._drag = function(sourceHtmlObject, dhtmlObject, targetHtmlObject) { targetHtmlObject.style.backgroundColor = ""; targetHtmlObject.value = sourceHtmlObject.parentObject.label; } this._dragIn = function(htmlObject, shtmlObject) { htmlObject.style.backgroundColor = "#fffacd"; return htmlObject; } this._dragOut = function(htmlObject) { htmlObject.style.backgroundColor = ""; return this; }
参照上面的思路,我们可以在grid的表头上面定义一个id,然后通过该id获得表头的dom对象,更好的一个方法是通过mygrid.hdr(看看源码就知道列)能过获得grid的表头对象,然后调用下面的方法,定义tree拖拽到grid的表头:
tree.dragger.addDragLanding(mygrid.hdr, new s_control);
但是这个时候,你将tree的一个节点拖到grid的表头,grid不会有任何反应,故需要改写s_control对象的方法,这里主要是改写一个方法:
var insertId; this._drag = function(sourceHtmlObject, dhtmlObject, targetHtmlObject, e) { var zel = e; while (zel.tagName != "TABLE") zel = zel.parentNode; var grid = zel.grid; if (!grid) return; grid.setActive(); if (!grid._mCol || e.button == 2) return; e = grid.getFirstParentOfType(e, "TD") if ((grid) && (!grid._colInMove)) { grid.resized = null; if ((!grid._mCols) || (grid._mCols[e._cellIndex] == "true")) insertId = e._cellIndex + 1; } mygrid.insertColumn(insertId, "12", "ed", 80); }
该方法主要做的事情是计算拖拽落脚时候鼠标焦点所在的列,然后在其右边添加一新的列。
本例最后的代码:
var mygrid; function maf() { return false; } tree = new dhtmlXTreeObject("treeboxbox_tree", "100%", "100%", 0); tree.setSkin('dhx_skyblue'); tree.setImagePath("../../dhtmlxTree/codebase/imgs/csh_yellowbooks/"); tree.enableDragAndDrop(true); //tree.setDragHandler(maf); tree.enableSmartXMLParsing(true); tree.loadXML("../../dhtmlxTree/samples/common/tree_05_drag_n_drop.xml") tree.openAllItems(0); function s_control() { var insertId; this._drag = function(sourceHtmlObject, dhtmlObject, targetHtmlObject, e) { var zel = e; while (zel.tagName != "TABLE") zel = zel.parentNode; var grid = zel.grid; if (!grid) return; grid.setActive(); if (!grid._mCol || e.button == 2) return; e = grid.getFirstParentOfType(e, "TD") if ((grid) && (!grid._colInMove)) { grid.resized = null; if ((!grid._mCols) || (grid._mCols[e._cellIndex] == "true")) insertId = e._cellIndex + 1; } mygrid.insertColumn(insertId, "12", "ed", 80); } } mygrid = new dhtmlXGridObject('gridbox'); mygrid.setImagePath("../codebase/imgs/"); mygrid.setHeader("Sales,Book Title,Author,Price,In Store,Shipping,Bestseller, Date of Publication"); mygrid.setInitWidths("50,150,100,80,80,80,80,200"); mygrid.setColAlign("right,left,left,right,center,left,center,center"); mygrid.setColTypes("dyn,edtxt,ed,price,ch,co,ra,ro"); mygrid.enableDragAndDrop("temporary_disabled", true); mygrid.init(); mygrid.setSkin("dhx_skyblue"); mygrid.enableHeaderMenu(); mygrid.enableColumnMove(true); mygrid.setColumnHidden(2, true); mygrid.attachEvent("onHeaderClick", function(ind, obj) { }); mygrid.loadXML("../common/grid_ml_16_rows_columns_manipulations.xml"); tree.dragger.addDragLanding(mygrid.hdr, new s_control);
本文实现的是将tree拖拽到grid,其实其他的一些支持拖拽的组件也可以做,并不局限于tree组件,甚至还见过有人实现jquery的dtree拖拽到dhtmlxGrid增加一行记录。