Có cách nào để thêm hoặc thay đổi một lớp thành một trình bao bọc biểu mẫu (div) bằng cách sử dụng biểu mẫu api không?
Hay đó chỉ là được thực hiện với chức năng chủ đề?
Nếu vậy chức năng chủ đề nào được sử dụng để thay đổi điều đó?
Có cách nào để thêm hoặc thay đổi một lớp thành một trình bao bọc biểu mẫu (div) bằng cách sử dụng biểu mẫu api không?
Hay đó chỉ là được thực hiện với chức năng chủ đề?
Nếu vậy chức năng chủ đề nào được sử dụng để thay đổi điều đó?
Câu trả lời:
Bạn có thể ghi đè theme_form_element()
bình thường nếu bạn muốn thay đổi chủ đề trên toàn cầu. Nếu bạn quan tâm đến việc sửa đổi chỉ một yếu tố biểu mẫu cụ thể thì tôi biết một vài lựa chọn.
Bạn có thể đăng ký một chức năng chủ đề mới cho loại phần tử biểu mẫu cụ thể mà bạn quan tâm (ví dụ: trường văn bản). Sau đó, bạn tạo chức năng chủ đề này (dựa trên bản gốc, vd. theme_textfield()
) Nhưng theme('form_element', ...)
cuối cùng không gọi (bạn có thể xử lý cả trình bao bọc và phần tử trong một chức năng chủ đề hoặc bạn có thể tạo một chức năng chủ đề trình bao riêng biệt và sử dụng nó). Cuối cùng bạn thêm một#theme
tính cho một thành phần biểu mẫu cụ thể và thành phần đó sẽ có được chủ đề tùy chỉnh của bạn.
Bạn có thể tạo một tệp mẫu form_element.tpl.php
có tên hành vi mặc định theme_form_element()
và sau đó sử dụng hook_preprocess_form_element()
để thêm đề xuất mẫu. Sau đó, bạn tạo mẫu mới phù hợp với đề xuất. Bạn thường nghe mọi người đề cập rằng các mẫu chậm hơn một chút so với các chức năng và đối với một cuộc gọi chủ đề được sử dụng thường xuyên như vậy, tôi có thể tưởng tượng mọi người chùn bước khi sử dụng một mẫu. Tuy nhiên, tôi chưa bao giờ thực hiện bất kỳ phép đo nào cho việc này. Ngoài ra, bạn cần có đủ bối cảnh ở giai đoạn tiền xử lý để có thể đưa ra đề xuất.
Tôi biết đây là một chủ đề siêu cũ, nhưng tôi đã học cách thay đổi các thành phần của biểu mẫu và thêm các lớp. Tôi có xung quanh để làm một mô-đun tùy chỉnh:
function yourtheme_custom_form_alter(&$form, &$form_state, $form_id) {
case'webform_number_whatever':
_yourtheme_form_add_wrapper($form['submitted']['yourfieldhere'], array('form-field-some-style', 'not-label', 'whatever-other-styles-you-want'));
break;
}
function _yourtheme_form_add_wrapper(&$element, $classes = array(), $type = array('form-item', 'form-type-textfield'), $removeTitle = FALSE){
$element['#prefix'] = '<div class="' . implode(" ", $classes) . '"><div class="' . implode(" ", $type) . '">';
$element['#suffix'] = '</div></div>';
}
Để thay đổi "trình bao bọc", bạn cần ghi đè form_element. Về cơ bản, tất cả các thành phần của biểu mẫu được hiển thị với chủ đề theme_form_element($element,$value);
form_element (tệp form.inc)
Vì vậy, để thay đổi cách thức này biểu hiện các thành phần biểu mẫu của bạn, bạn chỉ cần sao chép hàm đó vào thư mục template.php và đổi tên thành: phptemplate_form_element($element,$value)
bây giờ bạn có thể thực hiện bất kỳ thay đổi nào và chúng sẽ được sử dụng thay cho chức năng ban đầu
theme_form_element($element,$value);
từ form.incphptemplate_form_element($element,$value)
Điều quan trọng, theme_form_element sẽ chỉ sửa đổi div trình bao bọc cha mẹ trực tiếp và điều này có thể không phải là mục tiêu dự định cho các hiệu ứng CSS.
[Mặc dù không phải là lập trình, nhưng nếu chỉ đơn giản là muốn áp dụng một lớp cho trình bao bọc trên cùng của trường nút (đó là trình bao bọc, trình bao bọc, trình bao bọc) thì tôi có thể giả sử sử dụng mô-đun "Nhóm trường" bằng cách chọn "Quản lý trường" cho một loại nội dung cụ thể và chọn "Thêm nhóm mới" làm DIV đơn giản. Sau đó, nhãn có thể được loại bỏ và các lớp mong muốn được gán cho trình bao bọc bổ sung (nhưng bây giờ chúng ta có nhiều trình bao bọc hơn nữa) - với lồng không giới hạn]
Làm cho các thuộc tính bao bọc có thể cấu hình!
Tạo chức năng chủ đề yếu tố hình thức của riêng bạn trong chủ đề của bạn ...
sites/all/themes/MY_THEME/theme/form-element.theme.inc
function my_theme_form_element($variables) {
$element = &$variables['element'];
$attributes = isset($element['#my_theme_wrapper_attributes']) ?
$element['#my_theme_wrapper_attributes'] : array();
...
$output = '<div' . drupal_attributes($attributes) . '>' . "\n";
...
}
Sau đó, bạn có thể làm những thứ như thế này ...
function my_module_form_alter(&$form, &$form_state, $form_id) {
$form['account']['mail']['#my_theme_wrapper_attributes']['class'][] = 'form-field--inline';
}
Có những trường hợp mà trong đó không phải #prefix/#suffix
cũng không #attributes => array('class')
cho kết quả mong muốn. Trường hợp cụ thể của tôi là thêm một lớp vào div ajax-Wrapper xung quanh phần tử Managed_file. #prefix/#suffix
tạo một thùng chứa mới và #attributes/'class'
sửa đổi lớp của một phần tử bên trong, không phải lớp ngoài cùng.
Div ngoài cùng bình thường chỉ là
<div id="edit-doc1--XX-ajax-wrapper">
đó là khó khăn để nhắm mục tiêu trong CSS. Tôi có thể nhắm mục tiêu [id^="edit-doc"]
hoặc [id$="-ajax-wrapper"]
nhưng cả hai mục tiêu này không chỉ là các yếu tố tôi muốn.
Giải pháp tôi đưa ra là thêm một #process
phần tử vào biểu mẫu và thao tác thủ công mã của phần tử. Đây là #process
thuộc tính được thêm vào khai báo của mục mẫu:
$form['doc1'] = array(
'#type' => 'managed_file',
'#process' => array('mymodule_managed_file_process'),
);
Và đây là mymodule_managed_file_process()
chức năng:
function mymodule_managed_file_process($element, &$form_state, $form) {
// Call the original function to perform its processing.
$element = file_managed_file_process($element, $form_state, $form);
// Add our own class for theming.
$element['#prefix'] = str_replace(
'id=',
'class="managed-file-wrapper" id=',
$element['#prefix']
);
return $element;
}
Dựa vào thay thế chuỗi không phải là rất dễ mang theo, vì vậy str_replace
hãy tự chịu rủi ro khi sử dụng . Tuy nhiên, mã này thực sự thay đổi DIV ngoài cùng để thêm lớp cần thiết:
<div class="managed-file-wrapper" id="edit-doc1--XX-ajax-wrapper">
<?php
$form['#attributes'] = array('class' => 'your-class-name');
?>
Bạn có thể sử dụng cách trên để thêm một lớp vào phần tử biểu mẫu.