所以我现在已经在这一段时间了。我正在尝试创建一个具有父子关系的可拖动表,但是不能将子项移出父组,并且所有父项都可以在彼此之间进行排序。我已经从管理菜单代码中模拟了我的表单和主题,并且我重复了该功能。问题是我可以将孩子移到另一个父母,或让它成为父母。举例说明:
Category 1
|
|--Item 1
|--Item 2
Category 2
|
|--Item 3
|--Item 4
|--Item 5
我希望能够将项目1和项目2相互排序,项目3,项目4和项目5相互排序,但不能在类别1和类别2之间移动它们。我还需要能够将第1类和第2类相互排序,带着孩子们。我已经浏览了$action
,$group
,$subgroup
设置与$class
设置混合的多种组合,用于我丢失跟踪的类别和项目。到目前为止,我没有尝试过任何结果。这是我目前代码的相关位:
以我的形式:
$form['#tree'] = true;
foreach($categories as $cat) {
if(!isset($form['categories'][$cat->cid])){
$form['categories'][$cat->cid] = array(
'weight' => array(
'#type' => 'weight',
'#delta' => 25,
'#attributes' => array('class' => array('item-weight', 'item-weight-' . $cat->cid)),
),
'cid' => array(
'#type' => 'hidden',
'#value' => $cat->cid,
'#attributes' => array('class' => array('cid')),
),
);
foreach($cats[$cat->cid] as $item) {
$form['categories'][$cat->cid]['items'][$item->id] = array(
'weight' => array(
'#type' => 'weight',
'#delta' => 25,
'#default_value'=> $item->weight,
'#attributes' => array('class' => array('item-weight', 'item-weight-' . $cat->cid)),
),
'cid' => array(
'#type' => 'hidden',
'#value' => $cat->cid,
'#attributes' => array('class' => array('cid')),
),
);
}
}
}
在我的主题中:
$children = element_children($form['categories']);
$rows = array();
if(count($children) > 0) {
foreach($children as $cid) {
$row = array(
drupal_render($form['categories'][$cid]['weight']) .
drupal_render($form['categories'][$cid]['cid']),
);
$rows[] = array(
'data' => $row,
'class' => array('draggable', 'tabledrag-root'),
);
foreach(element_children($form['categories'][$cid]['items']) as $id) {
$row = array(
theme('indentation', array('size' => 1)) . drupal_render($form['categories'][$cid]['items'][$id]['name']),
drupal_render($form['categories'][$cid]['items'][$id]['weight']) .
drupal_render($form['categories'][$cid]['items'][$id]['cid']),
);
$rows[] = array(
'data' => $row,
'class' => array('draggable', 'tabledrag-leaf'),
);
}
drupal_add_tabledrag('cat-table', 'order', 'sibling', 'item-weight', 'item-weight-' . $cid);
}
}
drupal_add_tabledrag('cat-table', 'match', 'parent', 'cid', 'cid', 'cid', true, 1);
$output = theme('table', array('header' => $headers, 'rows' => $rows, 'attributes' => array('id' => 'cat-table')));
$output .= drupal_render_children($form);
return $output;
我已经阅读了drupal_add_tabledrag()
的文档,查看了代码,查看了示例代码,并在drupal.org和Google上搜索过,但还没有提出任何建议。
到目前为止,我唯一的解决方案是复制和修改tabledrag.js文件以消除这些功能,但在停止项目的缩进问题时(意思是,不要让它们与类别相同),保留它们在同一类别一直没有乐趣。
我想最重要的问题是,使用标准的Drupal是可能的吗?
答案 0 :(得分:0)
我知道你已经做了很多编码,所以你可能不想在此时放弃它,但DraggableViews很有可能实现这一目标。您可以设置普通视图并添加此draggableviews过滤器,它会添加权重和可选的父引用。视图本身使用与Drupal后端表的其余部分相同的拖放系统。
或者,您可以使用术语引用并将分类术语绑定到节点,并使用该拖放操作。
如果我错过了你需要的东西,我很抱歉,我以为我会提供这个更简单的解决方案,因为它在过去一定很好用。祝你好运。
答案 1 :(得分:0)
刚刚将此功能添加到我的模块
https://github.com/player259/ajax_table
没有任何帮助,演示已经过时,但我不时正在研究它
通过覆盖tabledrag.js函数
来实现节支持使用此代码段插入表格
$form['map'] = array(
'#type' => 'ajax_table',
'#header' => array(t('Element'), t('Settings'), t('Weight')),
'rows' => array(),
'#draggable' => array(
// drupal_add_tabledrag will be called in theme layer
// NULL first arg to apply to this table
array(NULL, 'match', 'parent', 'perfect-form-parent', 'perfect-form-parent', 'perfect-form-index'),
array(NULL, 'depth', 'group', 'perfect-form-depth', NULL, NULL, FALSE),
array(NULL, 'order', 'sibling', 'perfect-form-weight'),
),
'#draggable_groups' => array(),
);
foreach ($map as $i => $element) {
// ... some logic
$form['map']['rows'][$i] = array(
'data' => array(
'element' => array(),
'settings' => array(),
'tabledrag' => array(
'index' => array(
'#type' => 'hidden',
'#value' => $element['data']['tabledrag']['index'],
'#attributes' => array('class' => array('perfect-form-index')),
),
'parent' => array(
'#type' => 'hidden',
'#default_value' => $element['data']['tabledrag']['parent'],
'#attributes' => array('class' => array('perfect-form-parent')),
),
'depth' => array(
'#type' => 'hidden',
'#default_value' => $element['data']['tabledrag']['depth'],
'#attributes' => array('class' => array('perfect-form-depth')),
),
'weight' => array(
'#type' => 'weight',
'#delta' => $max_weight,
'#default_value' => $weight,
'#attributes' => array('class' => array('perfect-form-weight')),
),
),
),
'#attributes' => array('class' => array($row_class_current, $row_class_child)),
);
// This means that row with $row_class_child class could have as parent
// only row with $row_class_parent class
// NULL means root - there are no parents
$form['map']['#draggable_groups'][$row_class_child] =
$depth ? $row_class_parent : NULL;
}
答案 2 :(得分:0)
我在工作中遇到了类似的问题,所以在这里发布我的解决方案,因为我找不到所有情况下都能正常工作。它在javascript中完成100%,在php端你只需要在pid中设置tabledrag与pid上的parent匹配,并在重量上与兄弟姐妹排序。
当前代码在示例模块(tabledrag parent / child)上工作以使其适应您的需要,通过您的类为PID输入字段更改.example-item-pid。您只需将其添加到示例代码中即可使其工作,并查看它是否符合您的需求。
第一个函数使任何删除与目标元素不具有相同父元素(PID)的元素的尝试无效。
Second Function绕过dragRow函数,将元素放在正确的位置(=目标行的最后一个子节点)和右边深度(=与目标行相同的深度)。
/**
* Invalidate swap check if the row target is not of the same parent
* So we can only sort elements under the same parent and not move them to another parent
*
* @override Drupal.tableDrag.row.isValidSwap
*/
// Keep the original implementation - we still need it.
Drupal.tableDrag.prototype.row.prototype._isValidSwap = Drupal.tableDrag.prototype.row.prototype.isValidSwap;
Drupal.tableDrag.prototype.row.prototype.isValidSwap = function(row) {
if (this.indentEnabled) {
if (row && $('.example-item-pid', this.element).val() !== $('.example-item-pid', row).val()) {
return false;
}
}
// Return the original result.
return this._isValidSwap(row);
}
/**
* Position the dragged element under the last children of the element target for swapping when moving down our dragged element.
* Removed the indentation, since we can not change parent.
* @override Drupal.tableDrag.row.dragRow
*/
Drupal.tableDrag.prototype.dragRow = function (event, self) {
if (self.dragObject) {
self.currentMouseCoords = self.mouseCoords(event);
var y = self.currentMouseCoords.y - self.dragObject.initMouseOffset.y;
var x = self.currentMouseCoords.x - self.dragObject.initMouseOffset.x;
// Check for row swapping and vertical scrolling.
if (y != self.oldY) {
self.rowObject.direction = y > self.oldY ? 'down' : 'up';
self.oldY = y; // Update the old value.
// Check if the window should be scrolled (and how fast).
var scrollAmount = self.checkScroll(self.currentMouseCoords.y);
// Stop any current scrolling.
clearInterval(self.scrollInterval);
// Continue scrolling if the mouse has moved in the scroll direction.
if (scrollAmount > 0 && self.rowObject.direction == 'down' || scrollAmount < 0 && self.rowObject.direction == 'up') {
self.setScroll(scrollAmount);
}
// If we have a valid target, perform the swap and restripe the table.
var currentRow = self.findDropTargetRow(x, y);
if (currentRow) {
if (self.rowObject.direction == 'down') {
/**
* When going down we want to position the element after the last children and not right under the currentRow
*/
// create a new row prototype with currentRow
var rowObject = new self.row(currentRow, 'mouse', self.indentEnabled, self.maxDepth, false);
// extract all children
var childrenRows = rowObject.findChildren();
// if we have children
if (childrenRows.length > 0) {
// we change the row to swap with the last children
currentRow = childrenRows[childrenRows.length - 1];
}
self.rowObject.swap('after', currentRow, self);
}
else {
self.rowObject.swap('before', currentRow, self);
}
self.restripeTable();
}
}
/**
* We have disabled the indentation changes since it is not possible to change parent.
*/
return false;
}
};