Drag an item to dhtmlxGrid and add a column

简介:

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增加一行记录。

参考文章

  • Custom Drag Out:http://www.dhtmlx.com/docs/products/dhtmlxTree/samples/05_drag_n_drop/08_pro_drag_out.html
  • dhtmlxGrid doc:http://docs.dhtmlx.com/doku.php?id=dhtmlxgrid:toc
  • dhtmlxTree doc:http://docs.dhtmlx.com/doku.php?id=dhtmlxtree:toc
  • 目录
    相关文章
    |
    API
    DataTables中的column().visible()
    在数据表中显示和隐藏列非常方便,尤其是在显示信息密度较大的表时。此方法允许即时更改单个列的可见性,或读取列的可见性状态。
    167 0
    |
    容器
    Fragment的replace、add、hide、show的使用和详解
    Fragment的replace、add、hide、show的使用和详解
    Element UI - el-table el-table-column 表头自定义
    Element UI - el-table el-table-column 表头自定义
    694 0
    Element UI - el-table el-table-column 表头自定义
    |
    JavaScript
    Element UI - el-table-column 属性之 show-overflow-tooltip 爬坑
    Element UI - el-table-column 属性之 show-overflow-tooltip 爬坑
    2409 0
    Element UI - el-select 同时获取 value 和 label 的值
    Element UI - el-select 同时获取 value 和 label 的值
    603 0
    when click one item in table Select at least one column to perform the search
    when click one item in table Select at least one column to perform the search
    115 0
    when click one item in table Select at least one column to perform the search
    |
    C#
    Template、ItemsPanel、ItemContainerStyle、ItemTemplate
    原文:Template、ItemsPanel、ItemContainerStyle、ItemTemplate 先来看一张图(网上下的图,加了几个字) 实在是有够“乱”的,慢慢来理一下; 1、Template是指控件的样式 在WPF中所有继承自contentcontrol类的控件都含有此属性,(继承自FrameworkElementdl类的TextBlock等控件无)。
    732 0