Tự động điền các trường dựa trên một lĩnh vực khác


10

Tôi có một tình huống rất phức tạp khi tôi cần một lời khuyên. Tôi có một loại nội dung my_content, có trường bộ sưu tập trường được đính kèm field_mycollection, có trường tham chiếu thực thể tham chiếu đến người dùng field_my_userreference, trường điện thoại field_my_phone, trường văn bản field_my_textvà trường văn bản khác field_my_anothertext.

My Content
|_ field_mycollection
   |_ field_my_userreference
   |_ field_my_phone
   |_ field_my_text
   |_ field_my_anothertext

Các đơn vị sử dụng cũng đã có các trường field_my_phone, field_my_textfield_my_yetanothertextđó sau này có một tên máy khác nhau.

Những gì tôi muốn làm, nếu ở dạng my_contentchỉnh sửa / thêm, trong field_my_userreferencemột người dùng được chọn, các trường khác sẽ được tự động điền từ dữ liệu của người dùng đã chọn. Các trường tự động điền vẫn có thể chỉnh sửa.

Làm thế nào tôi có thể đạt được mục tiêu này? Tôi muốn làm điều đó, nếu có thể, với một số mã hóa, sử dụng hook_form_FORM_ID_alter().


Bạn có cần nó để xảy ra trực tiếp trên hình thức, hoặc tiết kiệm?
Mołot

Sống theo hình thức. Tôi đã thực hiện rằng khi lưu, dữ liệu sẽ được lấy từ thực thể người dùng nếu để trống. Nhưng thực ra những gì tôi cần nó trên mẫu :(
ЕЕнн.

OK, đặt ra câu trả lời của tôi.
Mołot

Câu trả lời:


11

Nếu bạn muốn nó diễn ra trực tiếp và tất cả các trường đều có trong biểu mẫu, cách an toàn nhất là sử dụng hook_form_FORM_ID_alter()để thêm sau vào biểu mẫu:

$form['#attached']['js'] = array(
  drupal_get_path('module', 'module_name') . '/js/copy_field_value.js',
);

Sau đó, trong copy_field_value.jshành vi tạo:

(function($) {
  Drupal.behaviors.moduleNameCopyFieldValue = {
    attach: function (context, settings) {

      // Repeat this for all fields as needed
      $('#source', context).on('blur', function () { 
        // above you can use change instead of blur if element is not changed by another js
        if (!$('#destination').val() || 0 === $('#destination').val().length) {
          $('#destination').val($(this).val());
          // wrap line above in "if no value" like I did, or other condition you like
        }
      });
      // end of "repeat this"
    }
  };
})(jQuery);

Bạn cũng có thể sử dụng hook_form_FORM_ID_alter()để thêm #ajaxtham số vào trường nguồn, nhưng nó sẽ làm cho biểu mẫu của bạn gọi một máy chủ trên mỗi bản sao của trường. Nếu bạn cần thực sự truy vấn cơ sở dữ liệu, đó là cách để đi. Nó sẽ là khá rộng để mô tả nó một lần nữa ở đây. Bạn cần thay đổi $form_state["input"]mảng để cập nhật giá trị thực mà người dùng nhìn thấy. Làm điều đó trong chức năng tạo biểu mẫu, gói nó issetđể tránh thông báo.

Nếu phần tử biểu mẫu của bạn là $form["something"]["something"]["element"], giá trị của nó sẽ nằm trong $form_state["input"]["something"]["something"]["element"]- và bạn có thể đặt nó hoàn hook_form_altertoàn đúng, chỉ cần nhớ lấy cả hai $form$form_statebằng cách tham chiếu.

Lưu ý : .on()phương thức đã được thêm vào jQuery 1.7, vì vậy bạn sẽ cần jQuery Update để sử dụng trực tiếp câu trả lời này hoặc dịch mã của tôi để sử dụng .change()hoặc .blur()phương thức.


Rất cám ơn đã hướng dẫn! Tôi không hiểu rõ về API API của Drupal. Bạn có thể giải thích làm thế nào tôi có được các giá trị trường từ thực thể người dùng? Ví dụ: nếu người dùng được chọn, làm cách nào tôi có thể điền vào các trường tiếp theo với thông tin của người dùng này?
ЕЕннн

1
@ ЕЕнн Mẹo ở đây là không quan tâm đến nền php. Chỉ cần xác định tham số ID của <input>thẻ bằng Firebird hoặc công cụ tương tự cho trình duyệt yêu thích của bạn. Hoặc sử dụng bất kỳ bộ chọn jQuery nào khác. Nó sẽ chỉ xảy ra trong trình duyệt, vì vậy bạn có những gì bạn có trên màn hình. Mặt khác, nếu bạn cần thực sự truy vấn cơ sở dữ liệu (dường như tôi đã bỏ lỡ điều đó), #ajaxlà cách để đi. Nhưng nó sẽ khá rộng. Bạn cần thay đổi $form_state["values"]mảng để cập nhật giá trị thực mà người dùng nhìn thấy. Làm điều đó trong chức năng tạo biểu mẫu, gói nó issetđể tránh thông báo.
Mołot

Cảm ơn một lần nữa @ Mołot, tôi sẽ cố gắng thực hiện nó vào ngày mai, hoặc có thể tối nay. Có vẻ như tôi sẽ cần một vài giờ để nó thực sự hoạt động, nếu không muốn nói là nhiều hơn.
ЕЕннн

@ ЕЕнн chúc may mắn, vui lòng quay lại với nhiều câu hỏi hơn và liên kết chúng ở đây trong các bình luận nếu chúng được kết nối. Cập nhật câu trả lời một chút, btw.
Mołot

1
Ok, tôi sẽ thử nghiệm nó một chút và tôi sẽ viết những trải nghiệm của mình.
ЕЕннн

4

Bạn có thể làm điều đó bằng cách sử dụng mô đun trường được tính toán

Trường được tính toán là một mô-đun trường CCK rất mạnh cho phép bạn thêm một "trường được tính toán" tùy chỉnh vào các loại nội dung của mình. Các trường được tính toán này được điền với các giá trị mà bạn xác định thông qua mã PHP. Bạn có thể rút ra bất cứ điều gì có sẵn cho Drupal, bao gồm các trường khác, người dùng hiện tại, bảng cơ sở dữ liệu, bạn đặt tên cho nó. (Cảm thấy sức mạnh chưa? :)) Bạn cũng có thể chọn lưu trữ các giá trị trường được tính toán của mình trong cơ sở dữ liệu với các trường nội dung khác hoặc để chúng được "tính toán" khi đang di chuyển trong chế độ xem nút. (Mặc dù bạn cần lưu ý rằng việc sử dụng Lượt xem yêu cầu các giá trị được lưu trữ cơ sở dữ liệu.) Trường này theo nghĩa đen là con dao của quân đội Thụy Sĩ của các trường CCK. Vì vậy, bắt đầu nấu các giá trị dựa trên PHP của bạn!


Cảm ơn đã phản ứng nhanh chóng. Nghe có vẻ rất hứa hẹn. Mặc dù, tôi không muốn cài đặt một mô-đun cho điều đó mà chỉ cần viết một số mã, vì tôi chỉ cần một chức năng như vậy trên biểu mẫu đó và hệ thống thực tế đã quá lớn và nhiều mô-đun được cài đặt cho các chức năng đa dạng.
ЕЕннн

Thứ hai, có thể sử dụng mô-đun này, cho người dùng đang tạo hoặc chỉnh sửa nút để ghi đè các trường tự động điền bằng tay và lưu không? Vì vậy, trong thực thể người dùng và my_content là các giá trị khác nhau được lưu.
ЕЕннн

Điều đó phụ thuộc vào cách thiết lập
4 life

Cảm ơn @ 4life, tôi cũng sẽ thử nếu tôi không thể đạt được điều đó bằng mã hóa, sử dụng các hướng dẫn của Mołot.
ЕЕннн

2

Tôi muốn đăng bài làm thế nào tôi đạt được nó nhờ sự giúp đỡ tuyệt vời của @ Mołot.

  1. Đã triển khai hook_form_FORM_ID_alter () .
  2. Đã thêm một div gói xung quanh bộ sưu tập trường.
  3. Vì bộ sưu tập trường của tôi là trường đa giá trị, lặp đi lặp lại và đặt thuộc #ajaxtính cho trường field_my_userreference.
  4. Đã tạo một hàm gọi lại mà chỉ cần trả về mục bộ sưu tập trường trở lại.
  5. Đã kiểm tra trong triển khai hook_form_FORM_ID_alter (), nếu $ form_state cho bộ sưu tập trường được đặt. Nếu có, hãy lấy các giá trị từ thực thể người dùng và điền vào các trường nhập mẫu với các giá trị đó.

Mã của tôi trông như:

function MYMODULE_form_my_content_node_form_alter(&$form, &$form_state, $form_id) {
  $form['field_mycollection']['#prefix'] = '<div id="mycollection-wrapper">';
  $form['field_mycollection']['#suffix'] = '</div>';
  foreach ($form['field_mycollection']['und'] as $key => $fc_mycollection) {
    if (is_numeric($key)) {
      $form['field_mycollection']['und'][$key]['field_my_userreference']['und']['#ajax'] = array(
        'callback' => 'MYMODULE_mycollection_callback',
        'wrapper' => 'mycollection-wrapper',
      );
      if (isset($form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id'])) {
        $user_wrapper = entity_metadata_wrapper('user', $form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id']);
        $form_state['input']['field_mycollection']['und'][$key]['field_my_text']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_text->value() : '';
        $form_state['input']['field_mycollection']['und'][$key]['field_my_anothertext']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_yetanothertext->value() : '';
      }
    }
  }
}

function MYMODULE_mycollection_callback($form, &$form_state) {
  return $form['field_mycollection'];
}

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.