使用项目列表和ajax的Drupal可扩展树

时间:2016-04-29 19:36:22

标签: ajax drupal drupal-7 drupal-forms

我一直在尝试使用项目列表和Ajax(类似于jsTree)来执行可扩展树。

我知道如何使用Java Script解决这个问题,但想知道是否可以只使用drupals表单,主题和Ajax回调来解决这个问题。

我的问题是我无法让ajax回调工作并加载到子列表中。这是我到目前为止所提出的:

<?php

function ajax_tree_list_menu()
{
    $items = array();    
    $items['ajax_tree_list'] = array(
        'title'           => 'Ajax Tree List',
        'description'     => 'Tree List only using ajax and themes(No js file)',
        'page callback'   => 'drupal_get_form',
        'page arguments'  => array('ajax_tree_list_form'),
        'access callback' => array(TRUE),
        'type'            => MENU_CALLBACK,
    );

    return $items;
}

function ajax_tree_list_theme()
{
    return array('tree_list_items' => array('render element' => 'form'));
}

function ajax_tree_list_form($form, &$form_state)
{
    $Items = array(
        'Item 1' => array('Item 1.1', 'Item 1.2', 'Item 1.3'),
        'Item 2' => array('Item 2.1', 'Item 2.2', 'Item 2.3'),
        'Item 3' => array('Item 3.1', 'Item 3.2', 'Item 3.3'),
        'Item 4' => array('Item 4.1', 'Item 4.2', 'Item 4.3'),
    );

    $form['tree_list'] = array
    (
        '#tree'  => true,
        '#theme' => 'tree_list_items',
    );

    foreach($Items as $key => $value)
    {
        $form['tree_list'][$key]['data'] = array(
            '#type'  => 'value',
            '#value' => $key,
        );

        $form['tree_list'][$key]['button'] = array(
            '#type' => 'button',
            '#name' => $key,
            '#ajax' => array(
                'callback' => 'ajax_update_sub_tree_list_callback',
                'wrapper'  => $key,
                'method'   => 'replace',
                'effect'   => 'fade',
            ),
            '#value' => t('+'),
        );

        $form['tree_list'][$key]['sub'] = array(
            '#theme' => 'item_list',
            '#items' => $value,
        );
    }

    return $form;
}

function theme_tree_list_items($variables)
{
    $form = $variables['form'];

    $items = array();
    foreach (element_children($form) as $key) {
        $div_to_replace = '<div id="' . $form[$key]['data']['#value'] . '">Put sub list here</div>';
        $name = $form[$key]['data']['#value'];

        $items[] = array(
            'data' => drupal_render($form[$key]['button']) . $name .  $div_to_replace
        );
    }

    $output = theme('item_list', array('items' => $items));

    return $output; // . drupal_render_children($form);
}

function ajax_update_sub_tree_list_callback($form, $form_state)
{
    return $form['tree_list'][$form_state['triggering_element']['#name']]['sub'];
}

这是我想要在子列表中加载的内容。 tree list built with only forms and ajax

这就是我想要的样子:

enter image description here

1 个答案:

答案 0 :(得分:0)

我发现为什么它不起作用。

问题是ID属性有空格,这不是HTML中的有效ID属性。

要解决此问题,我刚刚在所有使用标题为ID的地方添加了str_replace(&#39;&#39;&#39; _&#39;,):

$form['tree_list'][$key]['button'] = array(
    '#type' => 'button',
    '#name' => $key,
    '#ajax' => array(
        'callback' => 'ajax_update_sub_tree_list_callback',
        // Have added str_replace() on next line to replace all space with underscore
        'wrapper'  => str_replace(' ', '_', $key),
        'method'   => 'replace',
        'effect'   => 'fade',
    ),
    '#value' => t('+'),
);

更新了theme_tree_list_items(...)

foreach (element_children($form) as $key) 
{
    // Have added str_replace() on next line to replace all space with underscore 
    $div_to_replace = '<div id="' . str_replace(' ', '_', $form[$key]['data']['#value']) . '">Put sub list here</div>';
    $name = $form[$key]['data']['#value'];

    $items[] = array(
        'data' => drupal_render($form[$key]['button']) . $name .  $div_to_replace
    );
}