Có thể tự hiển thị Biểu mẫu Tiện ích Trường làm việc không?


21

Tôi quan tâm đến việc nhúng Biểu mẫu tiện ích trường bên ngoài ngữ cảnh của toàn bộ biểu mẫu chỉnh sửa nút.

Tôi đã hiển thị các biểu mẫu đầy đủ trong quá khứ bằng cách sử dụng drupal_get_form nhưng dường như điều đó không áp dụng cho Biểu mẫu trường đơn độc.

Có thể hiển thị Mẫu Widget Trường làm việc không? Điều gì sẽ là cách tốt nhất để làm như vậy?

Cả hai widget trường và các dạng "bình thường" có vẻ rất giống nhau, vì vậy nếu điều này là không thể, thì điều gì sẽ được yêu cầu để "thay đổi" một biểu mẫu widget thành một dạng bình thường?

Câu hỏi này dường như đang hỏi một điều tương tự nhưng tôi không hiểu câu trả lời. Câu trả lời đó chỉ định sử dụng hook_field_widget_form_alter ; Điều tôi không hiểu là làm thế nào để Biểu mẫu trường được hiển thị chứ không phải cách móc nó khi nó được tạo.

Câu trả lời:


18

VBO thực hiện một cái gì đó như thế này trong sửa đổi.action.inc:

$form_key = 'bundle_' . $bundle_name;
$form[$form_key] = array(
  '#type' => 'fieldset',
  '#title' => $label,
  '#parents' => array($form_key),
);  
field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, LANGUAGE_NONE);  

Vì vậy, bạn cần loại thực thể, thực thể (có thể là một đối tượng trống chỉ với bộ khóa gói, đó là những gì thực sự được sử dụng), hình thức nơi các vật dụng được thêm vào và ngôn ngữ. Nếu bạn muốn nhúng các widget sâu hơn vào biểu mẫu (không phải ở dạng $, mà ở $ form [$ form_key] như tôi đã làm, hoặc thậm chí sâu hơn), thì mảng biểu mẫu đó cần phải được đặt #parents.

Tất nhiên, lưu ý rằng điều này sẽ nhúng các widget của tất cả các trường thuộc loại & gói thực thể đó. Đây là cách các chức năng đính kèm đã được viết. Đi xung quanh đó sẽ yêu cầu bạn phải phát minh lại khá nhiều mã; xem mã thực tế mà nâng nặng. Những gì tôi làm là trải qua các trường hợp trường, nhận từng $ field_name và nếu loại trường đó không làm tôi quan tâm, tôi sẽ đặt các mục $form[$form_key][$field_name]['#access'] = FALSE; đó che giấu các vật dụng đó khỏi tầm nhìn.

EDIT: Được rồi, ctools có ctools_field_invoke_field () về lý thuyết có thể cho phép bạn làm việc trên cơ sở từng lĩnh vực. Tôi chưa bao giờ sử dụng nó mặc dù. Các văn bản trên là kinh nghiệm trực tiếp của tôi.


Câu trả lời tuyệt vời. Tôi đã dành phần tốt hơn của một ngày để làm việc với nó, và nó hoạt động như tôi muốn. Bounty được trao, và tôi khuyên OP nên chấp nhận đây là câu trả lời đúng. Cuối cùng tôi đã tạo ra một loại nội dung giả để tôi có thể kiểm soát các trường của mình như bất kỳ loại nội dung nào khác, thay vì cài đặt #access = FALSEcó vẻ khó hiểu trong bối cảnh này.
Letharion

Cảm ơn bạn đã xác nhận những gì tôi đã lo sợ: tiện ích trường đơn không thực sự có thể sử dụng được.
SMTF

7

Tôi đã rất tích cực sử dụng chức năng được đề xuất bởi ttk, nhưng tôi nghĩ rằng một bản cập nhật gần đây đã làm mọi thứ rối tung lên ...

Đây là phiên bản mới của giải pháp trước đó hoạt động tốt với Drupal 7.22 và ctools 7.x-1.3.

Vì vậy, giống như trong bài viết trước, bạn gọi hàm tùy chỉnh của mình như thế này:

my_field_attach_form('field_body', 'node', 'blog',  $node, $form, $form_state, LANGUAGE_NONE);

Lưu ý rằng gói thực thể bây giờ là một tham số. Tôi đã làm điều này bởi vì tôi cũng đang sử dụng chức năng này để chỉnh sửa người dùng. Bằng cách này, nó cũng có thể được sử dụng cho thuật ngữ phân loại, hoặc bất kỳ thực thể nào khác.

my_field_attach_formđược định nghĩa là:

function my_field_attach_form($field_name, $entity_type, $bundle, $entity, &$form, &$form_state, $langcode = NULL) {

  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );

  // Append to the form
  ctools_include('fields');
  $field_instance = field_info_instance($entity_type, $field_name, $bundle);
  $form += (array) ctools_field_invoke_field($field_instance, 'form', $entity_type, $entity, $form, $form_state, $options);
}

Chức năng này giúp tôi tiết kiệm rất nhiều thời gian, hy vọng nó cũng sẽ giúp bạn!


5

Đây là giải pháp sử dụng ctools_field_invoke_field()phương pháp. Trong chức năng biểu mẫu tùy chỉnh của bạn, thêm:

$form = array();
$node = new stdClass();
$node->type = 'blog';
my_field_attach_form('field_body', 'node', $node, $form, $form_state, LANGUAGE_NONE);

trong đó my_field_attach_formhàm được định nghĩa là

function my_field_attach_form($field_name, $entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );
  module_load_include("inc","ctools","includes/fields");
  $form += (array) ctools_field_invoke_field($field_name, 'form', $entity_type, $entity, $form, $form_state, $options);
}

Lưu ý rằng trang web của bạn cần phải bật ctools. Thật tệ khi Drupal không bao gồm chức năng trợ giúp như thế này theo mặc định.


2

Tôi đã không thể làm cho phương thức ctools hoạt động và quyết định làm theo cách này thay thế.

Mã này sẽ nằm trong hàm biểu mẫu, vì vậy $ form và $ form_state sẽ được truyền vào.

function form_function($form, &$form_state) {

Trước tiên, tạo một nút trống của loại có trường mà bạn đang muốn hiển thị.

    $entity = new stdClass();
    $entity->title = "Temp Object";
    $entity->type = "node_type";
    node_object_prepare($entity);

Tôi đã nhân đôi các biến của biểu mẫu để tôi không ghi đè lên bản gốc.

    $temp_form       = $form;
    $temp_form_state = $form_state;
    field_attach_form("node", $entity, $temp_form, $temp_form_state);

Kéo ra trường bạn đang tìm và thêm nó vào biểu mẫu.

    $form["field"] = $temp_form["existing_field"];
}

Tôi đã sử dụng phương pháp này để hiển thị tiện ích chọn phân loại, tiện ích hộp kiểm phân loại và tiện ích Chọn phân cấp trên biểu mẫu tùy chỉnh. (Tiện ích tự động phân loại hoàn nguyên hiển thị nhưng sẽ xuất hiện lỗi khi gửi)

Cuối cùng kết xuất và in

drupal_render(drupal_get_form("form_function"))

Đây có vẻ là một cách dễ dàng để sử dụng tiện ích trường trong một biểu mẫu tùy chỉnh. Nó phụ thuộc vào một Bundle hiện có mặc dù. Trong trường hợp của tôi, tôi sử dụng Loại Nội dung giả, nơi tôi tạo và định cấu hình các trường nếu cần. Đó là một chút hack nhưng cũng cần thiết cho các phương pháp khác. Chỉ cần lưu ý: ctools_field_invoke_field()Phương pháp được mô tả ở trên cũng hoạt động.
Bernhard Fürst

0

Tôi đã tạo các biểu mẫu từ các trường không thường xuyên bằng cách sử dụng

field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $form, $form_state);

cái này sẽ trả về mẫu widget yêu cầu có thể được sử dụng dưới mọi hình thức như

 $custom_form['form_element_to_display'] = field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $custom_form, $custom_form_state);

Để lấy các giá trị cho 2 tham số trên, hãy sử dụng:

$field = field_info_field($field_name);
$field_instance = field_info_instance('node', $field_name, $node_type);

Đối với các thông số khác, bạn có thể kiểm tra liên kết api tại đây

Điều này trả về mẫu widget mặc định được xác định trên trường loại nội dung.

Hy vọng điều này sẽ giúp được ai đó :)

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.