Làm cách nào tôi có thể vô hiệu hóa một hộp kiểm trong phần tử FAPI của 'hộp kiểm'?


31

Về cơ bản, tiêu đề nói lên tất cả, tôi muốn vô hiệu hóa một hộp kiểm của một hộp kiểm loại phần tử FAPI.

Tôi không muốn làm gì với JavaScript, cũng không thay đổi nó từ các hộp kiểm thành nhiều thành phần hộp kiểm tùy chọn vì thành phần này được cung cấp bởi một mô-đun khác.

Suy nghĩ?


Có một lỗi đánh máy trong câu hỏi của bạn: "vô hiệu hóa"
FR6

Câu trả lời:


36

Một cách sạch sẽ tồn tại trong Drupal 7! Rõ ràng, trên mỗi bài đăng này , nó chưa được ghi lại.

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
}

Một ví dụ khác .

Bạn cũng có thể đặt chức năng #access thành FALSE, để ẩn hoàn toàn hộp kiểm.


3
Với lỗi đánh máy được sửa, mã này hoàn toàn hoạt động với tôi trong D7. Cảm ơn bạn!
beth

1
Cú bắt tuyệt vời! Vui mừng nó đã làm việc cho bạn.
timofey.com

2
Nếu bạn sử dụng #access, thì nếu hộp kiểm được đặt trong #default_values, nó sẽ không được đặt trong các giá trị trạng thái biểu mẫu khi gửi.
Nick

Điều này hoạt động độc đáo.
David Meister

Sẽ không hoạt động với các hộp kiểm (có thể chọn nhiều hơn một yếu tố) bằng cách sử dụng Bộ lọc tiếp xúc tốt hơn (BEF) trong chế độ xem, AFAICT.
1kenthomas

22

Thật không may, không có cách nào thực sự sạch để làm điều đó trong FAPI. Đặt cược tốt nhất của bạn - nếu bạn đã xác định - là thay đổi chức năng # Process bổ sung vào thành phần hộp kiểm.

Hàm mặc định được thêm vào các phần tử của loại 'hộp kiểm' thực sự là một hàm ( extend_checkboxes () ) chia phần tử đơn thành nhiều phần tử của loại 'hộp kiểm' mà sau đó được hợp nhất lại thành một. Nếu bạn cõng chức năng xử lý thứ hai của mình, nó có thể tiếp cận với nhóm các phần tử 'hộp kiểm' được mở rộng và vô hiệu hóa phần tử đang nghi vấn.

Các mã sau đây hoàn toàn chưa được kiểm tra, vì vậy hãy cẩn thận emptor:

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

Âm thanh tốt hơn so với cách tiếp cận tôi đã thực hiện, đó là gắn một chức năng chủ đề cho thành phần và chạy preg_replace()trên đầu ra.
Giải mã

Bạn có thể thêm một "phá vỡ;" bên trong câu lệnh if ở trên để có hiệu quả cao hơn một chút, trừ khi bạn muốn thấy cùng một khóa phần tử hai lần.
Chris Cohen

Bắt tốt, Chris, tôi đã thay đổi đoạn mã. Cảm ơn!
Eaton

2
Câu trả lời được chấp nhận có vẻ hơi quá mức khi so sánh với câu trả lời của @ timofey.
Citricguy

6

Đây là mã của tôi cho Drupal 7, để thay đổi thành phần Vai trò trong trang Chỉnh sửa người dùng.

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

Tôi đang sử dụng các hộp kiểm là "gán" và "không gán". Khách hàng đã yêu cầu tôi vô hiệu hóa "unassign", nhưng điều quan trọng là phải đại diện cho "nhiệm vụ". Hãy nhớ rằng các hộp kiểm DISABLED gửi là "sai" và nếu không được xử lý đúng cách sẽ không được gán, tôi chia các hộp kiểm của mình thành "xử lý những cái này" và "bỏ qua những cái bị vô hiệu hóa này". Đây là cách thực hiện:

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

Lưu ý rằng 'Partner_assignments' là mảng / biến riêng của nó và sẽ không được xử lý là "unassign", trong trường hợp sử dụng của tôi. Cảm ơn bạn đã đăng bài-- nó dẫn tôi đến giải pháp này.


3

D7. Ở đây chúng tôi phải đảm bảo rằng khi thêm một nút, một tùy chọn tham chiếu thuật ngữ phân loại nhất định luôn không thể kiểm soát được và sẽ luôn được lưu vào nút. Vì vậy, chúng tôi đã đi vào #after_build và vô hiệu hóa tùy chọn nhất định đó, nhưng phải đảm bảo rằng cuối cùng thì tùy chọn nhất định sẽ được truyền lại. Nguyên nhân chỉ vô hiệu hóa nó sẽ khiến cho tùy chọn đó chuyển sang các móc nối trong tương lai.

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

Đó là cách tùy chọn bị vô hiệu hóa trông như sau:

nhập mô tả hình ảnh ở đây


2

Tôi không thể để câu trả lời của Eaton hoạt động như được viết (cuộc gọi lại # process không trả lại bất cứ điều gì và nó được gọi trước khi các hộp kiểm được mở rộng) và tôi cũng muốn trả về giá trị từ hộp kiểm bị vô hiệu hóa (tôi muốn nó được kiểm tra vĩnh viễn ). Điều này làm việc cho tôi (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';
}

Nếu bất cứ ai biết một cách gọn gàng hơn, tôi rất thích nghe nó!


Fatal error: Call to undefined function expand_checkboxes()
leymannx

1
@koivo Đây là câu trả lời của D6, chức năng không còn tồn tại trong D7
Andy

1

Đây là mã của tôi cho Drupal 7, để thay đổi thành phần Vai trò trong trang Chỉnh sửa người dùng.

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

Trong Drupal 7, để vô hiệu hóa các tùy chọn trong một lựa chọn trong một thực thể có thể thực hiện được, tôi thấy rằng tôi phải cài đặt một #processchức năng. Thật không may, điều này đã vô hiệu hóa chức năng quy trình tích hợp, form_process_checkboxesdo đó cần phải được thêm lại (hoặc được gọi từ chức năng quy trình của bạn). Ngoài ra, khi vô hiệu hóa các hộp kiểm đã được kiểm tra, tôi phát hiện ra rằng hàm gọi lại giá trị tích hợp ( form_type_checkboxes_value) bỏ qua mặc định khi truy xuất kết quả từ đầu vào.

$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';

Sau đó, một cái gì đó như thế này:

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

Và cuối cùng:

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

Tôi không thấy rằng bất kỳ câu trả lời nào khác trên trang này hoạt động trong trường hợp này.


1

Dưới đây là ví dụ của tôi (sử dụng #after_build):

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

Cộng với chức năng gọi lại sau:

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

Đã thử nghiệm trên Drupal 6, nhưng nó cũng hoạt động với Drupal 7.


Drupal 6

Bạn có thể sử dụng chức năng sau ( nguồn ):

/*
 * 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: Tương tự ở đây, sử dụng #after_build đang hoạt động như mong muốn. Đồng thời xác nhận cài đặt bị vô hiệu hóa bằng cách sử dụng #attribution.
SGhosh

0

Tôi đang sử dụng mã sau đây tại drupal 6: -

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

và chức năng gọi lại ở đây: -

/ ** * Xử lý từng hộp kiểm dựa trên 'feture' đã được sử dụng bởi Tên miền phụ hay chưa. * @param Array $ mảng phần tử của hộp kiểm biểu mẫu * /

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

Chào mừng bạn đến với drupal.stackexchange.com! Vui lòng sửa định dạng mã của bạn. Nhận xét trước khi hàm Legal_ process_checkboxes () được để bên ngoài định dạng "mã". Cảm ơn bạn.
ermannob

0

Một điều quan trọng cần tính đến là các hộp kiểm bị vô hiệu hóa không được gửi, vì vậy bạn có thể thấy rằng bạn cũng cần phải buộc #valuehộp kiểm đó .. Ví dụ:

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

Trong trường hợp của tôi, không có cái này, cái $form_state['values']này không chứa giá trị hộp kiểm của tôi (được bật theo mặc định, nhưng bị vô hiệu hóa).


0

Móc trường văn bản và tạo một hộp văn bản động với thông tin từ cơ sở dữ liệu

1 ° nhận PGS. mảng từ cơ sở dữ liệu, ví dụ

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

Thực hiện 2 ° hook_form_alter()

/ ** * Triển khai hook_form_alter (). * biểu mẫu id = lượt xem-lộ-mẫu * /

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 ° nhiều lĩnh vực sẽ được kiểm tra!


0

Nếu bạn đang xây dựng biểu mẫu của riêng mình, thay vì chạy qua các hàm form_alter / # process / # pre numnder riêng biệt, bạn chỉ có thể chuyển từ 'hộp kiểm' sang tạo các phần tử 'hộp kiểm' riêng lẻ.

$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' => TRUEcung cấp cho bạn cấu trúc cây giống như phiên bản hộp kiểm khi mảng $ form_state ['value'] đến lúc xác thực / gửi / xây dựng lại. Nếu bạn không thể hoặc không muốn sử dụng #tree vì một số lý do, hãy cung cấp cho mỗi hộp kiểm một thuộc '#parents' => array('my_element', $key)tính để đặt rõ ràng vị trí của nó trong cấu trúc giá trị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.