لدي قائمة منسدلة تعرض الحقول المختلفة بناءً على ما تم اختياره ، وأعلم أنه يمكنني الوصول إلى مستوى الرؤية مع الحالات ولكن عندما أحاول استخدام المطلوب ، يتم عرض الامتداد * ولكنه ليس مطلوبًا في الواقع. ما أعنيه أنه على الرغم من أنه "مطلوب" ، إلا أنني أستطيع الضغط على إرسال وعدم تلقي رسالة خطأ من دروبال. هل أفعل شيئًا خاطئًا أم أن هذا مكسور حاليًا Drupal 7.8؟
$form['Host_info'] = array(
'#type' => 'select',
'#title' => t("Host Connection"),
'#options' => array(
'SSH2' => t('SSH2'),
'Web Service' => t('Web Service'),
),
'#default_value' => t(variable_get('Host_info', 'SSH2')),
'#description' => t("Specify the connection information to the Host"),
'#required' => TRUE,
);
$form['ssh_Host'] = array(
'#type' => 'textfield',
'#title' => t("Host Address"),
'#description' => t("Host address of the SSH2 server"),
'#default_value' => t(variable_get('ssh_Host')),
'#states' => array(
'visible' => array(
':input[name=Host_info]' => array('value' => t('SSH2')),
),
'required' => array(
':input[name=Host_info]' => array('value' => t('SSH2')),
),
),
);
$form['ssh_port'] = array(
'#type' => 'textfield',
'#title' => t("Port"),
'#description' => t("Port number of the SSH2 server"),
'#default_value' => t(variable_get('ssh_port')),
'#states' => array(
'visible' => array(
':input[name=Host_info]' => array('value' => t('SSH2')),
),
'required' => array(
':input[name=Host_info]' => array('value' => t('Web Service')),
),
),
);
ستحتاج إلى التحقق من صحة ذلك بنفسك في وظيفة التحقق من الصحة المخصصة.
كل شيء تمت تهيئته بواسطة #states يحدث 100٪ في المتصفح ، وكل ما يفعله غير مرئي لـ Drupal عند إرسال النموذج (على سبيل المثال ، يتم إرسال جميع حقول النموذج غير المرئية والتحقق منها في نفس الطريقة إذا لم يكن هناك # دولة).
يمكنك استخدام المطلوب مثل هذا:
'#states'=> [
'required' => [
':input[name="abroad_because[somecheckbox]"]' => ['checked' => TRUE],
],
],
تشبه إلى حد كبير إجابة Felix Eve فقط هذا مقتطف للتحقق من صحة عنصر مضمن:
استدعاء استدعاء عنصر التحقق من صحة العنصر المطلوب:
$form['element'] = array(
....
'#element_validate' => array(
0 => 'my_module_states_require_validate',
),
)
ثم تبحث وظيفة التحقق من الصحة عن الحقل المطلوب وتتحقق لمعرفة ما إذا كانت تحتوي على قيمة النموذج الصحيحة التي تكشف عن الحقل المطلوب.
function my_module_states_require_validate($element, $form_state) {
$required_field_key = key($element['#states']['visible']);
$required_field = explode('"', $required_field_key);
if($form_state['values'][$required_field[1]] == $element['#states']['visible'][$required_field_key]['value']) {
if($form_state['values'][$element['#name']] == '') {
form_set_error($element['#name'], $element['#title'].' is required.');
}
}
}
هناك طريقة أخرى لاستخدام وظيفة AFTER_BUILD للنموذج وجعل هذا الحقل اختياريًا. هنا link for drupal 6.
أضف هذا إلى رمز النموذج الخاص بك
$form['#after_build'][] = 'custom_form_after_build';
نفذ بعد البناء ، واختبر حالة الحقل المخصص الخاص بك
function custom_form_after_build($form, &$form_state) {
if(isset($form_state['input']['custom_field'])) {
$form['another_custom_field']['#required'] = FALSE;
$form['another_custom_field']['#needs_validation'] = FALSE;
}
return $form;
}
في حالتي ، كانت #states تضيف عدة * * لذا يجب أن أتجنبها واستخدمت jquery لإخفاء وإظهار الامتداد الذي يحتوي على *
$('.another-custom-field').find('span').hide();
و
$('.another-custom-field').find('span').show();
بناءً على قيمة custom_field الخاصة بي.
هنا دليل مفصل عن نموذج دروبال 7 # دولة .
هذا هو الشيء المهم:
/**
* Form implementation.
*/
function module_form($form, $form_state) {
$form['checkbox_1'] = [
'#title' => t('Checkbox 1'),
'#type' => 'checkbox',
];
// If checkbox is checked then text input
// is required (with a red star in title).
$form['text_input_1'] = [
'#title' => t('Text input 1'),
'#type' => 'textfield',
'#states' => [
'required' => [
'input[name="checkbox_1"]' => [
'checked' => TRUE,
],
],
],
];
$form['actions'] = [
'submit' => [
'#type' => 'submit',
'#value' => t('Submit'),
],
];
return $form;
}
/**
* Form validate callback.
*/
function module_form_validate($form, $form_state) {
// if checkbox is checked and text input is empty then show validation
// fail message.
if (!empty($form_state['values']['checkbox_1']) &&
empty($form_state['values']['text_input_1'])
) {
form_error($form['text_input_1'], t('@name field is required.', [
'@name' => $form['text_input_1']['#title'],
]));
}
}
تمكنت من القيام بذلك بهذه الطريقة في Drupal 8:
'#states' => array(
'required' => array(
array(':input[name="Host_info"]' => array('value' => 'SSH2')),
),
),
لا تضع t ('SSH2'). هذا سيضع ترجمته هناك بدلاً من قيمة الخيار وهو SSH2 غير مترجم.
أظن أن هذا سيعمل من أجل Drupal 7 أيضًا.
لقد واجهت للتو نفس المشكلة لذا أحتاج إلى توفير التحقق المخصص ولكن أردت التحكم في ذلك عبر صفيف #states لذا لم يكن عليّ تحديد نفس القواعد مرتين.
يعمل عن طريق استخراج اسم الحقل من محدد jQuery (يجب أن يكون المحدد بالتنسيق :input[name="field_name"]
أو أنها لن تعمل).
يتم اختبار الرمز أدناه فقط في السيناريو المحدد الذي كنت أستخدمه فيه ، ولكن على الرغم من أنه قد يكون مفيدًا لشخص آخر.
function hook_form_validate($form, &$form_state) {
// check for required field specified in the states array
foreach($form as $key => $field) {
if(is_array($field) && isset($field['#states']['required'])) {
$required = false;
$lang = $field['#language'];
foreach($field['#states']['required'] as $cond_field_sel => $cond_vals) {
// look for name= in the jquery selector - if that isn't there then give up (for now)
preg_match('/name="(.*)"/', $cond_field_sel, $matches);
if(isset($matches[1])) {
// remove language from field name
$cond_field_name = str_replace('[und]', '', $matches[1]);
// get value identifier (e.g. value, tid, target_id)
$value_ident = key($cond_vals);
// loop over the values of the conditional field
foreach($form_state['values'][$cond_field_name][$lang] as $cond_field_val) {
// check for a match
if($cond_vals[$value_ident] == $cond_field_val[$value_ident]) {
// now we know this field is required
$required = true;
break 2;
}
}
}
}
if($required) {
$field_name = $field[$lang]['#field_name'];
$filled_in = false;
foreach($form_state['values'][$field_name][$lang] as $item) {
if(array_pop($item)) {
$filled_in = true;
}
}
if(!$filled_in) {
form_set_error($field_name, t(':field is a required field', array(':field' => $field[$lang]['#title'])));
}
}
}
}
}
لدي حقول نموذج متداخلة ، ومربع اختيار ، لذلك كنت بحاجة إلى العمل قليلاً على إجابة دومينيك وودمان. في حالة مواجهة أي شخص آخر لنفس المشكلة:
function my_module_states_require_validate($element, $form_state) {
$required_field_key = key($element['#states']['visible']);
$required_field = explode('"', $required_field_key);
$keys = explode('[', $required_field[1]);
$keys = str_replace(']', '', $keys);
$tmp = $form_state['values'];
foreach ($keys as $key => $value) {
$tmp = $tmp[$value];
}
if($tmp == $element['#states']['visible'][$required_field_key]['checked']) {
$keys2 = explode('[', $element['#name']);
$keys2 = str_replace(']', '', $keys2);
$tmp2 = $form_state['values'];
foreach ($keys2 as $key => $value) {
$tmp2 = $tmp2[$value];
}
if($tmp2 == '') {
form_set_error($element['#name'], $element['#title']. t(' is required.'));
}
}
}