it-swarm.asia

قائمة اختيار ديناميكية في النموذج (قائمة منسدلة تابعة)

أنا أستخدم Drupal سبعة. أريد أن أجعل الخيارات في قائمة تحديد تعتمد على القيمة المختارة في قائمة تحديد أخرى في نموذج. أنا متأكد من أن هذا قد تم طرحه عدة مرات من قبل ، لكني أجد صعوبة في العثور على إجابة واضحة لكيفية القيام بذلك.

النموذج للمستخدمين لإدخال سجل العمل. يحتاجون إلى تحديد سرب هو مرجع عقدة إلى نوع حقل السرب ، وهذا في قائمة منسدلة. ومع ذلك ، فإن السرب يعتمد على القائمة المنسدلة للمدينة. يحتاج المستخدمون أولاً إلى تحديد مدينة ستقوم بعد ذلك بتصفية خيارات السرب. في نوع محتوى السرب ، قمت بإنشاء تصنيف للمدينة يتم وضع علامة عليه في السرب.

سأكون ممتنًا جدًا لأية مؤشرات حول أفضل طريقة (أبسط؟) للقيام بذلك ، أو لأي موارد مفيدة عبر الإنترنت قد تساعد.

29
Ben

يمكنك استخدام Ajax لتحقيق ذلك. Drupal 7 يتمتع بدعم Ajax جيد الآن. في قائمة الاختيار الأولى (المدينة) ، ستحتاج إلى إضافة معلومات Ajax. ثم ، يمكن ملء قائمة التحديد الثانية بناءً على المعلومات الواردة في الأول يمكنك أيضًا إخفاء قائمة التحديد الثانية حتى يتم تحديد خيار في الأول ، وسأشرح كيفية القيام بذلك بعد قليل. أولاً ، لإعداد النموذج الأساسي:

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

هذا هو الإعداد الأساسي للعناصر فقط. ستحتاج الآن إلى طريقة لتحديد الخيارات التي يجب استخدامها في السرب. تحتاج أولاً إلى تحديد رد اتصال Ajax الخاص بك في قائمة اختيار "المدينة". في معظم الحالات ، يمكنك فقط إرجاع العنصر الذي يلف عنصر ajax ، في هذه الحالة $ form.

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

الآن ، عندما تتغير قائمة تحديد "المدينة" ، فإنها ستعيد بناء جزء التفاف السرب من النموذج. ستكون قيمة "مدينتك" الآن في $ form_state ["قيم"]. لذلك ، عندما يتم إعادة بناء النموذج ، نحتاج إلى تحديد الخيارات التي يجب تقديمها لقائمة التحديد بناءً على قيمة "المدينة".

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

شكرا جزيلا jordojuice أعلاه. وبمساعدته تمكنت من إيجاد حل. لقد أشرت أيضًا إلى المثال في http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-submission . استخدمت في النهاية الشفرة أدناه التي عملت في وحدة مخصصة. لسبب ما ، لم أتمكن من العثور على أي من القيم الخاصة بي في قيم $ form_state ، لكني تمكنت من العثور عليها في $ $. أخيرًا ، عندما اختبرت ، كنت أتلقى رسالة خطأ تفيد بأن Drupal خيارًا غير قانوني في القائمة المنسدلة. لقد حصلت على هذا تقريبًا من خلال التعليق على السطر 1290 في النموذج.

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

الرمز النهائي الذي استخدمته هو:

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

ضع سطر الكود ، أي
$nodes[''] = '- None -'; بعد

 $nodes = array();

في ur sappers_squadron_squadrons function وهذا سيحل خطأك

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

2
Hacker

السبب الجذري لـ "تم الكشف عن اختيار غير قانوني. يرجى الاتصال بمسؤول الموقع." هو أن السلسلة الفارغة بقيمة 0 مضافة بواسطة $nodes[]=""; غير صالح للحقل field_squadron.

انظر Advance PHP البرمجة والتطوير ، ولكن ضع في اعتبارك أن DANGEROUS_SKIP_CHECK والعلامات المصادق عليها موقوفة في D7 .

بعد إزالة هذا الخط ، ذهب الخطأ.

1
Siripong

استخدم حد خيار الحقل المرجعي الوحدة النمطية

تسمح هذه الوحدة للحقول المرجعية من عدة أنواع أن تكون الخيارات المتاحة لعناصر واجهة المستخدم الخاصة بهم محدودة بقيم الحقول الأخرى في الكيان الحالي.

0
Rakesh Nimje