Cuộc gọi AJAX trong Trình cắm loại nội dung CTools?


10

Tôi đang xây dựng Loại nội dung Bảng điều khiển CTools (nghĩa là thứ bạn chèn vào bảng khi thêm nội dung, không phải loại nút) và tôi đang cố gắng sử dụng #ajaxthuộc tính của mục biểu mẫu để đặt một số giá trị mặc định. Xem mã dưới đây.

Nhân tiện, đây là tất cả bên trong my_module_content_type_edit_form($form, &$form_state)cuộc gọi của loại nội dung .

  $form['link_type'] = array(
    '#type' => 'radios',
    '#title' => t('Link Type'),
    '#ajax' => array(
      'callback' => 'my_module_set_target'
    ),
    '#default_value' => empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' => array('none'=>t('No Link'), 'internal'=>t('Internal Link'), 'external'=>t('External Link'), 'document'=>t('Document Link')),
  );

Cuộc gọi lại của tôi là như sau.

function my_module_set_target($form, $form_state) {
  watchdog("Test", "Testing callback", array(), WATCHDOG_ALERT);
  $form['link_target']['#default_value'] = '_parent';

  return $form['link_target']['#default_value'];
}

Bất kể lợi nhuận mà tôi đề xuất có thực sự hoạt động hay watchdog()không , thậm chí không hoạt động.

Tôi biết CTools thực hiện một số điều kỳ lạ với AJAX, nhưng nó không thể kỳ lạ như vậy. Bạn có biết tôi sẽ làm những gì tôi muốn làm không?

Cảm ơn!

Ngoài ra: Làm cách nào để đặt giá trị mặc định dựa trên giá trị của tùy chọn biểu mẫu trước đó?

Tôi đã tìm ra cách để làm điều này, nhưng nó hơi rắc rối - bạn tạo các trường biểu mẫu mới cho mỗi ngã ba phụ thuộc. Sau đó, bạn có thể hợp nhất các giá trị lại với nhau hook_content_type_edit_form_submit(), sử dụng giá trị nào tương ứng với giá trị được chọn cho thành phần ban đầu rẽ nhánh mọi thứ.

Tôi bỏ ngỏ câu hỏi vì tôi (và, thành thật mà nói, mọi lập trình viên tôi đang làm việc) thực sự muốn có một cách tốt để sử dụng AJAX trong các biểu mẫu chỉnh sửa loại nội dung Bảng điều khiển này.

Cập nhật: Dường như bạn cũng không thể thực hiện công cụ với #attached.

$form['link'][$i] = array(
  '#type' => 'fieldset',
  '#title' => t('Link #@num', array('@num' => $i)),
  '#collapsible' => TRUE,
  '#collapsed' => TRUE,
  '#attached' => array(
    'js' => array(
      'alert("Yay.");', 'inline'
    ),
  )
);

Là một nhà phát triển Drupal kiểu "Tấm cho mọi thứ", tôi tưởng tượng rằng tôi cũng có thể tìm thấy sử dụng cho việc này trong tương lai, vì vậy tôi đã thêm một tiền thưởng, để xem điều gì sẽ xảy ra.
Letharion

Wow, tiền thưởng đó đã đến và đi mà không có một bình luận nào (Cảm ơn BTW, Letharion). Là những gì tôi yêu cầu không thể hoặc một cái gì đó?
gửi

Đáng lưu ý rằng tôi đã có thể thêm thành công Javascript bằng cách sử dụng ctools_add_js();hoặc drupal_add_js();vào cuối hook_content_type_edit_form();. Nếu bạn chỉ đang làm những việc đơn giản liên quan đến giao diện người dùng, có vẻ như đó có thể là cuộc gọi tốt nhất (Ít nhất là cho đến khi ai đó trả lời đúng câu hỏi này).
aendrew

Câu trả lời:


8

Câu trả lời ngắn: bạn nên sử dụng #ajax ['path'].

Câu trả lời dài:

Có một cuộc gọi lại ajax không giúp ích gì vì ctools tạo ra nó hình thành khác nhau afaik. Cuộc gọi lại được thực hiện bởi system / ajax không thể tìm thấy định nghĩa biểu mẫu hoàn chỉnh do đó không thể tìm thấy một phần tử để xử lý yêu cầu ajax cho. Sử dụng #ajax [path] chỉ kích hoạt một mục menu.

Bạn có thể tự kiểm tra bằng cách hủy biểu mẫu khi sử dụng #ajax [gọi lại]

function ajax_form_callback() {
  list($form, $form_state) = ajax_get_form();
  drupal_process_form($form['#form_id'], $form, $form_state);

Tôi đã sửa đổi Simplecontext_content_type_edit_form bằng cách thêm tiện ích tự động hoàn thành của người dùng và trường của bạn, cả hai đều hoạt động :)

function simplecontext_content_type_edit_form($form, &$form_state) {
  $conf = $form_state['conf'];

  $form['owner_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Username'),
    '#default_value' => 'admin',
    '#autocomplete_path' => 'user/autocomplete',
    '#size' => '6',
    '#maxlength' => '60',
    '#description' => '$description',
  );

  $form['link_type'] = array(
    '#type' => 'radios',
    '#title' => t('Link Type'),
    '#ajax' => array(
      'path' => 'my_module_set_target'
    ),
    '#default_value' => empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' => array('none' => t('No Link'), 'internal' => t('Internal Link'), 'external' => t('External Link'), 'document' => t('Document Link')),
  );
...

Như bây giờ bạn sử dụng đường dẫn #ajax, bạn cần thêm một mục menu như tôi đã thích

<?php

function my_module_menu() {
  $items = array(
    'my_module_set_target' => array(
      'title' => 'AJAX Example',
      'page callback' => 'my_module_set_target',
      'access callback' => TRUE,
      'expanded' => TRUE,
    )
  );
  return $items;
}

function my_module_set_target() {
  drupal_json_output( array('data' => "ABC"));
}

Một số ít về #attached [js]: js nội tuyến phải là khóa => giá trị như:

'#attached' => array(
  'js' => array(
    'alert("Yay.");' => 'inline',
  ),
),

Tôi đã sử dụng Fireorms để kiểm tra giá trị kết quả chứ không phải hiệu ứng kết quả. Vì vậy, tôi hy vọng điều này sẽ giúp khắc phục vấn đề của bạn.


Ồ Tôi rất phấn khích khi cuối cùng cũng có câu trả lời cho câu hỏi này. Sẽ thử nó trong một chút. Cũng cảm ơn về ghi chú trên bit #attached, đó thực sự là những gì tôi đã có ban đầu (Nhưng đã thay đổi nó vì tôi cho rằng điều đó không thể đúng).
aendrew

Vậy, thành công nào? Sẽ rất thú vị khi biết trước khi tiền thưởng kết thúc :)
Letharion

Tôi hy vọng tôi nhận được tiền thưởng của mình: p
Clemens Tolboom

Xin lỗi vì sự chậm trễ này, có một chút thời gian để nó hoạt động - khi tôi cố gắng trả về mảng $ form, nó cho tôi biết hàm xác thực của tôi không được xác định. Đó là và khi tôi cố gắng khai báo lại nó trong mô-đun của mình (trái ngược với tệp plugin loại nội dung), nó cho tôi biết tôi đang khai báo lại. Tôi đoán đó không phải là điều tôi cần làm, nhưng tôi không thể tìm ra cách cấu trúc drupal_jsonDefput để nó tạo ra thứ gì đó mà biểu mẫu của tôi sẽ diễn giải như một phản hồi có ý nghĩa. Có ai giúp đỡ không? Một ví dụ gọi lại tốt hơn sẽ giúp rất nhiều. Cảm ơn!

Tôi đã bỏ lỡ một phần nhỏ trong câu hỏi của bạn về giá trị trả về : return $ form ['link_target'] ['# default_value']; đó là việc bạn cố gắng trả lại một hình thức drupal cho bối cảnh html / javascript . Rằng sẽ không làm việc. Bạn đã thấy điều tương tự những gì bạn muốn trong giao diện người dùng chưa? (Bản thân tôi vô hiệu hóa JavaScript bây giờ và sau đó với quan điểm giao diện người dùng chỉ để xem js không workflow) (thay đổi nội dung nhận xét này một zillion lần ... vụng về)
Clemens Tolboom

2

Tôi đã gặp một vấn đề tương tự, trong đó tôi muốn đưa loại phần tử Media vào plugin loại nội dung CTools, cũng sử dụng ajax để chọn hình ảnh.

Nó sử dụng cài đặt 'đường dẫn' của ajax, thay vì cài đặt 'gọi lại', nhưng khi chọn một hình ảnh, biểu mẫu được xây dựng lại mà không có yếu tố truyền thông hoàn toàn.

Tôi bắt nguồn từ thực tế rằng drupal numbuild_form không thể tìm thấy chức năng trình bao bọc biểu mẫu CTools, cũng không phải chức năng biểu mẫu cài đặt thực tế. Vì vậy, tôi đã sửa nó bằng cách thêm các dòng mã này vào biểu mẫu cài đặt ctools:

function custom_module_my_content_plugin_content_type_edit_form($form, &$form_state) {

$background_image = isset($conf['background_image']) ? $conf['background_image'] : array();
  $form['background_image'] = array(
    '#title' => t('Background image'),
    '#default_value' => $background_image,
    '#type' => 'media',
    '#input' => TRUE,
    '#extended' => TRUE,
    '#tree' => TRUE,
    '#media_options' => array(),
  );

  // The two function calls below are necessary if we want to use a media
  // element type, because it causes ajax requests, which in turn call
  // drupal_form_rebuild(), and without the below includes, Drupal will
  // not be able to rebuild the form.

  // Include the CTools content type plugin file, because it provides
  // the ctools_content_configure_form_defaults() function, which is needed
  // when rebuilding the form, because of an ajax action, like selecting
  // a media element.
  ctools_form_include($form_state, 'content');

  // Include this plugin file as well, so that when the form is rebuilt, it
  // can successfully retrieve the settings form.
  ctools_form_include($form_state, 'my_content_plugin', 'custom_module', 'plugins/content_types/my_content_plugin');

}

Có thể tôi đang thiếu một cái gì đó rõ ràng tại sao các tệp bao gồm không được tải, nhưng bao gồm chúng đã tự khắc phục sự cố cho tôi.


0

Về phía tôi, tôi đã phải viết một hàm bao bọc biểu mẫu trong tệp .module và để bao gồm ngăn thủ công (nơi xác định nội dung biểu mẫu gốc) như thế:

function mymodule_form($form, &$form_state) {
  // include mymodule/panes/mypane.inc
  ctools_include('mypane', 'mymodule', 'panes');
  return mymodule_form_content($form, $form_state);
}

Bây giờ, trong cuộc gọi ajax, Drupal có thể truy xuất biểu mẫu của tôi để tôi có thể sử dụng API biểu mẫu AJAX tiêu chuẩn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.