Saturday, October 19, 2013

Variable number of module configuration parameters in Drupal's hook_form

Drupal lets you define in a module a form for editing its configuration parameters but the documentation doesn't seem to explain how to do a variable number of parameters. For example, let's say you wanted to supply some fixed quotes to cycle through like a news ticker, but you wanted to let the user specify not only which quotes but how many*. But Drupal seems to require you to specify a fixed number of configuration parameters for your module.

There is an easy way around this. You can define a parameter like quote_ticker_numquotes, and set it to 6 by default:

function quote_ticker_form($form, &$form_state)
{
    $n = variable_get('quote_ticker_numquotes',6);
    if ( $n > 32 )
        $n = 32;
    elseif ( $n < 1 )
        $n = 1;
    $form['quote_ticker_numquotes'] = array(
        '#type' => 'textfield',
        '#title' => t('Number of quotes (1 to 32)'),
        '#default_value' => $n,
        '#size' => 2,
        '#maxlength' => 2,
        '#required' => TRUE
    );
    ...
}

Now, having set the number of desired quotes to $n it is a simple matter to create that many fields:

...
    for ( $i=1;$i<=$n;$i++ )
    {
        $form['quote_ticker_'.ordinal($i)] = array(
        '#type' => 'textfield',
        '#title' => t('Quote '.$i),
        '#default_value' => variable_get('quote_ticker_'.ordinal($i),
            ordinal($i).' quote <a href="">more...</a>'),
        '#size' => 64,
        '#maxlength' => 128,
        '#required' => TRUE
        );
    }
    return system_settings_form($form);
}

'ordinal' is just a simple function to turn a number into its ordinal name. Now, whenever the user changes the number of quotes the number of fields for defining quotes will expand or contract accordingly.

* The reason I decided to write a 'quote-ticker' was because news-tickers pull data from stories (nodes) whereas I wanted the quotes to be essentially fixed and to point to arbitrary URLs not just to Drupal pages.

No comments:

Post a Comment