'checkboxes'FAPI 요소에서 단일 확인란을 비활성화하려면 어떻게해야합니까?


31

제목은 기본적으로 모든 것을 말하고, 확인란 유형 FAPI 요소 의 단일 확인란을 비활성화하고 싶습니다 .

JavaScript를 사용하고 싶지 않고 다른 모듈에서 요소를 제공 할 때 옵션 을 확인란 에서 여러 확인란 요소 로 변경하고 싶지 않습니다 .

생각?


질문에 오타가 있습니다 : "disable"
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

AFAICT 뷰에서 BEF (Better Exposed Filters)를 사용하는 확인란 (하나 이상의 요소를 선택할 수 있음)에서는 작동하지 않습니다.
1kenthomas

22

불행히도 FAPI에서는 그렇게 할 수있는 확실한 방법이 없습니다. 최선의 방법은 결정된 경우 확인란 요소 에서 추가 #process 함수 를 변경하는 것 입니다.

'checkboxes'유형의 요소에 추가 된 기본 함수는 실제로는 함수 ( expand_checkboxes () )는 단일 요소를 나중에 'checkbox'유형의 여러 요소로 분리하여 나중에 다시 하나로 병합합니다. 두 번째 프로세스 기능을 피기 백하려는 경우 확장 된 'checkbox'요소 그룹에 도달하여 해당 기능을 비활성화 할 수 있습니다.

다음 코드는 완전히 테스트되지 않았으므로주의하십시오.

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()하고 출력을 초과 실행했습니다 .
Decipher

"중단"을 추가 할 수 있습니다. 동일한 요소 키를 두 번 볼 것으로 예상하지 않는 한 위의 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

확인란을 "할당"및 "미 할당"으로 사용하고 있습니다. 클라이언트가 "할당 해제"를 비활성화하라고 요청했지만 "할당"을 나타내는 것이 여전히 중요합니다. DISABLED 확인란은 "false"로 제출되며 올바르게 처리되지 않으면 할당되지 않은 확인란을 "process these"로 분리하고 "disabled 확인란은 무시"합니다. 방법은 다음과 같습니다.

// 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'는 자체 배열 / 변수이며 유스 케이스에서 "unssign"으로 처리되지 않습니다. 게시 해 주셔서 감사합니다.이 솔루션으로 연결되었습니다.


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

이튼의 답변을 서면으로 작동시킬 수 없었습니다 (#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';
}

누군가가 더 깔끔한 방법을 알고 있다면 그것을 듣고 싶습니다!


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에서도 작동합니다.


드루팔 6

다음 기능을 사용할 수 있습니다 ( source ).

/*
 * 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 폼 체크 박스의 $ element 배열 * /

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 () 함수 앞의 주석은 "code"형식을 벗어났습니다. 고맙습니다.
ermannob

0

고려해야 할 한 가지 중요한 사항은 비활성화 된 확인란이 제출되지 않으므로 확인란을 선택해야한다는 것을 알 수 #value있습니다. 예를 들면 다음과 같습니다.

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

제 경우에는 이것이 $form_state['values']없으면 내 확인란 값이 포함되어 있지 않습니다 (기본적으로 활성화되었지만 비활성화되어 있음).


0

텍스트 필드를 연결하고 데이터베이스의 정보를 사용하여 동적 텍스트 상자 만들기

1 °는 Assoc를 얻습니다. 데이터베이스로부터의 배열

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

2 ° 구현 hook_form_alter()

/ ** * hook_form_alter ()를 구현합니다. * 양식 ID =보기 노출 형식 * /

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 함수를 실행하는 대신 'checkboxes'에서 개별 'checkbox'요소 생성으로 전환하면됩니다.

$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.