주에 필요한 양식을 작성하는 방법은 무엇입니까?


31

선택한 항목을 기반으로 다양한 필드를 표시하는 드롭 다운 목록이 있으며 상태와의 가시성을 너무 많이 볼 수 있지만 필수 * 범위를 사용하려고 할 때 실제로는 필요하지 않습니다. 내 말은 그것이 "필수"임에도 불구하고 제출을 누르고 drupal에서 오류 메시지를받지 못한다는 것입니다. 내가 잘못하고 있거나 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')),
            ),
        ),
    );

에 대한 큰 따옴표가 없습니다 name. 이어야합니다 :input[name="host_info"].
leymannx

답변:


20

사용자 지정 유효성 검사 기능에서이를 직접 확인해야합니다.

#states로 구성된 모든 것은 브라우저에서 100 % 발생하며, 양식이 제출 될 때 Drupal에 표시되지 않는 모든 것은 표시되지 않습니다 (예 : #states가없는 경우 모든 보이지 않는 양식 필드가 동일한 방식으로 제출되고 유효성 검사 됨).


나는 그것이 사실이라고 생각했다. 이 작업을 수행하는 방법을 조사 할 때 상태가 '필수'인 속성을 발견하고 추가 작업없이 필요한 방식으로 작동한다고 생각했습니다.
Sathariel

11

다음과 같이 필수를 사용할 수 있습니다.

'#states'=> [
  'required' => [
    ':input[name="abroad_because[somecheckbox]"]' => ['checked' => TRUE],
  ],
],

4
예-요소에 필요한 표시기를 추가합니다. 그러나 클라이언트 또는 서버 측 유효성 검사는 포함되지 않습니다.
AyeshK

버그 일 수 있습니까? #states에 버그가있는 필수 요소
colan

전자 메일 필드 유효성 검사가 있었음에도 불구하고 require 키를 #states 배열에 넣으면 효과가있는 것 같습니다. 따라서 양식 항목에 기본 drupal #element_validate를 사용하는지 궁금합니다.
Alex Finnarn

8

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.');
    }
  }
}

1
이것은 최고의 솔루션 IMHO입니다!
Alex Finnarn

3

양식에 AFTER_BUILD 함수를 사용하고 해당 필드를 선택적으로 만드는 다른 방법이 있습니다. 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 값을 기반으로합니다.


3

다음은 Drupal 7 form #states 에 대한 자세한 가이드입니다 .

이것은 중요한 부분입니다.

/**
 * 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'],
    ]));
  }
}

2

방금 동일한 문제에 직면하여 사용자 정의 유효성 검사를 제공해야하지만 #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'])));
                }
            }

        }
    }

}

2

Drupal 8에서 이런 식으로 할 수있었습니다.

          '#states' => array(
            'required' => array(
              array(':input[name="host_info"]' => array('value' => 'SSH2')),
             ),
           ),

t ( 'SSH2')를 넣지 마십시오. 이것은 번역되지 않은 SSH2 옵션의 값 대신 번역을 거기에 넣습니다.

나는 이것이 Drupal 7에서도 효과가 있다고 생각합니다.


1
drupal 7에서는 비슷한 솔루션을 제공하는 답변에서 지적한 것처럼 필수 필드 표시를 제공하지만 실제로는 유효성 검사를 수행하지 않습니다. drupal 8은 실제로 #states를 사용하여 필요한 것으로 표시된 필드의 유효성을 검사합니까?
UltraBob

0

양식 필드와 확인란이 중첩되어 있으므로 Dominic Woodman의 답변을 약간 연구해야했습니다. 다른 신체가 같은 문제를 겪을 경우 :

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.'));
    }
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.