Does somebody know a way to disable a checkbox once it has been checked and the node has been saved?

I have a CCK single on/off checkbox with PHP allowed values (either 0 or a value from the database). I want to allow users to 'activate' the checkbox, but once they save the node and edit it, they shouldn't be able to uncheck it.

i.e. if the active value is 0, allow selection, if it is different from 0, not.

Comments

sepla’s picture

For this example, we're assume that the checkbox field name is 'some_module_checkbox':

/**
 * Some module form.
 */
function some_module_form() {
  $form = array();

  $disabled = variable_get('some_module_checkbox', FALSE) ? TRUE : FALSE;
  $form['some_module_checkbox'] = array(
    '#type' => 'checkbox',
    '#title' => t('A Checkbox'),
    '#default_value' => 0,
    '#return_value' => 1,
    '#disabled' => $disabled,
  );
    
  return $form;
}
  
/**
 * Form validation callback.
 */
function some_module_form_validate($form, &$form_state) {
  if ($form_state['values']['some_module_checkbox'] && variable_get('some_module_checkbox', FALSE)) {
    form_set_error('some_module_checkbox', t('You cannot deactivate this checkbox once you check it.'));
  }
}

/**
 * Form submission callback.
 */
function some_module_form_submit($form, &$form_state) {
  if ($form_state['values']['some_module_checkbox']) {
    variable_set('some_module_checkbox', TRUE);
  }
}

Also I recommend to use #access instead of #disabled. If you provide some code snippets, the people could help you better.

API Reference:
http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....
http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....

yan’s picture

Thanks Sepher. Just a little confusion: Does "some_module" mean the name of a custom module? Or does it mean the name of the CCK field affected? In the second case, where would I place this code?

sagar ramgade’s picture

Yes some_module means a name of your custom module, You need to use a hook_form_alter in order to validate and add a submit function for your node form.

Acquia certified Developer, Back end and Front specialist
Need help? Please use my contact form

yan’s picture

Great, with some help from here I got to the following code which works for me:

/**
* Implementation of hook_form_alter().
* To disable the checkbox once a code has been selected
* From drupal.org/node/357328
*/

function mysnippet_form_alter(&$form, $form_state, $form_id) {

  if (isset($form['type']) && isset($form['#node']) && $form['#node']->field_myfield[0]['value'] != 0) {

    // Use this check to match node edit form for any content type.
    if ($form['type']['#value'] .'_node_form' == $form_id) {
      $form['#after_build'][] = '_mysnippet_after_build';
    }

    // Use this check to match node edit form for a particular content type.
    // if ('mytype_node_form' == $form_id) {
    //   $form['#after_build'][] = '_mysnippet_after_build';
    // }

  }
}


/**
* Custom after_build callback handler.
*/

function _mysnippet_after_build($form, &$form_state) {

  // Use this one if the field is placed on top of the form.
  _mysnippet_fix_disabled($form['field_myfield']);

  // Use this one if the field is placed inside a fieldgroup.
  // _mysnippet_fix_disabled($form['group_mygroup']['field_myfield']);

  return $form;
}


/**
* Recursively set the disabled attribute of a CCK field
* and all its dependent FAPI elements.
*/

function _mysnippet_fix_disabled(&$elements) {

  foreach (element_children($elements) as $key) {
    if (isset($elements[$key]) && $elements[$key]) {

      // Recurse through all children elements.
      _mysnippet_fix_disabled($elements[$key]);
    }
  }

  if (!isset($elements['#attributes'])) {
    $elements['#attributes'] = array();
  }
  $elements['#attributes']['disabled'] = 'disabled';
}

Thanks!