【问题标题】:Drupal 7 replacing texfield loses ajax functionalityDrupal 7 替换 texfield 失去了 ajax 功能
【发布时间】:2015-05-07 14:00:21
【问题描述】:

我在 Drupal 7 中的 ajax 函数有一些问题。 当我使用 ajax 命令替换功能来替换表单文本字段时,它会失去其 ajax 功能。

例子:

表单构建:

function ds_check_post_new_data_import($form, &$form_state) {
    $form['txt1'] = array(
        '#type' => 'textfield', 
        '#size' => 2,
        '#value' => "val1", 
        '#name' => "txt1",
        '#ajax' => array(
            'callback' => 'ajax_test_callback2',
        ),
        '#prefix' => '<div id="txt1">',
        '#suffix' => '</div>',
    );
    $form['txt2'] = array(
        '#type' => 'textfield', 
        '#size' => 2,
        '#value' => "val2",  
        '#name' => "txt2",
        '#ajax' => array(
            'callback' => 'ajax_test_callback2',
        ),
        '#prefix' => '<div id="txt2">',
        '#suffix' => '</div>',
    );

    return $form;
}

ajax 回调:

function ajax_test_callback2($form, &$form_state) {

    $form['txt1'] = array(
        '#type' => 'textfield', 
        '#size' => 2,
        '#value' => "ajaxed1", 
        '#name' => "txt1",
        '#ajax' => array(
            'callback' => 'ajax_test_callback2',
        ),
        '#prefix' => '<div id="txt1">',
        '#suffix' => '</div>',
    );
    $form['txt2'] = array(
        '#type' => 'textfield', 
        '#size' => 2,
        '#value' => "ajaxed2",  
        '#name' => "txt2",
        '#ajax' => array(
            'callback' => 'ajax_test_callback2',
        ),
        '#prefix' => '<div id="txt2">',
        '#suffix' => '</div>',
    );

    return array(
        '#type' => 'ajax',
        '#commands' => array(
            ajax_command_replace("#txt1", render($form['txt1'])),
            ajax_command_replace("#txt2", render($form['txt2']))
        )
    );
}

现在,当我更改第一个文本字段中的值时,两者都会被替换,这很好。但是当我再次更改该值时,ajax 功能就消失了。

有人遇到同样的问题吗?

在你问我为什么要这样做之前:

实际上我有一个自定义表格主题,它呈现一些行,并且在每一行上都有三个文本字段(使用自定义主题表格呈现..) 当用户在第一个文本框中更改某些内容时,其他两个必须根据输入的值进行更改。 然后当用户更改第二个文本字段中的值时,其他两个必须更新。

感谢阅读:)

【问题讨论】:

    标签: ajax forms drupal


    【解决方案1】:

    您应该在表单构建函数中进行所有表单构建。包括调用 ajax 回调时的任何更改。

    function ds_check_post_new_data_import($form, &$form_state) {
        $form['wrap'] = array(
            '#markup' => '',
            'prefix' => '<div id="field-wrapper">',
            'suffix' => '</div>',
        );
        $form['wrap']['txt1'] = array(
            '#type' => 'textfield', 
            '#size' => 2,
            '#value' => "val1", 
            '#name' => "txt1",
            '#ajax' => array(
                'callback' => 'ajax_test_callback2',
                'wrapper' => 'field-wrapper',
            ),
        );
        $form['wrap']['txt2'] = array(
            '#type' => 'textfield', 
            '#size' => 2,
            '#value' => "val2",  
            '#name' => "txt2",
            '#ajax' => array(
                'callback' => 'ajax_test_callback2',
                'wrapper' => 'field-wrapper',
            ),
        );
    
        // Here check if it has been called via ajax, check something in
        // $form_state, I forget what.
        // Its something like $form_state['submitted'] or $form_state['input']
        // If true, set values
        if (ajax called) {
            $form['wrap']['txt1']['#value'] = 'ajaxed1';
            $form['wrap']['txt2']['#value'] = 'ajaxed2';
        }
    
        return $form;
    
    }
    
    function ajax_test_callback2($form, &$form_state) {
        // return the element that contains both testfields.
        // no need to create a $command, it defaults to replace.
        return $form['wrap'];
    }
    

    我不知道你为什么从两个文本字段调用相同的回调函数,所以我将举一个例子,它们各自调用自己的函数

    function ds_check_post_new_data_import($form, &$form_state) {
        $form['txt1'] = array(
            '#type' => 'textfield', 
            '#size' => 2,
            '#value' => "val1", 
            '#name' => "txt1",
            '#ajax' => array(
                'callback' => 'ajax_test_callback1',
                'wrapper' => 'txt1',
            ),
            '#prefix' => '<div id="txt1">',
            '#suffix' => '</div>',
        );
        $form['txt2'] = array(
            '#type' => 'textfield', 
            '#size' => 2,
            '#value' => "val2",  
            '#name' => "txt2",
            '#ajax' => array(
                'callback' => 'ajax_test_callback2',
                'wrapper' => 'txt2',
            ),
            '#prefix' => '<div id="txt2">',
            '#suffix' => '</div>',
        );
    
        // Here check if it has been called via ajax, check something in
        // $form_state, I forget what.
        // Its something like $form_state['submitted'] or $form_state['input']
        // If true, set values
        if (ajax called on first field) {
            $form['txt1']['#value'] = 'ajaxed1';
        }
        if (ajax called on second field) {
            $form['txt2']['#value'] = 'ajaxed2';
        }
    
        return $form;
    }
    
    function ajax_test_callback1($form, &$form_state) {
        // no need to create a $command, it defaults to replace.
        return $form['txt1'];
    }
    
    function ajax_test_callback2($form, &$form_state) {
        // no need to create a $command, it defaults to replace.
        return $form['txt2'];
    }
    

    注意:这些都未经测试,但你明白了

    【讨论】:

      【解决方案2】:

      如果您实际上要替换绑定了 JS 事件的元素,则需要在替换后重新绑定事件。 Drupal 集成了一个很棒的行为系统,可以在 AJAX 碰巧替换页面上的元素时专门处理这个问题。如果你有自定义 JS(听起来像你这样做),请确保在替换元素时事件得到反弹。

      【讨论】:

      • 如果他确实有自定义 js,他可能应该使用ajax_command_invoke
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多