Bagaimana cara menonaktifkan kotak centang tunggal di elemen FAPI 'kotak centang'?


31

Judul pada dasarnya mengatakan itu semua, saya ingin menonaktifkan satu kotak centang dari elemen kotak centang jenis FAPI.

Saya tidak ingin melakukannya jika dengan JavaScript, juga tidak mengubahnya dari kotak centang ke beberapa elemen kotak centang sebagai pilihan karena elemen disediakan oleh modul lain.

Pikiran?


Ada salah ketik dalam pertanyaan Anda: "disable"
FR6

Jawaban:


36

Cara bersih memang ada di Drupal 7! Rupanya, per posting ini , belum didokumentasikan.

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
}

Contoh lain .

Anda juga dapat mengatur fungsi #access ke FALSE, untuk menyembunyikan kotak centang.


3
Dengan kesalahan ketik diperbaiki, kode ini benar-benar berfungsi untuk saya di D7. Terima kasih!
beth

1
Tangkapan hebat! Senang itu berhasil untuk Anda.
timofey.com

2
Jika Anda menggunakan #access, maka jika kotak centang diatur dalam #default_values, itu tidak akan ditetapkan dalam nilai-nilai bentuk negara pada saat pengiriman.
Nick

Ini bekerja dengan baik.
David Meister

Tidak akan berfungsi dengan kotak centang (dapat memilih lebih dari satu elemen) menggunakan Filter Ekspos yang Lebih Baik (BEF) dalam tampilan, AFAICT.
1kenthomas

22

Sayangnya tidak ada cara yang benar-benar bersih untuk melakukannya di FAPI. Taruhan terbaik Anda - jika Anda bertekad - adalah untuk mengubah fungsi proses #process tambahan ke elemen kotak centang.

Fungsi default yang ditambahkan ke elemen tipe 'checkbox' sebenarnya adalah fungsi ( expand_checkboxes () ) membagi elemen tunggal menjadi beberapa elemen dari tipe 'checkbox' yang kemudian digabungkan kembali menjadi satu. Jika Anda ingin mendukung fungsi proses kedua Anda, itu bisa menjangkau ke dalam grup elemen 'kotak centang' yang diperluas dan menonaktifkan elemen yang dimaksud.

Kode berikut ini sama sekali tidak diuji, jadi emptor peringatan:

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

Kedengarannya lebih baik daripada pendekatan yang saya ambil, yaitu untuk melampirkan fungsi tema ke elemen dan menjalankan preg_replace()lebih dari output.
Menguraikan

Anda dapat menambahkan "break;" di dalam pernyataan if di atas untuk efisiensi sedikit lebih, kecuali Anda berharap untuk melihat kunci elemen yang sama dua kali.
Chris Cohen

Bagus, Chris, saya mengubah cuplikan kode. Terima kasih!
Eaton

2
Jawaban yang diterima tampaknya agak berlebihan jika dibandingkan dengan respons @ timofey.
Citricguy

6

Ini kode saya untuk Drupal 7, untuk mengubah elemen Peran di halaman Edit Pengguna.

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

Saya menggunakan kotak centang sebagai "menetapkan" dan "membatalkan penetapan". Klien telah meminta agar saya menonaktifkan "membatalkan tugas", tetapi masih penting untuk mewakili "tugas." Perlu diingat bahwa kotak centang DISABLED mengirimkan sebagai "salah" dan jika tidak ditangani dengan benar akan membatalkan penetapan, saya membagi kotak centang saya menjadi "proses ini" dan "abaikan yang dinonaktifkan ini." Begini caranya:

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

Perhatikan bahwa 'partner_assignments' adalah array / variabelnya sendiri dan tidak akan diproses sebagai "unassign," dalam kasus penggunaan saya. Terima kasih telah memposting - itu menuntun saya ke solusi ini.


3

D7. Di sini kami harus memastikan bahwa ketika menambahkan sebuah node satu opsi referensi istilah taksonomi tertentu selalu tidak dapat diperiksa dan akan selalu disimpan ke node tersebut. Jadi kami masuk ke #after_build dan menonaktifkan opsi tertentu itu, tetapi harus memastikan bahwa pada akhirnya opsi tertentu akan diteruskan. Karena hanya menonaktifkan itu akan menghentikan perjalanan opsi itu ke kait masa depan.

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

Seperti itulah tampilan opsi yang dinonaktifkan:

masukkan deskripsi gambar di sini


2

Saya tidak bisa mendapatkan jawaban Eaton agar berfungsi seperti yang tertulis (proses panggilan balik #process tidak mengembalikan apa pun, dan itu dipanggil sebelum kotak centang diperluas) dan saya juga ingin agar nilai dikembalikan dari kotak centang yang dinonaktifkan (saya ingin itu diperiksa secara permanen ). Ini bekerja untuk saya (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';
}

Jika ada yang tahu cara yang lebih rapi, saya ingin mendengarnya!


Fatal error: Call to undefined function expand_checkboxes()
leymannx

1
@ Koivo Ini adalah jawaban D6, fungsi tidak ada lagi di D7
Andy

1

Ini kode saya untuk Drupal 7, untuk mengubah elemen Peran di halaman Edit Pengguna.

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

Di Drupal 7, untuk menonaktifkan opsi di pilih di entitas yang dapat fieldable, saya menemukan bahwa saya harus menginstal #processfungsi. Sayangnya, ini menonaktifkan fungsi proses bawaan form_process_checkboxes, sehingga perlu ditambahkan kembali (atau dipanggil dari fungsi proses Anda). Selain itu, ketika menonaktifkan kotak centang yang sudah diperiksa, saya menemukan bahwa callback nilai form_type_checkboxes_valuebawaan ( ) mengabaikan default ketika mengambil hasil dari input.

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

Maka sesuatu seperti ini:

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

Dan akhirnya:

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

Saya tidak menemukan bahwa ada jawaban lain di halaman ini yang berfungsi dalam kasus ini.


1

Inilah contoh saya (menggunakan #after_build):

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

Ditambah fungsi callback berikut:

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

Diuji pada Drupal 6, tetapi harus bekerja untuk Drupal 7 juga.


Drupal 6

Anda dapat menggunakan fungsi ( sumber ) berikut:

/*
 * 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: Sama di sini, menggunakan #after_build berfungsi seperti yang diinginkan. Juga mengonfirmasi pengaturan dinonaktifkan menggunakan #attribute.
SGhosh

0

Saya menggunakan kode berikut ini di drupal 6: -

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

dan fungsi panggilan balik ada di sini: -

/ ** * Memproses setiap kotak centang berdasarkan 'feture' sudah digunakan oleh Sub-domain atau tidak. * @param Array $ array elemen dari checkbox form * /

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

Selamat datang di drupal.stackexchange.com! Harap perbaiki pemformatan kode Anda. Komentar sebelum fungsi legal_process_checkboxes () ditinggalkan di luar format "kode". Terima kasih.
ermannob

0

Satu hal penting yang harus diperhatikan adalah bahwa kotak centang yang dinonaktifkan tidak dapat dikirimkan, jadi Anda mungkin perlu memaksa #valuekotak centang itu juga .. Misalnya:

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

Dalam kasus saya, tanpa ini, $form_state['values']tidak mengandung nilai kotak centang saya (yang diaktifkan secara default, tetapi dinonaktifkan).


0

Kaitkan bidang teks dan buat kotak teks dinamis dengan info dari basis data

1 ° dapatkan assoc. array dari database misalnya

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

2 ° Implements hook_form_alter()

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

Beberapa bidang 3 ° akan dapat diperiksa!


0

Jika Anda sedang membangun form Anda sendiri, alih-alih menjalankan fungsi form_alter / # proses / # pre_render yang terpisah, Anda bisa beralih dari 'kotak centang' ke menghasilkan elemen 'kotak centang' individual.

$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' => TRUEmemberi Anda struktur pohon yang sama dengan versi kotak centang ketika array $ form_state ['values'] tiba di validasi / kirim / bangun kembali. Jika Anda tidak bisa atau tidak ingin menggunakan #tree karena alasan tertentu, berikan setiap kotak centang '#parents' => array('my_element', $key)properti untuk secara eksplisit mengatur posisinya dalam struktur nilai.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.