Devletlerle gerekli bir form nasıl yapılır?


31

Neyin seçildiğine bağlı olarak çeşitli alanları gösteren bir açılır liste var ve devletlerle görünürlüğü artırabileceğimi biliyorum, ancak kullanmaya çalıştığımda * span gösteriliyor ama aslında gerekli değil. Demek istediğim, "zorunlu" olsa bile, drupal'dan bir hata mesajı alamıyor ve gönderim yapabilirim. Yanlış bir şey mi yapıyorum veya şu anda Drupal 7.8'de bu durum bozuk mu?

        $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')),
            ),
        ),
    );

İçin çift tırnak işareti eksik name. Olmalı :input[name="host_info"].
leymannx

Yanıtlar:


20

Bunu özel bir doğrulama fonksiyonunda kendiniz doğrulamanız gerekecektir.

#States tarafından yapılandırılan her şey tarayıcıda% 100 olur, form gönderildiğinde Drupal için görünmeyen her şey (örneğin, görünmez tüm form alanları #stat olmasaydı aynı şekilde gönderilir ve doğrulanır).


Durumun bu olduğunu düşündüm. Bunun nasıl yapıldığını araştırırken, devletlerin 'zorunlu' özelliğini keşfettim ve fazla çalışmadan ihtiyacım olan şekilde çalışacağını düşündüm.
Sathariel

11

Bunun gibi gerekli kullanabilirsiniz:

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

4
Evet - bu gerekli göstergeyi elemana ekleyecektir. Ancak ilgili müşteri veya sunucu tarafı doğrulaması yapılmayacaktır.
AyeshK


Gereklilik anahtarını #states dizisine koymak benim için çalışıyor gibiydi, ancak bir e-posta alan doğrulamasına sahip olmama rağmen. Yani, işe yarayacak form öğesinde varsayılan drupal #element_validate işlevini kullanıyor musunuz?
Alex Finnarn

8

Felix Eve'in cevabına çok benzer, ancak bu, satır içi öğe doğrulaması için bir pasajdır:

Bir element validate fonksiyonuna gerekli elemanı çağırırsınız:

$form['element'] = array(
....
  '#element_validate' => array(
     0 => 'my_module_states_require_validate',
   ),
)

Ardından doğrulama işlevi gerekli alanı bulur ve gerekli olan alanı ortaya çıkaracak doğru form değerine sahip olup olmadığını kontrol eder.

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
Bu en iyi çözüm IMHO!
Alex Finnarn

3

AFTER_BUILD işlevini form olarak kullanmanın ve bu alanı isteğe bağlı hale getirmenin başka bir yolu var. İşte drupal 6 için bir link .

Bunu form koduna ekle

$form['#after_build'][] = 'custom_form_after_build';

Oluşturulduktan sonra uygulayın, özel alan koşulunuzu test edin

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;
}

Benim durumumda #states birden fazla * ekliyordu, bu yüzden kaçınmalıyım ve içeren aralığı gizlemek ve göstermek için jquery kullandım *

$('.another-custom-field').find('span').hide();  

Ve

$('.another-custom-field').find('span').show();

Custom_field değerime göre.


3

İşte Drupal 7 form #states hakkında ayrıntılı bir rehber .

Bu önemli bir parça:

/**
 * 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

Ben sadece aynı sorunla karşı karşıya kaldım, bu yüzden özel doğrulama sağlamak için gerekli ancak bunun #states dizisi üzerinden kontrol edilmesini istedim, böylece aynı kuralları iki kez belirtmek zorunda kalmamıştım.

Alan adını jQuery seçicisinden ayıklayarak çalışır (seçici biçiminde olmalıdır :input[name="field_name"], yoksa çalışmaz).

Aşağıdaki kod yalnızca, kullandığım belirli senaryoda test edilmiştir, ancak başkalarına yararlı olabileceğini düşünmeme rağmen.

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'de bu şekilde yapabildim:

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

T ('SSH2') koyma. bu, çevrilmemiş bir SSH2 olan seçeneğin değeri yerine çevirisini oraya koyacaktır.

Bunun Drupal 7 için de işe yarayacağından şüpheleniyorum.


1
Drupal 7'de, benzer çözümler veren cevaplara işaret edildiği gibi, bu gerekli alan işaretlerini sağlar, ancak aslında herhangi bir doğrulama yapmaz. Drupal 8, #states'de gerekli kullanım olarak işaretlenmiş alanları doğrular mı?
UltraBob

0

İç içe form alanları ve bir onay kutusu aldım, bu yüzden Dominic Woodman'ın cevabı üzerinde biraz çalışmam gerekiyordu. Herhangi bir bedenin aynı problemle karşılaşması durumunda:

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.'));
    }
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.