Hi people,

i developed a little module to generate voucher-codes out of userpoints. The user can choose how many userpoints he wants to redeem. I.e. 250, 500, 750 or 1000. To make that possible, my module (called "userpoints_redeem") has a little form with a dropdown-menue that holds the values and a submit-button. All that is shown in a block.

I implemented the following workflow: _FORM -> _VALIDATE -> _SUBMIT and everthing works fine (the feedback for the user that the transaction has happened is solved with drupal_set_message()).

Now i want to insert a confirm_form to let let the user confirm the transaction. But the confirm_form doesnt show up in the block. Means like: nothing happens.

My question: is it possible to show the confirm_form in that block? Or do i have to put that all in the page? I havent found anything on the net about it.

Thanks in advance
Fabian

Comments

Jaypan’s picture

This works for me:


function confirm_form_block_block($op = 'list', $delta = 0, $edit = array())
{
	if($op == 'list')
	{
		$block = array();
	    $block[0]["info"] = t('Confirm Form');
	    return $block;
	}
	elseif($op == 'view')
	{
		$block['subject'] = t('Confirm Form');
	    $block['content'] = drupal_get_form('confirm_form_block_form');
		return $block;
	}
}

function confirm_form_block_form($form_state)
{
	$form['item'] = array
	(
		'#type' => 'value',
		'#value' => 1,
	);
	return confirm_form($form, t('Can you see this form?'), '', t('Can you see this form?'));
}

function confirm_form_block_form_submit($form, &$form_state)
{
	$form_state['redirect'] = '';
}

The Drupal organization has shut down discussion on improvement of the forums: https://www.drupal.org/node/2536122

It's time to start a new forum somewhere else. The Drupal organization does not care about the forums.

stone_d’s picture

Hm - i got the following workflow and its definately happening nothing after i pressed the submit-button. Do you know whats wrong with it?

function userpoints_redeem_form() {

	global $user;
	$userid = $user->uid;
	$userpoints_amount = userpoints_get_current_points($userid, 45); 
	
	/* Fill the arrays for the dropdown */
	$userpoints = array('250','500','750','1000');
	$euros = array('5','15','30','50');	
	$amount = 0;
	
	/*Fill the array for the select-dropdown and disable the values that are not selectable due to less userpoints*/ 
	for($i = 0; $i <  count($userpoints); $i++) {
		$values[$userpoints[$i]] = $userpoints[$i] . " userpoints = " . $euros[$i] . " EUR";
		if($userpoints_amount < $userpoints[$i]) {
			$disabled[$i] = $userpoints[$i];
		} else {
			 
		}	
	}	
	
	/*If User has less than */
	if($userpoints_amount < $userpoints[0]) {
		$text_redeem = "Sie benötigen mindestens 250 userpoints, um einen Gutschein einzulösen";
	} else {
		$text_redeem = "Wie viele userpoints möchten Sie einlösen?";
	}	
	
	$form['userpoints_amount'] = array(
	'#type' => 'select', 
    '#title' => t($text_redeem), 
    '#values' => $values, 
    '#options' => $values, 
    '#disabled_options' => $disabled,
	);
	
	if($userpoints_amount >= $userpoints[0]) {
		$form['userpoints_amount']['#description'] = t('Wenn Sie auf "GUTSCHEIN ANFORDERN" klicken, wird Ihnen ein Gutscheincode per E-Mail zugeschickt.');
	}
	
	$form['submit'] = array(
	  '#type' => 'submit',
	  '#value' => t('Gutschein anfordern'),
	  
	);
	
	if (count($disabled) == 4) {
		$form['submit']['#disabled'] = TRUE;
	}
	
	return $form;
}

function userpoints_redeem_form_validate($form, &$form_state) {
	global $user;
	$userpoints_amount = userpoints_get_current_points($user->uid, 45); 	
	
	if($form_state['values']['userpoints_amount'] > $userpoints_amount) {
		form_set_error('userpoints_amount', t('Sie besitzen nicht genügend userpoints (= weniger als 250)'));
	}
	if($user->uid=='') {
		drupal_set_message('Ihr Benutzer konnte nicht validiert werden'); 
	}
}

function userpoints_redeem_form_confirm (&$form_state) {
  $desc = 'The following new items will be created ... your code here';
  // Tell the submit handler to process the form
  $form['process'] = array('#type' => 'hidden', '#value' => 'true');
  // Make sure the form redirects in the end
  $form['destination'] = array('#type' => 'hidden', '#value' => 'user/%user/points');

  return confirm_form($form, 'Are you sure?', 'user/%user/points', $desc, 'Continue','Start again');
}

function userpoints_redeem_form_submit($form, &$form_state) {
	$form['destination'] = array('#type' => 'hidden', '#value' => 'user/%user');		
  
	if (isset($form_state['values']['process'])) {
		drupal_set_message(t('Sie haben ' . $form_state['values']['userpoints_amount'] . ' userpoints eingelöst. Der Gutscheincode wurde Ihnen per E-Mail zugeschickt.'));
		global $user;
		$params = array(
		'uid' => $user->uid,
		'points' => -($form_state['values']['userpoints_amount']),
		'description' => "Gutscheincode: " . $vouchercode ." im Wert von " . $eur . " EUR",
		'operation' =>  $vouchercode,
		'display' => false,
		'tid' => 45,
		);
		unset($form_state['storage']);
		userpoints_userpointsapi($params);
		
		return true;
	}

	$form_state['rebuild'] = TRUE;
}

function userpoints_redeem_block($op='list', $delta=0) {
  // listing of blocks, such as on the admin/block page  
	global $user;
	$userpoints_amount = userpoints_get_current_points($user->uid, 45);
	$block_content .= "Ihr aktueller Kontostand: " . $userpoints_amount . " userpoints

"; if ($op == "list") { $block[0]["info"] = t('Userpoints redeem'); return $block; } else if ($op='view') { $block_content .= drupal_get_form('userpoints_redeem_form'); if ($block_content == '') { return; } $block['subject'] = 'Userpoints redeem'; $block['content'] = $block_content; return $block; } } // end userpoints_redeem_block
Jaypan’s picture

You aren't calling this function anywhere: userpoints_redeem_form_confirm()

The Drupal organization has shut down discussion on improvement of the forums: https://www.drupal.org/node/2536122

It's time to start a new forum somewhere else. The Drupal organization does not care about the forums.

stone_d’s picture

Thanks again ...

Well - im also not calling the _VALIDATE-function explicitly... i thought _form_confirm is a hook thats implemented automatically into the workflow after the validate-function. But maybe i was wrong in assuming this :)
So where should i return the confirm_form in my workflow?

Thanks in advance

Jaypan’s picture

_validate() and _submit() functions are automatically called by drupal_get_form(), but _confirm() isn't called (as far as I know at least - I've never seen that anywhere).

Basically, you can re-write your form function like this:

function mymodule_form($form_state)
{
  if(!isset($form_state['storage']['confirm']))
  {
    // do your normal $form definition here
    return $form;
  }
  else
  {
    // do your confirm form here
    return confirm_form($form);
  }
}

function mymodule_form_validate($form, &$form_state)
{
  if(!isset($form_state['storage']['confirm'])) 
  {
    // put any initial validation here. This only be called the first time through, not when the confirm button has been pushed.
  }
}

function mymodule_form_submit($form, &$form_state)
{
    if(!isset($form_state['storage']['confirm']))
    {
      $form_state['storage']['confirm'] = TRUE; // this will cause the form to be rebuilt, entering the confirm part of the form
    }
    else
    {
      // this is where you do your processing after they have pressed the confirm button
    }
}

The Drupal organization has shut down discussion on improvement of the forums: https://www.drupal.org/node/2536122

It's time to start a new forum somewhere else. The Drupal organization does not care about the forums.

stone_d’s picture

man - that rocks!!! Thank you very much. This code is working as i wanted it to!
Even i dunno if that the correct/best way to solve this problem, it is solved ... so ;)

Thank you very much!

916Designs’s picture

So I got your example working! Yes!

One caveat, had to add $form_state['rebuild'] = TRUE; right after setting confirm to true, otherwise the form would just reload its current state or do nothing.

So the submit function that worked for me (ignore php tag):

<?php
function mymodule_form_submit($form, &$form_state)
{
    if(!isset($form_state['storage']['confirm']))
    {
      $form_state['storage']['confirm'] = TRUE; // this will cause the form to be rebuilt, entering the confirm part of the form
      $form_state['rebuild'] = TRUE;
    }
    else
    {
      // this is where you do your processing after they have pressed the confirm button
    }
}
?>

Thank you so much for the post!