Método mais fácil para campos condicionais em um formulário


20

Qual é a maneira mais fácil de obter alguma mágica javascript para ativar / desativar os campos de formulário com base no valor de outro campo? Parece algo que deve haver um ajudante para algum lugar, mas não consigo encontrá-lo. Estou procurando uma solução que não seja restrita a nós.


Não tenho certeza se esta é realmente uma pergunta Drupal. É um JavaScript e deve ser solicitado no Stack Overflow.
Camsoft 8/03/11

3
Eu estava procurando uma solução Drupal. Eu sou capaz de escrever o Javascript para ele, mas realmente parece que ele deve estar conectado à API do Formulário de alguma forma.
Fuzzy76

Isso é legal. Eu não acho que isso ficou claro na pergunta original. Não conheço nenhum módulo que possa fazer isso.
Camsoft 8/03/11

Respostas:


18

A magia está usando o #ahah / #ajax propriedade com elementos de formulário, de que maneira você pode definir o que deve provocar a modificação eo que deve ser modificado, como resultado, mais ele se integra perfeitamente com jQuery.

Esta é a parte importante do exemplo abaixo:

'#ajax' => array(
    'event' => 'change',
    'callback' => 'myajax_ajax_callback',
    'wrapper' => 'dropdown_second_replace',
),

Aqui está um exemplo que mostra uma página baseada em formulário com duas listas suspensas: a lista de opções na segunda lista suspensa depende da seleção na primeira lista suspensa.

<?php

/**
 * Implementation of hook_menu().
 * Registers a form-based page that you can access at "http://localhost/myajax"
 */
function myajax_menu(){
    return array(
        'myajax' => array(
            'title' => 'A page to test ajax',
            'page callback' => 'drupal_get_form',
            'page arguments' => array('myajax_page'),
            'access arguments' => array('access content'), 
        )
    );
}



/**
 * A form with a dropdown whose options are dependent on a
 * choice made in a previous dropdown.
 *
 * On changing the first dropdown, the options in the second are updated.
 */
function myajax_page($form, &$form_state) {
    // Get the list of options to populate the first dropdown.
    $options_first = myajax_first_dropdown_options();

    // If we have a value for the first dropdown from $form_state['values'] we use
    // this both as the default value for the first dropdown and also as a
    // parameter to pass to the function that retrieves the options for the
    // second dropdown.
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
        '#type' => 'select',
        '#title' => 'First Dropdown',
        '#options' => $options_first,
        '#default_value' => $value_dropdown_first,

        // Bind an ajax callback to the change event (which is the default for the
        // select form type) of the first dropdown. It will replace the second
        // dropdown when rebuilt
        '#ajax' => array(
            // When 'event' occurs, Drupal will perform an ajax request in the
            // background. Usually the default value is sufficient (eg. change for
            // select elements), but valid values include any jQuery event,
            // most notably 'mousedown', 'blur', and 'submit'.
            'event' => 'change',
            'callback' => 'myajax_ajax_callback',
            'wrapper' => 'dropdown_second_replace',
        ),
    );
    $form['dropdown_second'] = array(
        '#type' => 'select',
        '#title' => 'Second Dropdown',
        // The entire enclosing div created here gets replaced when dropdown_first
        // is changed.
        '#prefix' => '<div id="dropdown_second_replace">',
        '#suffix' => '</div>',
        // when the form is rebuilt during ajax processing, the $value_dropdown_first variable
        // will now have the new value and so the options will change
        '#options' => myajax_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
    );
    return $form;
}

/**
 * Selects just the second dropdown to be returned for re-rendering
 *
 * Since the controlling logic for populating the form is in the form builder
 * function, all we do here is select the element and return it to be updated.
 *
 * @return renderable array (the second dropdown)
 */
function myajax_ajax_callback($form, $form_state) {
    return $form['dropdown_second'];
}


/**
 * Helper function to populate the first dropdown. This would normally be
 * pulling data from the database.
 *
 * @return array of options
 */
function myajax_first_dropdown_options() {
    return array(
        'colors' => 'Names of colors',
        'cities' => 'Names of cities',
        'animals' => 'Names of animals',
    );
}


/**
 * Helper function to populate the second dropdown. This would normally be
 * pulling data from the database.
 *
 * @param key. This will determine which set of options is returned.
 *
 * @return array of options
 */
function myajax_second_dropdown_options($key = '') {
    $options = array(
        'colors' => array(
            'red' => 'Red',
            'green' => 'Green',
            'blue' => 'Blue'
        ),
        'cities' => array(
            'paris' => 'Paris, France',
            'tokyo' => 'Tokyo, Japan',
            'newyork' => 'New York, US'
        ),
        'animals' => array(
            'dog' => 'Dog',
            'cat' => 'Cat',
            'bird' => 'Bird'
        ),  
    );
    if (isset($options[$key])) {
        return $options[$key];
    }
    else {
        return array();
    }
}

Essa é a maneira correta de alterar um formulário, dependendo do valor de um de seus campos. Mas para ocultar / mostrar ou ativar / desativar os campos, a propriedade #states no elemento do formulário é mais fácil.
Pierre Buyle

6

O módulo Campos Condicionais não faz exatamente isso?

Ao editar um nó, os campos controlados são mostrados e ocultados dinamicamente com JavaScript.


Para formulários de nó e campos CCK, sim. Mas eu queria algo que pudesse ser usado em outras circunstâncias. Vou esclarecer minha pergunta.
Fuzzy76

3

Existem dois sistemas diferentes que você pode usar:

  • # ahah / # ajax permite enviar o formulário com o AJAX e reconstruí-lo no lado do servidor. Útil quando você realmente deseja adicionar novos elementos de formulário, o exemplo típico no D6 é upload.module. Já explicado acima.
  • O novo no Drupal 7 é o sistema #states, que permite fazer coisas como mostrar / ocultar / ativar / desativar elementos do formulário com base em outros elementos. Consulte http://www.randyfay.com/node/58 para obter mais informações sobre isso.

1

O método mais fácil seria escrever seu próprio JavaScript e usar o jQuery para anexar manipuladores de eventos aos eventos de desfoque e foco. Quando seus retornos de chamada forem acionados, desative / ative os campos com base em sua lógica.


E se ele não é capaz de escrever seu próprio jQuery? Um módulo Drupal não seria fácil do que codificar? - Devido ao esclarecimento da questão, retiro meu comentário.
Decipher

Em primeiro lugar, eu mesmo não conhecia o módulo Condicional Fields. Em segundo lugar, quanto sobrecarga um módulo como esse adicionará ao seu projeto em algumas JS simples do lado do cliente?
Camsoft
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.