Formdaki dinamik seçim listesi (bağımlı açılan menü)


28

Drupal Yedi kullanıyorum. Seçim listesindeki seçeneklerin, başka bir seçim listesinde formda seçilen değere bağlı olmasını istiyorum. Bundan daha önce defalarca sorulmuştu eminim ama bunun nasıl yapılacağına dair net bir cevap bulmakta zorluk çekiyorum.

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 gerekir ve bu, aşağı açılır bir listededir. Bununla birlikte, filo, bir şehir açılır listesine bağlıdır. Kullanıcıların önce bir şehir seçmesi gerekir, ardından filo için seçenekleri filtreler. Filo içerik türünde, filo ile etiketlenen şehir için bir taksonomi oluşturdum.

Herhangi bir işaretçi için bu konuda en iyi yolu (en basit?) Veya çevrimiçi yardımcı olacak herhangi bir yararlı kaynak için minnettar olurum.

Yanıtlar:


27

Bunu başarmak için Ajax kullanabilirsiniz. Drupal 7 şimdi iyi Ajax desteğine sahip. İlk seçim listenize (şehir) Ajax bilgileri eklemeniz gerekecek. Ardından, ikinci seçim listesi, birinci kısımdaki bilgilere göre doldurulabilir. İlk seçimde bir seçenek seçilinceye kadar ikinci seçim listesini de gizleyebilirsiniz ve bunun nasıl yapılacağını biraz açıklayacağım. İlk olarak, temel formu ayarlamak için:

$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 elementlerin temel kurulumudur. Şimdi hangi seçeneklerin filoda olması gerektiğini belirlemek için bir yola ihtiyacınız olacak. Öncelikle, 'şehir' seçim listesinde Ajax geri çağrınızı tanımlamanız gerekir. Çoğu durumda, ajax öğesini saran öğeyi sadece bu durumda $ formuna geri 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şturacaktır. 'Şehir' değeriniz şimdi $ form_state ['değerler'] cinsinden olacaktır. Öyleyse, form yeniden oluşturulduğunda, 'şehir' değerini temel alarak seçim listesine hangi seçenekleri vereceğimizi 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,
  );
}

6
Örnekler Örnekler modülünde bulunabilir ("AJAX Örnekleri" → "Bağımlı açılır menü"). Ayrıca Hiyerarşik Seçim modülünde de görebilirsiniz .
kalabro

Bu arada, alternatif olarak bunu çok adımlı bir şekilde yapabilirsiniz, ancak aradığın gibi göründüğünü düşünmedim. Ayrıca ^ iyi çağrı! Örnek modüller bu tür şeyleri öğrenmek için mükemmeldir .
jordojuice

@ jordojuice Cevabınız için çok teşekkür ederim. Şimdi çalışıyorum. Yukarıda verdiğiniz kodun üçüncü örneğinde (başlıyor // değeri alın ...) kodun bu bölümünü hangi fonksiyona koyarım? _Ajax_callback işlevine giriyor mu? Teşekkürler
Ben

Bunun için örnek modülü takip ettim, ancak ilk açılan menüden bir öğe seçtiğimde her zaman bir hatayla karşılaştım: Uyarı: array_values ​​(), parametre 1'in dizi olmasını bekliyor, dize, _field_filter_items () (I: \ My Documents satırı 525) \ web \ xampp \ htdocs \ sitem \ modülleri \ alan \ field.module). Özel bir geçersiz kılma modülünde yazdığım bu ajax bağımlı açılır pencere ile birlikte çok adımlı bir form kullanıyorum .... Her ne kadar değerler birinci dd için ikinci gd için değişse de. Bu sadece ortaya çıkan bir uyarı, ama rahatsız edici ... birileri lütfen bu uyarıyı kaldırmama yardım eder mi? Teşekkürler!
jan

2 Bu kod ile @Ben'de çalışmak için sona eren arasındaki farklar. #Suffix'in bir kimlik kullandığını ve ajax geri çağırma işleminin tüm formu değil, form öğesini döndürdüğünü unutmayın. Bunun dışında bu süper yardımcı oldu!
wolffer-doğu

11

Yukarıdaki jordojuice için ç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 atıfta bulundum . Sonunda özel bir modülde çalışan aşağıdaki kodu kullandım. Bazı nedenlerden dolayı benim değerlerin hiçbirini $ form_state değerinde bulamadım, ancak bunları $ biçiminde bulabildim. Sonunda, test ettiğimde, Drupal'ın açılan menüde geçersiz bir seçim tespit ettiğini belirten bir hata mesajı alıyordum. Bunu 1290 satırını form.inc biçiminde yorumlayarak anladım:

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

Kullandığım son kod şuydu:

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

?>

Anladığım kadarıyla yasadışı bir seçim tespit edildi. Lütfen site yöneticisiyle iletişime geçin. Yukarıdaki uygulamayı denediğimde hata. Yardım edebilir misin?
harshal

@harshal - Aynı problemi yaşadım ve cevabımda verdiğim çözümü uygulayarak sorunum vardı, lütfen yukarıya bakın (form.inc değiştirerek). Bu biraz kesmek ama benim için çalıştı.
Ben,

@harshal - Muhtemelen daha iyi bir çözüm, Hacker tarafından aşağıda verilen çözümdür.
Ben,

1

kod İe'nin çizgisini koymak
$nodes[''] = '- None -'; sonra

 $nodes = array();

içinde sappers_squadron_squadrons function ve bu senin hatayı çözecek

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



1

Referans alanı seçenek limit modülünü kullanın

Bu modül, birkaç tipteki referans alanlarının, mevcut varlıktaki diğer alanların değerleri ile sınırlandırılmış widget'larının kullanılabilir seçeneklerine sahip olmasını sağlar.


Koşullu alan modülüne bir alternatif mi?
Umair
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.