ฉันจะปิดใช้งานช่องทำเครื่องหมายเดียวในองค์ประกอบ 'ช่องทำเครื่องหมาย' FAPI ได้อย่างไร


31

โดยทั่วไปชื่อจะบอกว่ามันทั้งหมดฉันต้องการปิดใช้งานช่องทำเครื่องหมายเดียวของช่องทำเครื่องหมายประเภทองค์ประกอบ FAPI

ฉันไม่ต้องการจะทำอะไรกับ JavaScript หรือไม่เปลี่ยนจากช่องทำเครื่องหมายเป็นองค์ประกอบช่องทำเครื่องหมายหลายตัวเลือกตัวเลือกเป็นองค์ประกอบที่มีให้โดยโมดูลอื่น

คิด?


มีข้อผิดพลาดในคำถามของคุณ: "ปิดการใช้งาน"
FR6

คำตอบ:


36

วิธีทำความสะอาดนั้นมีอยู่ใน Drupal 7! เห็นได้ชัดว่าตามโพสต์นี้ยังไม่มีการจัดทำเป็นเอกสาร

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#disabled'] = TRUE; //disables all options
  $form['checkboxes_element'][abc]['#disabled'] = TRUE; //disables option, called abc
}

อีกตัวอย่างเช่น

นอกจากนี้คุณยังสามารถตั้งค่า#accessฟังก์ชันเป็น FALSE เพื่อซ่อนช่องทำเครื่องหมายอย่างสมบูรณ์


3
ด้วยการแก้ไขการพิมพ์ผิดรหัสนี้ได้ผลสำหรับฉันใน D7 ขอขอบคุณ!

1
เยี่ยมมาก! ดีใจที่ได้ผลกับคุณ
timofey.com

2
หากคุณใช้ #access ดังนั้นหากมีการตั้งค่าช่องทำเครื่องหมายใน #default_values ​​จะไม่ได้รับการตั้งค่าในรูปแบบค่าสถานะของการส่ง
Nick

มันใช้งานได้ดี
David Meister

จะไม่ทำงานกับช่องทำเครื่องหมาย (สามารถเลือกมากกว่าหนึ่งองค์ประกอบ) โดยใช้ Better Exposed Filters (BEF) ในมุมมอง AFAICT
1kenthomas

22

น่าเสียดายที่ไม่มีวิธีที่สะอาดในการทำเช่นนั้นใน FAPI ทางออกที่ดีที่สุดของคุณ - ถ้าคุณตั้งใจ - คือการเปลี่ยนฟังก์ชั่น #processเพิ่มเติมลงในองค์ประกอบช่องทำเครื่องหมาย

ฟังก์ชั่นเริ่มต้นที่เพิ่มให้กับองค์ประกอบประเภท 'ช่องทำเครื่องหมาย' เป็นจริงฟังก์ชั่น ( expand_checkboxes () ) แยกองค์ประกอบเดียวออกเป็นองค์ประกอบหลายประเภท 'ช่องทำเครื่องหมาย' ประเภทที่จะรวมกันในภายหลัง หากคุณต้องการย้อนกลับฟังก์ชั่นกระบวนการที่สองของคุณมันสามารถเข้าถึงกลุ่มที่ขยายขององค์ประกอบ 'ช่องทำเครื่องหมาย' และปิดการใช้งานหนึ่งในคำถาม

รหัสต่อไปนี้ยังไม่ได้ทดสอบอย่างเต็มที่ดังนั้นตัวเตือน caveat:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#process'][] = 'mymodule_disable_element';
}

function mymodule_disable_element($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#disabled'] = TRUE;
      return;
    }
  }
}

ฟังดูดีกว่าวิธีที่ฉันใช้ซึ่งก็คือการแนบฟังก์ชั่นชุดรูปแบบกับองค์ประกอบและเรียกใช้preg_replace()เอาต์พุต
ถอดรหัส

คุณสามารถเพิ่ม "ตัวแบ่ง;" ภายในคำสั่ง if ด้านบนเพื่อประสิทธิภาพที่เพิ่มขึ้นเล็กน้อยเว้นแต่คุณคาดว่าจะเห็นคีย์องค์ประกอบเดียวกันสองครั้ง
Chris Cohen

จับได้ดี Chris ฉันเปลี่ยนข้อมูลโค้ด ขอบคุณ!
Eaton

2
คำตอบที่ได้รับการยอมรับดูเหมือนจะเกินความจริงเล็กน้อยเมื่อเทียบกับคำตอบของ @ timofey
Citricguy

6

นี่คือรหัสของฉันสำหรับ Drupal 7 เพื่อเปลี่ยนองค์ประกอบบทบาทในหน้าแก้ไขผู้ใช้

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#pre_render'][] = 'form_process_checkboxes'; // I had to add this one, or it will return the first role only with my callback bellow
  $form['checkboxes_element']['#pre_render'][] = 'mymodule_disable_element';
}

function mymodule_disable_element(($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#attributes']['disabled'] = 'disabled';
    }
  }
  return $element;
}

3

ฉันใช้ช่องทำเครื่องหมายเป็น "กำหนด" และ "ยกเลิกการกำหนด" ลูกค้าขอให้ฉันปิดการใช้งาน "ยกเลิกการกำหนด" แต่ก็ยังมีความสำคัญที่จะแสดง "การมอบหมาย" โปรดทราบว่ากล่องกาเครื่องหมายปิดใช้งานการส่งเป็น "เท็จ" และหากไม่ได้รับการจัดการอย่างถูกต้องจะยกเลิกการกำหนดฉันจะแยกช่องทำเครื่องหมายของฉันเป็น "ประมวลผลสิ่งเหล่านี้" และ "เพิกเฉยต่อคนพิการเหล่านี้" นี่คือวิธี:

// Provide LIVE checkboxes only for un-assigned Partners
$form['partner']['partners'] = array(
  '#type' => 'checkboxes',
  '#options' => array_diff($partners, $assignments),
  '#title' => t($partnername),
);
// Provide DISABLED checkboxes for assigned Partners (but with a different variable, so it doesn't get processed as un-assignment)
$form['partner']['partner_assignments'] = array(
  '#type' => 'checkboxes',
  '#options' => $assignments,
  '#default_value' => array_keys($assignments),
  '#disabled' => TRUE,
  '#title' => t($partnername),
);

โปรดสังเกตว่า 'partner_assignments' เป็นอาร์เรย์ / ตัวแปรของตัวเองและจะไม่ถูกประมวลผลเป็น "unassign" ในกรณีที่ใช้งานของฉัน ขอบคุณสำหรับการโพสต์ - มันนำฉันไปสู่โซลูชันนี้


3

D7 ที่นี่เราต้องให้แน่ใจว่าเมื่อเพิ่มโหนดหนึ่งตัวเลือกการอ้างอิงคำศัพท์อนุกรมวิธานบางอย่างนั้นไม่สามารถตรวจสอบได้และจะถูกบันทึกลงในโหนดเสมอ ดังนั้นเราจึงเข้าไปใน #after_build และปิดการใช้งานตัวเลือกบางอย่าง แต่ต้องตรวจสอบให้แน่ใจว่าในที่สุดแล้วตัวเลือกบางอย่างจะถูกส่งต่อไป สาเหตุเฉพาะการปิดการใช้งานมันจะหยุดการเดินทางของตัวเลือกนั้นไปยังตะขอในอนาคต

// a constant
define('MYTERM', 113);

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id == 'MYCONTENTTYPE_node_form') {
    $form['#after_build'][] = 'MYMODULE_MYCONTENTTYPE_node_form_after_build';
    }
}

/**
 * Implements custom after_build_function()
 */
function MYMODULE_MYCONTENTTYPE_node_form_after_build($form, &$form_state) {
  foreach (element_children($form['field_MYFIELD'][LANGUAGE_NONE]) as $tid) {
    if ($tid == MYTERM) {
      $element = &$form['field_MYFIELD'][LANGUAGE_NONE][$tid];
      $element['#checked'] = TRUE;
      $element['#attributes']['disabled'] = 'disabled';
    }
  }
  // here's ensured the term's travel goes on
  $form['field_MYFIELD'][LANGUAGE_NONE]['#value'] += drupal_map_assoc(array(MYTERM));
  return $form;
}

นี่คือลักษณะของตัวเลือกที่ปิดใช้งาน:

ป้อนคำอธิบายรูปภาพที่นี่


2

ฉันไม่สามารถรับคำตอบของ Eaton ได้ตามที่เขียนไว้ (การเรียกกลับ #process ไม่ส่งคืนสิ่งใดและถูกเรียกก่อนที่จะขยายช่องทำเครื่องหมาย) และฉันต้องการรับค่าที่ส่งคืนจากช่องทำเครื่องหมายที่ปิดใช้งาน (ฉันต้องการให้ตรวจสอบอย่างถาวร ) สิ่งนี้ใช้ได้สำหรับฉัน (D6)

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#process'][] = 'mymodule_disable_element';
}

function mymodule_disable_element($element) {
  $expanded = expand_checkboxes($element);
  $checkbox =& $expanded[YOUR_CHECK_VALUE];
  $checkbox['#disabled'] = TRUE;
  $checkbox['#value_callback'] = 'mymodule_element_value_callback';
  return $expanded;
}

function mymodule_element_value_callback($element, $edit = FALSE) {
  // Return whatever value you'd like here, otherwise the element will return
  // FALSE because it's disabled.
  return 'VALUE';
}

หากใครรู้วิธีที่ neater ฉันชอบที่จะได้ยินมัน!


Fatal error: Call to undefined function expand_checkboxes()
leymannx

1
@koivo นี่คือคำตอบ D6 ฟังก์ชั่นนี้ไม่มีอยู่ใน D7 อีกต่อไป
Andy

1

นี่คือรหัสของฉันสำหรับ Drupal 7 เพื่อเปลี่ยนองค์ประกอบบทบาทในหน้าแก้ไขผู้ใช้

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#pre_render'][] = 'form_process_checkboxes'; // I had to add this one, or it will return the first role only with my callback bellow
  $form['checkboxes_element']['#pre_render'][] = 'mymodule_disable_element';
}

function mymodule_disable_element(($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#attributes']['disabled'] = 'disabled';
      return $element;
    }
  }
  return $element;
}

1

ใน Drupal 7 เพื่อที่จะปิดการใช้งานตัวเลือกในรายการที่เลือกในเอนทิตีที่สามารถทำงานได้ฉันพบว่าฉันต้องติดตั้ง#processฟังก์ชั่น น่าเสียดายที่สิ่งนี้ปิดใช้งานฟังก์ชันกระบวนการในตัวform_process_checkboxesดังนั้นจำเป็นต้องเพิ่มกลับ (หรือเรียกจากฟังก์ชันกระบวนการของคุณ) นอกจากนี้เมื่อปิดการใช้งานช่องทำเครื่องหมายที่ตรวจสอบแล้วฉันค้นพบว่าการเรียกกลับค่าในตัว ( form_type_checkboxes_value) จะละเว้นค่าเริ่มต้นเมื่อดึงผลลัพธ์จากอินพุต

$field_lang_form = &$your_form[$field][LANGUAGE_NONE];
$field_lang_form['#process'][] = 'form_process_checkboxes';
$field_lang_form['#process'][] = 'YOURMODULE_YOURFUNCTION_process';
$field_lang_form['#value_callback'] = 'YOURMODULE_form_type_checkboxes_value';

จากนั้นบางสิ่งเช่นนี้:

function YOURMODULE_YOURFUNCTION_process($element) {
  // Disallow access YOUR REASON, but show as disabled if option is set.
  foreach (element_children($element) as $field) {
    if (REASON TO DISABLE HERE) {
      if (!empty($element[$field]['#default_value'])) {
        $element[$field]['#disabled'] = TRUE;
      } else {
        $element[$club]['#access'] = FALSE;
      }
    }
  }
  return $element;
}

และในที่สุดก็:

function YOURMODULE_form_type_checkboxes_value($element, $input = FALSE) {
  if ($input !== FALSE) {
    foreach ($element['#default_value'] as $value) {
      if (THIS OPTION WAS SET AND DISABLED - YOUR BUSINESS LOGIC) {
        // This option was disabled and was not returned by the browser. Set it manually.
        $input[$value] = $value;
      }
    }
  }
  return form_type_checkboxes_value($element, $input);
}

ฉันไม่พบคำตอบอื่นใดในหน้านี้ที่ใช้งานได้ในกรณีนี้


1

นี่คือตัวอย่างของฉัน (ใช้#after_build):

$form['legal']['legal_accept']['#type'] = 'checkboxes';
$form['legal']['legal_accept']['#options'] = $options;
$form['legal']['legal_accept']['#after_build'][] = '_process_checkboxes';

บวกฟังก์ชั่นการโทรกลับต่อไปนี้:

function _process_checkboxes($element) {
  foreach (element_children($element) as $key) {
    if ($key == 0) { // value of your checkbox, 0, 1, etc.
      $element[$key]['#attributes'] = array('disabled' => 'disabled');
      // $element[$key]['#theme'] = 'hidden'; // hide completely
    }
  }
  return $element;
}

ทดสอบกับ Drupal 6 แล้ว แต่ควรใช้กับ Drupal 7 เช่นกัน


Drupal 6

คุณสามารถใช้ฟังก์ชั่นต่อไปนี้ (ที่มา ):

/*
 * Change options for individual checkbox or radio field in the form
 * You can use this function using form_alter hook.
 * i.e. _set_checkbox_option('field_tier_level', 'associate', array('#disabled' => 'disabled'), $form);
 *
 * @param $field_name (string)
 *    Name of the field in the form
 * @param $checkbox_name (string)
 *    Name of checkbox to change options (if it's null, set to all)
 * @param $options (array)
 *    Custom options to set
 * @param $form (array)
 *    Form to change
 *
 * @author kenorb at gmail.com
 */
function _set_checkbox_option($field_name, $checkbox_name = NULL, $options, &$form) {
    if (isset($form[$field_name]) && is_array($form[$field_name])) {
        foreach ($form[$field_name] as $key => $value) {
            if (isset($form[$field_name][$key]['#type'])) {
                $curr_arr = &$form[$field_name][$key]; // set array as current
                $type = $form[$field_name][$key]['#type'];
                break;
            }
        }
        if (isset($curr_arr) && is_array($curr_arr['#default_value'])) {
            switch ($type) { // changed type from plural to singular
                case 'radios':
                    $type = 'radio';
                    break;
                case 'checkboxes':
                    $type = 'checkbox';
                    break;
            }

            foreach ($curr_arr['#default_value'] as $key => $value) {
                foreach($curr_arr as $old_key => $old_value) { // copy existing options for to current option
                    $new_options[$old_key] = $old_value;
                }
                $new_options['#type'] = $type;  // set type
                $new_options['#title'] = $value;  // set correct title of option
                $curr_arr[$key] = $new_options; // set new options

                if (empty($checkbox_name) || strcasecmp($checkbox_name, $value) == 0) { // check name or set for 
                    foreach($options as $new_key => $new_value) {
                        $curr_arr[$key][$new_key] = $value;
                    }
                }
            }
            unset($curr_arr['#options']); // delete old options settings
        } else {
            return NULL;
        }
    } else {
        return NULL;
    }
}

/*
 * Disable selected field in the form(whatever if it's textfield, checkbox or radio)
 * You can use this function using form_alter hook.
 * i.e. _disable_field('title', $form);
 *
 * @param $field_name (string)
 *    Name of the field in the form
 * @param $form (array)
 *    Form to change
 *
 * @author kenorb at gmail.com
 */
function _disable_field($field_name, &$form) {
    $keyname = '#disabled';

    if (!isset($form[$field_name])) { // case: if field doesn't exists, put keyname in the main array
        $form[$keyname] = TRUE;
    } else if (!isset($form[$field_name]['#type']) && is_array($form[$field_name])) { // case: if type not exist, find type from inside of array
        foreach ($form[$field_name] as $key => $value) {
            if (isset($form[$field_name][$key]['#type'])) {
                $curr_arr = &$form[$field_name][$key]; // set array as current
                break;
            }
        }
    } else {
        $curr_arr = &$form[$field_name]; // set field array as current
    }

    // set the value
    if (isset($curr_arr['#type'])) {
        switch ($curr_arr['#type']) {
            case 'textfield':
            default:
                $curr_arr[$keyname] = TRUE;
        }
    }
}

D7: เหมือนกันที่นี่การใช้ #after_build ทำงานได้ตามที่ต้องการ ยังยืนยันการตั้งค่าที่ปิดใช้งานโดยใช้ #attribute
SGhosh

0

ฉันใช้รหัสต่อไปนี้ที่ drupal 6: -

$form['statuses'] = array(
    '#type' => 'checkboxes',
    '#options' => $statuses,
    '#default_value' => $status_val,
    '#after_build' => array('legal_process_checkboxes')
    );

และฟังก์ชั่นการโทรกลับอยู่ที่นี่: -

/ ** * ประมวลผลแต่ละช่องที่อ้างอิงตาม 'feture' ถูกใช้โดยโดเมนย่อยหรือไม่ * @param Array $ อาร์เรย์องค์ประกอบของช่องทำเครื่องหมายแบบฟอร์ม * /

function legal_process_checkboxes($element) {

  foreach (element_children($element) as $key) {

    $feature_id = $key;
    $res_total = '';

    $total = feature_used($feature_id) ;

    if ($total) {
      $element[$key]['#attributes'] = array('disabled' => 'disabled');
    }
  }
  return $element;
}

ยินดีต้อนรับสู่ drupal.stackexchange.com! โปรดแก้ไขการจัดรูปแบบรหัสของคุณ ความคิดเห็นก่อน legal_process_checkboxes () ฟังก์ชั่นถูกทิ้งไว้นอกรูปแบบ "รหัส" ขอขอบคุณ.
ermannob

0

สิ่งสำคัญอย่างหนึ่งที่ต้องคำนึงถึงคือไม่ได้ส่งช่องทำเครื่องหมายที่ถูกปิดใช้งานดังนั้นคุณอาจพบว่าคุณจำเป็นต้องบังคับ#valueช่องทำเครื่องหมายด้วยเช่น:

$element['child1']['#disabled'] = TRUE;
$element['child1']['#value'] = 'child1';

ในกรณีของฉันหากไม่มีสิ่งนี้$form_state['values']จะไม่มีค่าช่องทำเครื่องหมายของฉัน (ซึ่งถูกเปิดใช้งานโดยค่าเริ่มต้น แต่ถูกปิดใช้งาน)


0

ขอเพิ่มฟิลด์ข้อความและสร้างกล่องข้อความแบบไดนามิกพร้อมข้อมูลจากฐานข้อมูล

1 °รับรอง อาร์เรย์จากฐานข้อมูลเช่น

$blah = array('test1' => 'Choose for test1', 'test2' => 'Choose for test2', ...)

2 °นำไปใช้ hook_form_alter()

/ ** * ใช้งาน hook_form_alter () * form id = views-exposed-form * /

function test_form_alter(&$form, &$form_state, $form_id)
{
  //only for this particular form
  if ($form['#id'] == "views-exposed-form-advanced-search-page-2")
    {
       $form['phases'] = array(
           '#type' => 'checkboxes',
           '#options' => $blah,
      );
    }
}

3 °หลายช่องจะตรวจสอบได้!


0

หากคุณกำลังสร้างฟอร์มของคุณเองแทนที่จะเรียกใช้ผ่านฟังก์ชั่น form_alter / # process / # pre_render แยกจากกันคุณสามารถเปลี่ยนจาก 'ช่องทำเครื่องหมาย' เป็นการสร้างองค์ประกอบ 'ช่องทำเครื่องหมาย' แต่ละรายการ

$options = array(
   1 => t('Option one'),
   2 => t('Option two'),
);

// Standard 'checkboxes' method:
$form['my_element'] = array(
  '#type' => 'checkboxes',
  '#title' => t('Some checkboxes'),
  '#options' => $options,
);

// Individual 'checkbox' method:
$form['my_element'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('form-checkboxes')),
  '#tree' => TRUE,
  'label' => array('#markup' => '<label>' . t('Some checkboxes') . '</label>',
);
foreach ($options as $key => $label) {
  $form['my_element'][$key] = array(
    '#type' => 'checkbox',
    '#title' => $label,
    '#return_value' => $key,
  );
}
// Set whatever #disabled (etc) properties you need.
$form['my_element'][1]['#disabled'] = TRUE;

'#tree' => TRUEให้โครงสร้างแบบต้นไม้เดียวกับรุ่นกล่องกาเครื่องหมายเมื่ออาร์เรย์ $ form_state ['values'] มาถึงเมื่อมีการตรวจสอบ / ส่ง / สร้างใหม่ หากคุณไม่สามารถหรือไม่ต้องการใช้ #tree ด้วยเหตุผลบางอย่างให้กล่องกาเครื่องหมายแต่ละรายการมี'#parents' => array('my_element', $key)คุณสมบัติเพื่อกำหนดตำแหน่งอย่างชัดเจนในโครงสร้างค่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.