In a module I'm working on, I have a couple of blocks. I've edited the block configuration form using hook_form_alter() so that settings specific to that block will appear. But I need to validate those settings so users can't put values like -1 in a field that asks how many results they want displayed. How would I go about doing that?

Thanks in advance.

Comments

icecreamyou’s picture

Alright, so I just found out I can use '#validate' to specify the validation function I want to use for a form element. But will that override the default validation function? And if so, how can I keep it from doing that?

icecreamyou’s picture

*Bump.*

icecreamyou’s picture

*Bump.*

omnyx’s picture

but you may want to use the following format:

        $form['#validate'] += array('module_name_validate' => array());

you put this in yout hook_form_alter (as you can see it's the '+=' that does the trick in ensuring other validations are untouched)
then you have that function (for example this checks if the emails match)

function module_name_validate($form_id, $form_values) {
  //Check to see whether our e-mail address matches the confirm address if enabled.
    if ($form_values['mail'] != $form_values['mail1']) {
      form_set_error('mail1', t('Your e-mail address and confirmed e-mail address must match.'));
    }
}

please let me know if this works - i'm interested myself :)

icecreamyou’s picture

please let me know if this works - i'm interested myself :)

Sorry I didn't get to this yesterday - I was really busy. But I'll try it out tonight and see how it goes. It looks right to me - I seem to remember seeing similar code somewhere...

icecreamyou’s picture

It turns out that the block configuration page doesn't have any built-in validation, so it *should* be okay to just add custom validation with '#validate' => array('your_function_validate' => array()); except that this *could* cause problems if another module edits the block configuration form.

However, using += causes a Fatal Error: Invalid Operator. The only remaining option as far as I can tell is to use array_merge(), but since we don't know what array we need to merge with, that won't help anything. :-/

omnyx’s picture

This is how I'm using that code. It's almost identical to the code in login toboggan module (which is where i got it :)

/*
** This module adds a 'Confirm e-mail address' field to ensure accuracy  
*/
function emailverify_form_alter($form_id, &$form) {
  switch ($form_id) {
    case 'user_register':
      {
        $form['#validate'] += array('emailverify_user_register_validate' => array());
          // Make sure user help is at the top of the form.
          //$form['user_registration_help']['#weight'] = -100;
          $form['conf_mail'] = array('#type' => 'textfield',
            '#title' => t('Confirm e-mail address'),
            '#weight' => -28,
            '#maxlength' => 64,
            '#description' => t('Please re-type your e-mail address to confirm it is accurate.'),
            '#required' => TRUE,
            );

          // Weight things properly so that the order is name, mail, conf_mail, then pass
          if (isset($form['account'])) {
            $form['account']['#weight'] = -50;  // Make sure account form group is at the top of the display.
            $form['account']['name']['#weight'] = -30;
            $form['account']['mail']['#weight'] = -29;
            $form['account']['conf_mail'] = $form['conf_mail'];
            unset($form['conf_mail']);
            $form['account']['conf_mail']['#weight'] = -28;
          }
          else {
            $form['name']['#weight'] = -30;
            $form['mail']['#weight'] = -29;
          }
      }
   }
}           
        
           
function emailverify_user_register_validate($form_id, $form_values) {
  //Check to see whether our e-mail address matches the confirm address if enabled.
      if ($form_values['mail'] != $form_values['conf_mail']) {
      form_set_error('conf_mail', t('Your e-mail address and confirmed e-mail address must match.'));
    }
}

It seems to work for me - no problems so far

icecreamyou’s picture

That's nearly exactly what I did. But maybe "+=" only works if there's already a value for '#validate', and there isn't one for the block configuration form. Maybe I should do a check first. Will look into it.

icecreamyou’s picture

The problem turned out to be that I wasn't using $form['#validate'] - I was using $form['...']['#validate'] which is broken in 5.x. The solution is to use the validate function for the entire form, as you did.

Thanks.

coderintherye’s picture

I've been trying to use this method effectively using $form['#submit'] but haven't been able to figure out a way to get it to work. If I do it with $form[..]['#submit'] in 5.x then it fails to work. I tried the += bit and it worked, but then Drupal returns errors (which is highly annoying although I remember reading something about how += isn't supported in php 5 or somthing along those lines)

So, i'm stuck. Using submit on the whole form works, but it interrupts the normal node submit. I tried using validate instead and got the same effect.

icecreamyou’s picture

I have no idea, honestly. But if you want to take a look at my implementation you can look at facebook_status.module... although I've been having some problems getting the _validate and _submit functions to run at all on that one lately.

coderintherye’s picture

Heine in #drupal chat told me to use hook_nodeapi() instead, once we tweaked it right, using case insert and case update and $node->xxxxx to get form variable data, it worked like a charm and was able to get rid of the need for a function_submit or ['#submit']

icecreamyou’s picture

That's not a generic solution and won't work for the original question about block configuration forms. But good to know nonetheless.

smanes’s picture

$form[#validate][] = 'your_validation_function';

I'm plugging my validation function into FeedAPI's add/edit node form. I've got a couple of CCK ImageFields planted in that form as well that I need to validate in context with the form. When I look at the dump of the form array being passed into hook_form_alter I see:

[#validate] => Array
        (
            [0] => node_form_validate
            [1] => filefield_node_form_validate
        )

Using the above approach generates:

[#validate] => Array
        (
            [0] => node_form_validate
            [1] => filefield_node_form_validate
            [2] => rsshq_node_form_validate
        )

... which is what you want. The += approach does this to that array:

[#validate] => Array
        (
            [0] => node_form_validate
            [1] => filefield_node_form_validate
            [rsshq_node_form_validate] => Array
                (
                )
        )