web-gelistirme-sc.com

Formdaki dinamik seçim listesi (bağımlı açılır liste)

Drupal yedi kullanıyorum. Bir seçim listesindeki seçeneklerin bir formdaki başka bir seçim listesinde seçilen değere bağlı olmasını istiyorum. Eminim bu birçok kez sorulmuştur ama bunu nasıl yapacağım konusunda net bir cevap bulmakta zorlanıyorum.

Form, kullanıcıların bir çalışma geçmişi girmeleri içindir. Filo alan türüne bir düğüm referansı olan bir filo seçmeleri gerekiyor ve bu bir açılır listede. Ancak filo, bir şehir açılır listesine bağlıdır. Kullanıcıların önce bir filo için seçenekleri filtreleyecek bir şehir seçmeleri gerekir. Filo içerik türünde, filoya etiketlenen şehir için bir sınıflandırma oluşturdum.

Bu konuda gitmek için en iyi yolu (en basit?) Ya da yardımcı olacak herhangi bir yararlı kaynaklar için herhangi bir işaretçiler için çok minnettar olacaktır.

29
Ben

Bunu yapmak için Ajax'ı kullanabilirsiniz. Drupal 7 şu anda iyi Ajax desteğine sahip. İlk seçim listenize (şehir) Ajax bilgileri eklemeniz gerekecek, daha sonra ikinci seçim listesi, ilk seçimdeki bilgilere göre doldurulabilir. Ayrıca, ilk seçimdeki bir seçenek seçilene kadar ikinci seçim listesini de gizleyebilirsiniz ve bunu biraz nasıl yapacağınızı açıklayacağım.

$form['city'] = array(
  '#type' => 'select',
  '#title' => t('City'),
  '#options' => $options,
  '#ajax' => array(
    'event' => 'change',
    'wrapper' => 'squadron-wrapper',
    'callback' => 'mymodule_ajax_callback',
    'method' => 'replace',
  ),
);
$form['squadron_wrapper'] = array('#prefix' => '<div class="squadron-wrapper">', '#suffix' => '</div>');
$form['squadron_wrapper']['squadron'] = array(
  '#type' => 'select',
  '#title' => t('Squadron'),
  '#options' => $squadron_options,
);

Bu sadece elemanların temel kurulumu. Şimdi filoda hangi seçeneklerin gideceğini belirlemek için bir yola ihtiyacınız olacak. Öncelikle Ajax geri aramanızı 'şehir' seçim listesinde belirtmeniz gerekir. Çoğu durumda ajax öğesini saran öğeyi, bu durumda $ formunu döndürebilirsiniz.

function mymodule_ajax_callback($form, $form_state) {
  return $form;
}

Şimdi, 'şehir' seçim listesi değiştiğinde, formun filo sarmalayıcı kısmını yeniden oluşturacak. 'Şehir' değeriniz şimdi $ form_state ['değerleri'] şeklinde olacaktır. Bu nedenle, form yeniden oluşturulduğunda, 'şehir'in değerine göre seçim listesine hangi seçeneklerin verileceğini belirlememiz gerekir.

// Get the value of the 'city' field.
$city = isset($form_state['values']['city']) ? $form_state['values']['city'] : 'default';
switch ($city) {
  case 'default':
    // Set default options.
    break;
  case 'losangeles':
    // Set up $squadron_options for los angeles.
    break;
}

// If you want to hide the squadron select list until a city is
// selected then you can do another conditional.
if ($city !== 'default') {
  $form['squadron_wrapper']['squadron'] = array(
    '#type' => 'select',
    '#title' => t('Squadron'),
    '#options' => $squadron_options,
  );
}
27
jordojuice

Yukarıdaki jordojuice'e çok teşekkürler. Onun yardımıyla bir çözüm bulmayı başardım. Ayrıca http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-submission adresindeki örneğe de değindim. Sonunda özel bir modülde çalışan aşağıdaki kodu kullandım. Herhangi bir nedenle $ form_state değerlerinde değerlerimden hiçbirini bulamadım, ancak bunları $ biçiminde bulabildim. Son olarak, test ettiğimde, Drupal açılır menüde yasadışı bir seçim tespit etmişti bir hata mesajı alıyordum. Form.inc satır 1290 yorum yaparak bu yuvarlak var:

form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));

Kullandığım son kod:

<?php

function sappers_squadron_form_work_history_node_form_alter(&$form, &$form_state) {     
        //echo '<pre>';
        //print_r ($form);
        //echo '</pre>';

        $squadron_options = array();

        if(isset($form['field_wkhist_city']['und']['#default_value'][0])) {
            $city = $form['field_wkhist_city']['und']['#default_value'][0];
        }
        else {
            $city = 0;
        }

        $squadron_options = sappers_squadron_squadrons($city);

        $form['field_wkhist_city']['und']['#ajax'] = array(
            'event' => 'change',
            'wrapper' => 'squadron-wrapper',
            'callback' => 'sappers_squadron_ajax_callback',
            'method' => 'replace',
        );

        $form['field_squadron']['und']['#prefix'] = '<div id="squadron-wrapper">';
        $form['field_squadron']['und']['#suffix'] = '</div>';
        $form['field_squadron']['und']['#options'] = $squadron_options;
}


function sappers_squadron_ajax_callback($form, $form_state) {   
    $city = $form['field_wkhist_city']['und']['#value'];

    $form['field_squadron']['und']['#options'] = sappers_squadron_squadrons($city);

    return $form['field_squadron'];
}


function sappers_squadron_squadrons($city) {
    $nodes = array();

    $select = db_query("SELECT node.title AS node_title, node.nid AS nid FROM  {node} node INNER JOIN {taxonomy_index} taxonomy_index ON node.nid = taxonomy_index.nid WHERE (( (node.status = '1') AND (node.type IN  ('squadron')) AND (taxonomy_index.tid = $city) )) ORDER BY node_title ASC");

    $nodes[]="";

    foreach ($select as $node) {
            $nodes[$node->nid] = $node->node_title;
    }

    return $nodes;
}

?>
11
Ben

kod satırını koy, yani
$nodes[''] = '- None -'; Sonra

 $nodes = array();

ur sappers_squadron_squadrons function 'da

form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));

2
Hacker

"Geçersiz bir seçim tespit edildi. Lütfen site yöneticisine başvurun." $nodes[]=""; tarafından 0 değerine sahip boş dizenin field_squadron alanı için geçersiz olmasıdır.

Advance PHP Programlama ve Geliştirme konusuna bakın, ancak DANGEROUS_SKIP_CHECK ve onaylanmış bayrakların D7'de kullanımdan kaldırıldığını unutmayın.

Bu satırı kaldırdıktan sonra hata gitti.

1
Siripong

Referans alanı seçenek sınırı modülünü kullanın

Bu modül, çeşitli türlerdeki referans alanlarının widget'larının mevcut seçeneklerinin geçerli varlıktaki diğer alanların değerleriyle sınırlı olmasını sağlar.

0
Rakesh Nimje