Hello all,

I use the following function in my custom module which gives me a table where one can select a favourite colour. It actually works well:
http://www.selimoezkan.com/files/images/snap_2.jpg

The only thing: How can I put the selected attribute to the according option-Tag after submitting the form, so that the selected value keeps selected.

This is the code:

function theme_colour_radios($variables) {
    global $colours;
    $counter = 0;
    $element = $variables['element'];
    $output = '<tr>';
    foreach ($element['#options'] as $option => $value) {
        $counter++;
        $output .= '<td style="width: 57px; text-align: center; background-color: #'.$colours[$option].';">';
        $output .= drupal_render($element[$option]);
        $output = preg_replace('/\>[0-9a-fA-F ]+\<\/label\>/', '></label>', $output);
        $output = preg_replace('/name\="favouritecolour" value\="[0-9]+"/', 'name="favouritecolour" value="#'.$colours[$option].'"', $output);
        if($counter % 12 == 0) $output .= '</tr><tr>';
    }
    $output .= '</tr>';
    return $output;
}

Many thanks for help.

Best wishes
Soezkan

Comments

jaypan’s picture

It will happen in your form definition, not your form theme. What does your form definition look like?

Contact me to contract me for D7 -> D10/11 migrations.

selimoezkan’s picture

Hi Jaypan,

this is my .module:

/**
 * Add module's own CSS
 */
function personality_add_css() {
	$pathtomodule = drupal_get_path('module', 'personality');
	$csspath = $pathtomodule.'/css/personality.css';

    if (isset($csspath)) {
    	drupal_add_css ($csspath, array('type' => 'file'));
	}
}


/**
 * Implements hook_init
 */
function personality_init() {
	personality_add_css();
}


/** 
 * Implements hook_permission
 */
function personality_permission() {
    return array(
		'use personality calculation' => array(
			'title' => t('personality'),
			'description' => t('Allow users to use the personality calculations.'),
		),
	);
}


/**
 * Implements hook_menu
 */
function personality_menu() {
    $items = array();
    $items['evocations/personality'] = array(
        'title' => 'personality',
        'type' => MENU_NORMAL_ITEM,
        'access arguments' => array('use personality calculation'),
        'page callback' => 'drupal_get_form',
        'page arguments' => array('personality_form'),
    );
    return $items;
}

/**
 * Implements hook_theme
 */
function personality_theme() {
      return array(
         'colour_radios' => array(
             'render element' => 'element'
         ),
    );
}

/**
 * Implements a form
 */
function personality_form($form, &$form_state) {
	global $colours, $base_url, $rating;

	$form = array();

	$form['personalitytest'] = array(
		'#title' => t('Your personal data'),
		'#type' => 'fieldset',
		'#collapsible' => TRUE,
		'#collapsed' => FALSE
	);

	/* ABOUT YOU */
	/* NAME, EMAIL, GENDER */
	$form['personalitytest']['aboutyou'] = array(
		'#title' => t('About you'),
		'#type' => 'fieldset',
		'#description' => t('The following data is required in order to determine your personality-conditions.'),
		'#collapsible' => TRUE,
		'#collapsed' => FALSE
	);
	
    $form['personalitytest']['aboutyou']['firstname'] = array(
		'#prefix' => '<p>',
		'#suffix' => '</p>',
        '#type' => 'textfield',
        '#title' => t('First name'),
        '#size' => 20,
        '#maxlength' => 50,
    );
	
    $form['personalitytest']['aboutyou']['lastname'] = array(
		'#prefix' => '<p>',
		'#suffix' => '</p>',
        '#type' => 'textfield',
        '#title' => t('Last name'),
        '#size' => 20,
        '#maxlength' => 50,
    );

    $form['personalitytest']['aboutyou']['email'] = array(
		'#prefix' => '<p>',
		'#suffix' => '</p>',
        '#type' => 'textfield',
        '#title' => t('Email'),
        '#size' => 20,
        '#maxlength' => 50,
    );

    $form['personalitytest']['aboutyou']['gender'] = array(
		'#prefix' => '<p>',
		'#suffix' => '</p>',
        '#type' => 'radios',
        '#title' => t('Gender'),
        '#options' => array(
			'female' => t('female'),
			'male' => t('male'),
		),
		'#default_value' => 'female',
    );
	
	/* BIRTHDATE */
    $form['personalitytest']['aboutyou']['birthdate'] = array(
		'#prefix' => '<p>',
		'#suffix' => '</p>',
        '#type' => 'fieldset',
		'#description' => t('Your date of birth.'),
		'#collapsible' => FALSE
    );	
    $form['personalitytest']['aboutyou']['birthdate']['birthday'] = array(
		'#prefix' => '<div style="float: left; padding: 0 20px 0 0">',
		'#suffix' => '</div>',
        '#type' => 'textfield',
        '#title' => t('Day of birth'),
        '#size' => 2,
        '#maxlength' => 2,
    );
    $form['personalitytest']['aboutyou']['birthdate']['birthmonth'] = array(
		'#prefix' => '<div style="float: left; padding: 0 20px 0 0">',
		'#suffix' => '</div>',
        '#type' => 'textfield',
        '#title' => t('Month of birth'),
        '#size' => 2,
        '#maxlength' => 2,
    );
    $form['personalitytest']['aboutyou']['birthdate']['birthyear'] = array(
		'#prefix' => '<div style="margin: 0 0 0 0">',
		'#suffix' => '</div>',
        '#type' => 'textfield',
        '#title' => t('Year of birth'),
        '#size' => 4,
        '#maxlength' => 4,
    );

	/* FAVOURITE COLOUR */
	$form['personalitytest']['aboutyou']['colours'] = array(
		'#title' => t('Your most favourite colour'),
		'#prefix' => '<p>',
		'#suffix' => '</p>',
        '#type' => 'fieldset',
		'#collapsible' => TRUE,
		'#collapsed' => FALSE
    );	
    $form['personalitytest']['aboutyou']['colours']['favouritecolour'] = array(
		'#prefix' => '<table cellpadding="4" cellspacing="3"><tbody>',
		'#suffix' => '</tbody></table>',
        '#type' => 'radios',
        '#options' => $colours,
		'#theme' => 'colour_radios',
		'#validated' => TRUE
    );
	
	/* Submission */
	$form['personalitytest']['submit'] = array(
		'#prefix' => '<div style="clear: both">',
		'#suffix' => '</div>',
        '#type' => 'submit',
        '#value' => t('Evaluate')
    );	

    if( isset($form_state['storage']['firstname']) &&
    	isset($form_state['storage']['lastname']) &&
    	isset($form_state['storage']['email']) &&
    	isset($form_state['storage']['gender']) &&
    	isset($form_state['storage']['birthmonth']) &&
    	isset($form_state['storage']['birthyear']) &&
    	isset($form_state['storage']['birthday']) &&
    	isset($form_state['storage']['favouritecolour'])) {

		// Equalize form submission values
		include('includes/form-submission-values.inc.php');

		// Output data
		include('includes/personality-output.inc.php');
    }

    return $form;
}


/**
 * Validation handler for the birthday_numerology_form
 */
function personality_form_validate($form, &$form_state) {
	
	$validator_boolean = TRUE;
	
	$firstname = $form_state['values']['firstname'];
	$lastname = $form_state['values']['lastname'];
	$email = $form_state['values']['email'];
	
	if (empty($firstname)) {
		form_set_error('firstname', t('Please indicate your first name'));
        $validator_boolean = FALSE;
	}

	if (empty($lastname)) {
		form_set_error('lastname', t('Please indicate your last name'));
        $validator_boolean = FALSE;
	}
	
	if (empty($email)) {
		form_set_error('email', t('Please indicate your email'));
        $validator_boolean = FALSE;
	}
	else if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
		form_set_error('email', t('Your email is not correct'));
        $validator_boolean = FALSE;
	}
	
	$day = $form_state['values']['birthday'];
	$month = $form_state['values']['birthmonth'];
	$year = $form_state['values']['birthyear'];
	
	if (($day < 1) || ($day > 31)) {
		form_set_error('birthday', t('The days of a month have to be in the range of 1 to 31!'));
        $validator_boolean = FALSE;
	}
	elseif(empty($day)) {
		form_set_error('birthday', t('Please enter your day of birth!'));
        $validator_boolean = FALSE;
	}

	if (($month < 1) || ($month > 12)) {
		form_set_error('birthmonth', t('The month has to be in the range of 1 to 12!'));
        $validator_boolean = FALSE;
	}
	elseif(empty($month)) {
		form_set_error('birthmonth', t('Please enter your month of birth!'));
        $validator_boolean = FALSE;
	}

	if (($day > 30) && (($month == 4) || ($month == 6) || ($month == 9) || ($month == 11))) {
		form_set_error('birthday', t('The @month hasn\'t so many days!', array('@month'=>$monthnames[$month])));
        $validator_boolean = FALSE;
	}  

	if (($day > 29) && ($month == 2)) {
		form_set_error('birthday', t('February hasn\'t so many days!'));
        $validator_boolean = FALSE;
	}  

	if (($day == 29) && ($month == 2) && !(($year % 400) == 0 || (($year % 4) == 0 && ($year % 100) != 0))) {
		form_set_error('birthday', t('February has only 28 days in this year!'));
        $validator_boolean = FALSE;
	}  	
	
    if (empty($year) || $year < 1) {
        form_set_error('birthyear', t('You must enter a value for the year.'));
        $validator_boolean = FALSE;
    }
	
	$favouritecolour = $form_state['values']['favouritecolour'];
	if (empty($favouritecolour)) {
		form_set_error('favouritecolour', t('Please select your most favourite colour'));
		$validator_boolean = FALSE;
	}
	
    return $validator_boolean;
}


/*
 * Theme Output
 */
function theme_colour_radios($variables) {
	global $colours;
	$counter = 0;

    $element = $variables['element'];
    $output = '<tr>';
    foreach ($element['#options'] as $option => $value) {
    	$counter++;

        $output .= '<td style="width: 57px; text-align: center; background-color: #'.$colours[$option].';">';
        $output .= drupal_render($element[$option]);
		$output = preg_replace('/\>[0-9a-fA-F ]+\<\/label\>/', '></label>', $output);

		$output = preg_replace('/name\=\"favouritecolour\" value\=\"[0-9]+\"/', 'name="favouritecolour" value="'.$colours[$option].'"', $output);
		if($counter % 12 == 0) $output .= '</tr><tr>';
    }
    $output .= '</tr>';
    return $output;
}


/**
 * Submission handler for the personality_form
 */
function personality_form_submit($form, &$form_state) {
	
    // First we save the submitted data to $form_state['storage']
    $form_state['storage']['firstname'] = $form_state['values']['firstname'];
	$form_state['storage']['lastname'] = $form_state['values']['lastname'];
    $form_state['storage']['gender'] = $form_state['values']['gender'];
	$form_state['storage']['birthmonth'] = $form_state['values']['birthmonth'];
	$form_state['storage']['birthyear'] = $form_state['values']['birthyear'];
    $form_state['storage']['birthday'] = $form_state['values']['birthday'];
	$form_state['storage']['email'] = $form_state['values']['email'];
	$form_state['storage']['favouritecolour'] = $form_state['values']['favouritecolour'];

    // Then we set $form_state['rebuild'] to TRUE, so that the values stored in
    // $form_state['storage'] are available in the form definition.
    $form_state['rebuild'] = TRUE;
}

Do I have to touch personality_form($form, &$form_state)?

Many thanks
Soezkan

jaypan’s picture

Add this:

        '#default_value' => isset($form_state['storage']['favouritecolor']) ? $form_state['storage']['favouritecolor'] : FALSE,

To this:

$form['personalitytest']['aboutyou']['colours']['favouritecolour'] = array(
        '#prefix' => '<table cellpadding="4" cellspacing="3"><tbody>',
        '#suffix' => '</tbody></table>',
        '#type' => 'radios',
        '#options' => $colours,
        '#theme' => 'colour_radios',
        '#validated' => TRUE
    );

Then add this to your submit function:

$form_state['storage']['favouritecolor'] = $form_state['values']['favouritecolor'];
$form_state['rebuild'] = TRUE;

Contact me to contract me for D7 -> D10/11 migrations.

selimoezkan’s picture

Thanks. But it doesn't seem to work yet.

This is what I have changed in my function personality_form($form, &$form_state) :

...
    $form['chakratest']['aboutyou']['colours']['favouritecolour'] = array(
		'#prefix' => '<table cellpadding="4" cellspacing="3"><tbody>',
		'#suffix' => '</tbody></table>',
        '#type' => 'radios',
        '#options' => $colours,
		'#theme' => 'colour_radios',
		'#validated' => TRUE,
		'#default_value' => isset($form_state['storage']['favouritecolour']) ? $form_state['storage']['favouritecolour'] : FALSE,
    );
...

This was already in my submit function:

$form_state['storage']['favouritecolour'] = $form_state['values']['favouritecolour'];
$form_state['rebuild'] = TRUE;

Any ideas?

I found that even if "hard coded" like:

...
    $form['chakratest']['aboutyou']['colours']['favouritecolour'] = array(
		'#prefix' => '<table cellpadding="4" cellspacing="3"><tbody>',
		'#suffix' => '</tbody></table>',
        '#type' => 'radios',
        '#options' => $colours,
		'#theme' => 'colour_radios',
		'#validated' => TRUE,
		'#default_value' => 'c3680f'
    );
...

It remains without a selected one.

Mayn thanks
Soezkan

jaypan’s picture

What is in $colors?

Contact me to contract me for D7 -> D10/11 migrations.

selimoezkan’s picture

In the $colours array are all the hexdec colours for the table selector:

global $colours;
$colours = array(
	'c9db6d',
	'd0cf13',
	'c3680f',
	'bd2112',
...
	'808080',
	'999999',
	'b3b3b3',
	'cccccc',
	'e5e5e5',
	'ffffff',
);

Just found that the "problem" can be solved the dirty way like this:

function theme_colour_radios($variables) {
	global $colours;
	$counter = 0;

    $element = $variables['element'];
    $output = '<tr>';
    foreach ($element['#options'] as $option => $value) {
    	$counter++;

        $output .= '<td style="width: 57px; text-align: center; background-color: #'.$colours[$option].';">';
        $output .= drupal_render($element[$option]);
		$output = preg_replace('/\>[0-9a-fA-F ]+\<\/label\>/', '></label>', $output);

		if($_POST['favouritecolour']==$colours[$option]) $selected = ' checked="checked"';

		else $selected = '';
		$output = preg_replace('/name\=\"favouritecolour\" value\=\"[0-9]+\"/', 'name="favouritecolour" '.$selected.' value="'.$colours[$option].'"', $output);
		if($counter % 12 == 0) $output .= '</tr><tr>';
    }
    $output .= '</tr>';
    return $output;
}

Added the ...

if($_POST['favouritecolour']==$colours[$option]) $selected = ' checked="checked"';

... in the function theme_colour_radios.

There is probably a more coherent way to do this. But it seems to work.

Many thanks
Soezkan