In Drupal 5.x: I am stuck at trying to validate an admin form that uses checkboxes for a selection. I need to make sure at least one checkbox is ticked. How do I validate this?

Thanks~

Comments

3cwebdev’s picture

BUMP- Any way to validate that at least one checkbox was selected?

The Cosmic Gift | Complete Computer Care | Team Hope

pembeci’s picture

Example taken from the Forms API:

$form['test'] = array(
  '#type' => 'checkboxes',
  '#title' => t('Default options'),
  '#default_value' => variable_get('node_options_'. $node->type, array('status', 'promote')),
  '#options' => array(
    'status' => t('Published'),
    'moderate' => t('In moderation queue'),
    'promote' => t('Promoted to front page'),
    'sticky' => t('Sticky at top of lists'),
    'revision' => t('Create new revision'),
  ),
  '#description' => t('Users with the <em>administer nodes</em> permission will be able to override these options.'),
);

At your form validation function when you check the $form_values array you will see:

Array ( [test] => Array ( [moderate] => moderate [sticky] => sticky [status] => 0 [promote] => 0 [revision] => 0 )

which means 0 for unchecked boxes and the key of the options array for checked ones. So you may use:

count( array_filter($form_values['test'], create_function("$box_value", "return $box_value != 0")))

to get the number of ticked boxes and require it to be greater than 0.

3cwebdev’s picture

I appreciate your reply but I'm afraid I am still stuck with this. I have tried many combos with the example you provided and it still does not work for me. I'm sure the problem is in the fact that I don't really understand what the last parts of the validation line does ... create_function("$box_value", "return $box_value != 0")))

Here is my latest attempt:


function bibleplans_settings_validate($form_id, $form_values) {
	$plans = count( array_filter($form_values['bibleplans_plans'], create_function("$box_value", "return $box_value != 0")))
}

I've cruised right through all the other parts of my module development, it's kinda' annoying to be stuck on what seems like it should be such a simple task. Any more help would be greatly appreciated.

The Cosmic Gift | Complete Computer Care | Team Hope

pembeci’s picture

to be used by php's array_filter function. If you don't know much about php or callback functions, don't worry about that part.

First make sure you are using the correct function name:

function bibleplans_settings_validate($form_id, $form_values) {
    form_set_error('', t('This form would never validate.'));
}

If you can see that error message when you send the form than you are OK. Otherwise, post the form function here, so I can tell you the appropriate function name.

Next do this

function bibleplans_settings_validate($form_id, $form_values) {
  $f = create_function("$box_value", "return $box_value != 0");
  if (count(array_filter($form_values['bibleplans_plans'], $f)) == 0) {
       form_set_error('', t('You must select at least one box.'));
  }
}

Let me know if this didn't work.

3cwebdev’s picture

I verified that the function name was correct with the above test and it did show form validation the error message 'This form would never validate.'

When I used the code you supplied for the actual validation I get this error:
****************************************************************************************
# warning: array_filter(): The second argument, '', should be a valid callback in /rootdir/sites/all/modules/bibleplans/bibleplans.module on line 138.
# You must select at least one box
****************************************************************************************

...which is the same as when I tried with my first attempt.

Perhaps I'm missing something in the way that I'm building/using the form element?

function bibleplans_settings(){
  $form['bibleplans_plans'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Active Bible Plans.'),
	  '#description' => t('Disable any plans that you do not want available to users.'),
      '#default_value' => variable_get('bibleplans_plans', array('chronological')),
      '#options' => $plans, // note: $plans is an associative array
	);
}

The Cosmic Gift | Complete Computer Care | Team Hope

pembeci’s picture

I wrote the code over the top of my head and made the mistake of using double quotes at create_function's parameters. Try this:

function bibleplans_settings_validate($form_id, $form_values) {
  $f = create_function('$box_value', 'return $box_value != 0');
  if (count(array_filter($form_values['bibleplans_plans'], $f)) == 0) {
       form_set_error('', t('You must select at least one box.'));
  }
}

This is a shorter way of doing this:

function bibleplans_settings_validate($form_id, $form_values) {
  $number_of_checked_boxes = 0;
  foreach ($form_values['bibleplans_plans'] as $boxvalue) {
    if ($boxvalue != 0) $number_of_checked_boxes++;
  }
  if ($number_of_checked_boxes == 0) {
       form_set_error('', t('You must select at least one box.'));
  }
}
3cwebdev’s picture

Not for lack of effort, I still can not get this simple function to work properly!

I appreciate your help with this but after three days of trying I still can't validate the checkboxes.

I used both long and short versions of the code supplied, I ended up using the long version because it made sense to me.

Here is the current incarnation:

function bibleplans_settings_validate($form_id, $form_values) {
  $number_of_checked_boxes = 0;
  foreach ($form_values['bibleplans_plans'] as $boxvalue) {
  $test .= $boxvalue . " - ";
    if ($boxvalue != 0) {$number_of_checked_boxes++;}
  }
	if ($number_of_checked_boxes == 0) {
  		form_set_error('bibleplans_plans', t('You must select at least one Bible Plan.'));
	}
}

No matter how I implement the code the checkboxes always fail the validation. Could the problem be in the way that I build the checkbox options array?

Using the Variable editor, this is what it shows the bibleplans_plans array to be:

Array
(
    [chronological] => chronological
    [blended] => 0
)

... which is what I expected it to be with the first of the two checkboxes options ticked. When I made a $test string to append to it the value of $boxvalue on every iteration through the loop, this is the output:

chronological
0"

So the problem is that the ($boxvalue !=0) is not evaluating correctly. I tried ..!='0', with the same result. The really weird thing is that even if I just make an always true statement if(1){.... then the evaluation function doesn't even appear to run (the test I put in the if statement and the evaluation error never fire).

After so much time invested I am at a total loss right now as to what is wrong. Any ideas, or is there a functioning example to look at somewhere?

The Cosmic Gift | Complete Computer Care | Team Hope

pembeci’s picture

Did you try making the first parameter of form_set_error empty string, like:

form_set_error('', t('You must select at least one Bible Plan.'));

May be you are giving the wrong name. Other than that I don't know what is wrong. The array seems correct. What happens when you check the value of $number_of_checked_boxes after the foreach loop is completed? You can also check if you are going inside the last if loop like this:

 if ($number_of_checked_boxes == 0) {
      drupal_set_message('If condition evaluates to true', 'error'); 
      form_set_error('bibleplans_plans', t('You must select at least one Bible Plan.'));
    }
else {
      drupal_set_message('If condition evaluates to false', 'error'); 
}
3cwebdev’s picture

I spent several more hours on it tonight. Yes, I did try making the first parameter of form_set_error empty string. I must of tried every conceivable test and combination to get this thing to work. I thought I had it at one point by making the comparison a single quoted string ... if ($check != '0'){ ... that was the only time it appeared to work, but the next attempt it failed again.

Short of someone actually taking the time to look at the module I don't know what else to do. membeci, I really appreciate all of your help and patience....

The Cosmic Gift | Complete Computer Care | Team Hope

liuba’s picture

This should work:

function bibleplans_settings_validate($form_id, $form_values) {

  $f = create_function('$box_value', 'return $box_value != 0;');

  if (count(array_filter($form_values['bibleplans_plans'], $f)) == 0) {
       form_set_error('', t('You must select at least one box.'));
  }

}
simplyManu’s picture

It works just putting the zero between quotation marks.
I mean, the second argument of the create_function should be: 'return $box_value != "0";'
Remember the array value brought by $form_values is not an int, its a string.

The code that should definitively work:

<?php
function bibleplans_settings_validate($form_id, $form_values) {

  $f = create_function('$box_value', 'return $box_value != "0";');

  if (count(array_filter($form_values['bibleplans_plans'], $f)) == 0) {
       form_set_error('', t('You must select at least one box.'));
  }

}
?>

After this, why don't we just set to TRUE the '#required' when building the form?