Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Drupal:父子可拖动表_Drupal_Drupal 7 - Fatal编程技术网

Drupal:父子可拖动表

Drupal:父子可拖动表,drupal,drupal-7,Drupal,Drupal 7,所以我已经研究了一段时间了。我试图创建一个具有父子关系的可拖动表,但不能将子对象移出父组,并且所有父对象都可以在彼此之间排序。我已经根据管理菜单代码对我的表单和主题进行了建模,我让它复制了该功能。问题是,我可以将孩子移动到另一个家长,或者让它成为家长。举个例子: Category 1 | |--Item 1 |--Item 2 Category 2 | |--Item 3 |--Item 4 |--Item 5 我希望能够将项目1和项目2彼此排序,并将项目3、项目4和项目5彼此排序,但不能将它

所以我已经研究了一段时间了。我试图创建一个具有父子关系的可拖动表,但不能将子对象移出父组,并且所有父对象都可以在彼此之间排序。我已经根据管理菜单代码对我的表单和主题进行了建模,我让它复制了该功能。问题是,我可以将孩子移动到另一个家长,或者让它成为家长。举个例子:

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\u add\u tabledrag()的文档,查看了代码,查看了示例代码,搜索了drupal.org和Google,但没有找到任何结果

到目前为止,我唯一的解决方案是复制和修改tabledrag.js文件以消除这些功能,但在停止项目的缩进问题(也就是说,不让它们与类别相同)的同时,将它们保持在相同的类别中并不有趣


我想最重要的问题是,使用标准Drupal这可能吗?

我知道您已经做了很多编码,所以现在您可能不想放弃它,但是DragableViews非常适合完成这一点。您可以设置普通视图并添加此DragableViews过滤器,它会添加权重和可选的父引用。视图本身使用与Drupal的其他后端表相同的拖放系统

或者,您可以使用术语引用并将分类术语绑定到节点,只需使用拖放即可


如果我在你的需求中遗漏了什么,我很抱歉,我想我会提供这个更简单的解决方案,因为它在过去确实为我提供了很好的服务。祝你好运。

刚刚将此功能添加到我的模块中

没有帮助,演示已经过时,但我会不时地做

节支持是通过重写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;
}

我在工作中遇到了类似的问题,所以在这里发布我的解决方案,因为我发现没有一个在所有情况下都能正确工作。它是100%在javascript中完成的,在php端,您只需在pid上设置tabledrag与父级匹配,并在权重上与同级排序

当前代码在示例模块(tabledrag parent/child)上工作为了使其适应您的需要,请按类更改pid输入字段的.example项pid。您只需将其添加到示例代码中,即可使其正常工作,并查看它是否符合您的需要

第一个函数使删除与目标元素不具有相同父元素(PID)的元素的任何尝试无效

第二个函数绕过dragRow函数,将元素放置在正确的位置(=目标行的最后一个子元素)和正确的深度(=与目标行相同的深度)

/**
*如果行目标不属于同一父级,则使交换检查无效
*因此,我们只能对同一父级下的元素进行排序,而不能将它们移动到另一父级
*
*@override Drupal.tableDrag.row.isValidSwap
*/
//保留原始实现—我们仍然需要它。
Drupal.tableDrag.prototype.row.prototype.\u isValidSwap=Drupal.tableDrag.prototype.row.prototype.isValidSwap;
Drupal.tableDrag.prototype.row.prototype.isValidSwap=函数(行){
如果(此.indentEnabled){
if(行&&$('.example item pid',this.element).val()!==$('.example item pid',row.val()){
返回false;
}
}
//返回原始结果。
返回此项。\u isValidSwap(世界其他地区);
}
/**
*将拖动的元素放置在元素目标的最后一个子元素下,以便在向下移动拖动的元素时进行交换。
*删除了缩进,因为我们无法更改父项。
*@override Drupal.tableDrag.row.dragRow
*/
Drupal.tableDrag.prototype.dragRow=函数(事件,自){
if(自拖放对象){
self.currentMouseCoords=self.mouseCoords(事件);
var y=self.currentMouseCoords.y-self.dragObject.initMouseOffset.y;
var x=self.currentMouseCoords.x-self.dragObject.initMouseOffset.x;
//检查行交换和垂直滚动。
如果(y!=self.oldY){
self.rowObject.direction=y>self.oldY“向下”:“向上”;
self.oldY=y;//更新旧值。
//检查是否应滚动窗口(以及滚动速度)。
var scrollmount=self.checkScroll(self.currentMouseCoords.y);
//停止任何当前滚动。
clearInterval(self.scrollInterval);
//如果鼠标已沿滚动方向移动,则继续滚动。
如果(scrollAmount>0&&self.rowObject.direction==“向下”| | scrollAmount<0&&self.rowObject.direction==“向上”){
自身设置滚动(滚动量);
}
//如果我们有一个有效的目标,则执行交换并重新对表执行管道。
var currentRow=self.findDropTargetRow(x,y);
如果(当前行){
如果(self.rowObject.direction=='down'){
/**
*向下时,我们希望将元素放置在最后一个子元素之后,而不是当前行的正下方
*/
//使用currentRow创建新行原型
var rowObject=new self.row(currentRow,'mouse',self.indentEnabled,self.maxDepth,false);
//提取所有儿童
var childrenRows=rowObject.findChildren();
//如果我们有孩子
如果(儿童)
/**
 * 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;
  }
};