I am creating a module to perform a customised member search according to the Node Profile content types I have set up. What I imagined would be a reasonably straight forward task has had me banging my head against the wall, the desk, the keyboard, the wall... again and again. So I am hoping that someone is able to point me in the right direction as I am sure I have read every post and form doco available without finding the exact answers I'm looking for.

Below I have my code which is almost working... so so close. Obviously I'm just showing a couple of fields here for simplicity. But my troubles are as follows:

Trouble #1
-----------
Should the user select an option from the 'Gender' select box I would really like this to be selected by default again when the form is redisplayed. This works perfectly in the 'Country' textfield but I cannot for the life of me get this to work for the select box. I don't know how many different methods I've tried. The 'allowed values' set up in the CCK are as follows:

X|Not Stated
M|Male
F|Female

If I print out the $form_value['gender'] to the screen (after the form has processed) I can see the value that was selected. But how can I use this to set the default_value of the select in the form?

Trouble #2
-----------
The pager only half works and I suspect it is to do with how my form is processed and that the default values aren't carrying through as stated in #1 above. As mentioned in my code below I've set the max results per page to '1' just while I'm testing with limited data. When the form is first submitted the first result is displayed. But when I click on the next page number, the form is redisplayed with no results. However, if I was to make the same selection from the form, the second results page is then displayed.

-----------

I am so close to giving up on this Form API method completely and using plain old PHP in a standalone file to get this running, but I would really like to do this properly.

If anyone is able to lend their advice I would be most grateful.

Cheers.

//-----------------------------------------------------------------------------
// Member Search :: Help
function member_search_help($section='') {
  $output = "";
  switch ($section) {
    case "admin/help#member_search":
      $output = t("<p>Detailed instructions on using the Member Search module to go here.</p>");
      break;
  }
  return $output;
}

//-----------------------------------------------------------------------------
// Member Search :: Perm
function member_search_perm() {
  return array('search member profiles');
}

//-----------------------------------------------------------------------------
// Member Search :: Menu
function member_search_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'member_search',
      'title' => t('Member Search'),
      'description' => t('Search other member\'s profiles.'),
      'callback' => 'member_search',
      'access' => user_access('search member profiles'),
	  'type' => MENU_NORMAL_ITEM,
	);

  } 
  return $items;
}

//-----------------------------------------------------------------------------
// Member Search
function member_search() {
	return drupal_get_form('member_search_form');
}

//-----------------------------------------------------------------------------
// Member Search :: Form
function member_search_form($form_values=NULL) {

	// ---------------------------------
	// Country
	$form['country'] = array(
		'#type' => 'textfield', 
		'#title' => t('Country'), 
		'#default_value' =>  variable_get('country', ''),	// ### This places entered value in form when redisplayed
		'#size' => 60, 
		'#maxlength' => 75, 
	);

	// ---------------------------------
	// Gender
	$allowed_values = array();
	$result = db_query("SELECT global_settings FROM {node_field} WHERE field_name='%s'", 'field_profile_gender');
	while ( $info = db_fetch_object($result) ) {
		$settings = unserialize($info->global_settings);
		$allowed_values = $settings['allowed_values'];
	}
	$allowed_values = split("\r", $allowed_values);

	$options = array('-'=>'---');
	foreach ($allowed_values as $option) {
		$opt_array = explode('|', $option);
		$options[$opt_array[0]] = t($opt_array[1]);
	}

	$form['gender'] = array(
		'#type' => 'select', 
		'#title' => t('Gender'), 
		'#default_value' => variable_get('gender', '-'),	// ### This does not set the value of the select field
		'#options' => $options, 
		'#DANGEROUS_SKIP_CHECK'=>true,						// ### Otherwise form returns 'illegal choice' error
	);

	$form['op'] = array(
		'#type' => 'submit',
		'#value' => t('Submit'),
	);

	$form['#multistep'] = TRUE;
	$form['#redirect'] = FALSE;

	if ( $form_values != NULL ) {
		// Show results from form
		$results = $form_values['country'] . ' :: ' . $form_values['gender'] . '<BR /><BR />';
		$results .= _get_search_results($form_values);

		$form['results'] = array(
		  '#type' => 'item',
		  '#title' => t('Search Results'),
		  '#value' => $results,
		);

	}
	return $form;
}

//-----------------------------------------------------------------------------
// Member Search Form :: Submit
function member_search_form_submit($form_id, $form_values) {
	return FALSE;	// do not redirect, just display the page
}

//-----------------------------------------------------------------------------
// Member Search Form :: Theme
function theme_member_search_form(&$form) {
	$output = drupal_render_form($form['#id'], $form);
	return $output;
}

//-----------------------------------------------------------------------------
// Get Search Results
function _get_search_results($form_values) {
	$results = '';

	// ------------------------------------------
	// Build the search query
	$vCount			= "SELECT count(DISTINCT u.uid) FROM {users} u INNER JOIN {node} n1 ON u.uid=n1.uid";
	$vSelect		= "SELECT DISTINCT u.uid FROM {users} u INNER JOIN {node} n1 ON u.uid=n1.uid";
	$vJoin			= '';
	$vWhere			= " WHERE u.status>0";

	// --------------------------------
	// Country
	if ( isset($form_values['country']) && $form_values['country']!='-' ) {
		$vCountry	= $form_values['country'];
		$vJoin .= " INNER JOIN {content_field_profile_country} c ON n1.nid=c.nid";
		$vJoin .= " AND c.field_profile_country_value='$vCountry'";
	}

	// --------------------------------
	// Gender
	if ( isset($form_values['gender']) && $form_values['gender']!='-' ) {
		$vGender	= $form_values['gender'];
		$vJoin .= " INNER JOIN {content_field_profile_gender} gen ON n1.nid=gen.nid";
		$vJoin .= " AND gen.field_profile_gender_value='$vGender'";
	}

	// --------------------------------
	$vSelect	.= $vJoin . $vWhere;
	$vCount		.= $vJoin . $vWhere;

	$num_per_page = 1;		// ### Just for testing with limited number of test users in database
	$result = pager_query($vSelect, $num_per_page, 0, $vCount, $user_load->uid);

	$output = '<div id="profile">';
	while ($account = db_fetch_object($result)) {
		$account = user_load(array('uid' => $account->uid));
		$output .= theme('username', $account);
		$output .= '<BR />-----<BR />';
	}
	$output .= '</div>';
	$output .= theme('pager', NULL, 1, 0);

	return $output;
}

Comments

nevets’s picture

I would expect this code

 '#default_value' => variable_get('gender', '-'), // ### This does not set the value of the select field

to look something like

 '#default_value' => (isset($form_values['gender']) ? $form_values['gender'] : '-'),

In general if you want to carry forward the last selection I would expected to see $form_values uses and not variable_get() which gets a value stored in the database and is not specific to the current user but the same for all users.

webbasics’s picture

Hi Nevets,

Thanks for a speedy reply. Unfortunately that is one of the many different methods I tried. Just to try and get a result I even tried setting it with hard coded values e.g.

  '#default_value' => array('M'=>'Male'),

  '#default_value' => 'M|Male',

  '#default_value' => 'M',

  '#default_value' => 'Male',

  '#default_value' => 2,    // thought this might set the 3rd option in field array

I even tried something similar to what you see in this post http://drupal.org/node/170238

If I 'print_r' the actual '$form' I can see the default value has been set (in most cases, depending what method was used), but it does not result in the correct value being set in the field itself :(

Cheers.

nevets’s picture

Look at the $options variable, it should have keys like 'M' and values like 'Male'.

zetxek’s picture

I'm having the same problem. I'm using a select box in a custom content form, but there is no way I can make the default_value of a select form work...

When I modify it and print the $form with print_r, I see the default_value has been changed, but I always see the select box in the same way.

Probably I'm doing it wrong (as you probably do too), but I couldn't find any working example of how to change it, neither in the forums or in the API...

Does anybody have a clue?

heine’s picture

First of all, only use options that are in the optiions array as default_value, that way, you don't get validation errors.

Here's some complete sample code you can use to experiment with #default_value, just save as test.module, make a test.info with appropriate name and description, enable the module and visit test/form-select-default.

Of course, normally, you'd fetch the default_value from the database for a specific user.


function test_menu($maycache) {
   if ($maycache) {
     $items[] = array(
       'path' => 'test/form-select-default',
       'callback' => 'drupal_get_form',
       'callback arguments' => array('test_form_select_default_form'),
       'access' => TRUE,
       'type' => MENU_CALLBACK,
     );
     return $items;
   }
}

function test_form_select_default_form() {
  $form = array();

  $gender_options = array(
    'U' => t("Won't say"),
    'F' => t('Female'),
    'M' => t('Male'),
  );

  $form['gender'] = array(
    '#type' => 'select',
    '#title' => t('Gender'),
    '#options' => $gender_options,
    '#default_value' => 'F',
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  return $form;
}

function test_form_select_default_form_submit($form_id, $form_values) {
  // TODO: Remove debugging code.
  drupal_set_message('<pre>'. check_plain(print_r($form_values, TRUE)) .'</pre>');
}

--
The Manual | Troubleshooting FAQ | Tips for posting | How to report a security issue.

webbasics’s picture

Okay, so the form works if I build the options array manually as shown in test_form above as provided by Heine. But not when I build the options from the data collected from the database. I have tried the following:

// you can see where 'allowed_values' comes from in my first post
$options = array('-'=>'');
foreach ($allowed_values as $option) {
  $opt_array = explode('|', $option);
  $options[$opt_array[0]] = $opt_array[1];
}

and

$options = array('-'=>'');
foreach ($allowed_values as $option) {
  $token = strpos($option, '|');
  $key = substr($option, 0, $token);
  $value = substr($option, $token+1);
  $options[$key] = $value;
}

I have also tried the above examples using t(), e.g. 't($key)', 't($value)' etc.

Thanks again for any input anyone can provide.

Cheers.