I've been hunting for a good example of how to build a confirmation form from my module, but the Examples module doesn't use it, and the samples I've found from D7 aren't making sense.  

I'm doing this:

if (backdrop_get_form('modulename_status_confirm', $node)){

and

function modulename_status_confirm($form, $form_state, $node) {

$form['#node'] = $node;

$path = $_SESSION['vhb_status_destination'] ;

$path= '/home';

$ret= confirm_form(

$form,

t('Are you sure you want to change the status on %node-title?', array('%node-title' => $node->title)),

$path,

t('This action can be undone.'),

t('Save'),

t('Cancel'),

t('Change status')

);

return $ret;

}

The form fails to render as far as it's buttons are concerned, though the title renders.

Accepted answer

Looking at the gist you created, I see the following problems:

1. You are calling backdrop_get_form('vhb_status_confirm', $node), but you are never returning the form array for rendering. The important bit here is that, if you want to display the form, you MUST return the form array, so that Backdrop can render it

2. Second problem: you are still using backdrop_get_form within an if statement. This will never work. backdrop_get_form returns an array, which will ALWAYS be evaluated as true if you have it inside an if statement. From what you say before, you are trying to check whether the user confirmed or canceled. This can't be done by putting backdrop_get_form inside an if statement. 

I still see problem #2 in the second code you posted above.

So, the correct way to do this is:

1. Use backdrop_get_form in the menu callback (as you have in the second posting). But please notice you CAN pass additional parameters as you were doing before.

2. To check if the user confirmed or canceled you must do that in the submit handler. You can't use an if statement in the form builder to check for that. This will never work. The user will confirm or cancel during an additional page request, where the form will be shown to the user, who then will click confirm or cancel, producing a third page request. By then the if statement is far gone. 

There are special techniques to pass parameters between page requests, for example, to assure that the submit handler receives the parameters you first sent to the form builder. You must use $form_state to store these parameters. $form_state is PERSISTENT among page requests that deal with the same form.

In a nutshell, this is what it would look like:

https://gist.github.com/argiepiano/c9ac414e3874331f875c7cc057975637

Take a look and let me now if you have any questions.

 

Comments

The checking about whether the user confirmed is done in the submit handler for the form. What you are doing (that if statement on top) is wrong.The example I posted above doesn't provide code for the submit handler, but you can be sure that, if the submit handler was invoked, the user confirmed. When the user cancels, that handler is not invoked.

Thanks, but I am not getting any submit buttons at all. So nothing to handle. Only the title appears. I've checked for form_alter removal, and CSS removal, they are not in the output html.

How are you accessing the form? Can you post the menu item in your module's hook_menu() that calls the form?



$menu['node/%/edit/status/%'] = array(

'page callback' => 'modulename_status_change',

'access callback' => 'modulename_access_callback',

'page arguments' => array(1, 4),

);

return $menu;

is the hook_menu, which is activated from a link out of a view.

So the view throws a table out, where one of the fields is a drop-down of the status change link as per the menu above. The link fires off fine, goes to the page where the confirmation form is supposed to show, renders the confirmation form's title, and then finishes the rest of the normal template of the page.

 

The submit and cancel button seem to be there in the form definition:

I'm not getting the full picture of what you are trying to accomplish.

There are mostly two ways to render functioning forms in Backdrop. I think the problem you are facing is that you probably are not using either way correctly.

1. You can define a menu item with a 'page callback' => 'backdrop_get_form' and a 'page argument' => array('my_form_builder_function', ... ). The form builder will receive parameters $form and $form_state, plus any other parameters you send in the array for 'page arguments'

2. You COULD avoid using backdrop_get_form in the menu item definition, and instead build the form within a "regular" page callback. It seems to me this is what you are trying to do. 

However, a confirm form should pretty much always use #1 above. The code you pasted doesn't do that. I'm not sure why you chose not to use backdrop_get_form as the page callback.

It's hard to help without actually fully seeing what you are trying to do. Any chance you can visit the Wednesday office hours? This is the most efficient way to solve complex problems like this one.

 

 

Here's another thought. Can you create a public "gist" on github or somewhere else, and post just the code for hook_menu() (which you posted above) AND the full callback function? And then post the link to the gist here...

That will help me see what you are trying to accomplish.

Thanks, I think I have solved it...I was overloading some bits, underloading others...

 $menu['node/%/edit/status/%'] = array(

    'page callback' => 'backdrop_get_form',
    
    'access callback' => 'mymodule_access_callback',
    
    'page arguments' => array('mymodule_status_change',1, 4),
    
    );
    
    return $menu;
}
function mymodule_status_change($form, &$form_state){
    // enable a change in status by hitting the right URL with the right privileges
    //  /node/7956/edit/status/515
    if (null!==arg(1)) { $nid=arg(1);}
    if (null!==arg(4)) { $status=arg(4);}
   
    // dpm($status);
    global $user;
  
    $rolevar=mymodule_rolevar($user);
    if ( $rolevar > 1  && is_numeric(($status))){

      $_SESSION['mymodule_status_destination'] = $_SERVER['HTTP_REFERER'];
        
     
          $termname='';
          $term= taxonomy_term_load($status);
          if(isset($term->name)){ $termname = $term->name; }
          
          $node=node_load($nid);

          $node->field_status['und'][0]['tid'] = $status;
         
          // also new note added here
          // get the vars for the NOTE to build
      $note=array();
      $note['content_type']='Application';
      $note['mode']='Update';
      $uid=0;
      global $user;
      if(isset($user->uid)){
        $note['user_link']=$uid;
      }
      $nid=field_get_value($node, 'field_opening', 'target_id');
      if(isset($nid)){
        $note['content_link']=$nid;
      }
      if(isset($org) && $org !='0'){
        $note['org']=$org;
      }
      $note['notetext']="Application :".$node->title;
      if ($form=backdrop_get_form('mymodule_status_confirm', $node)){

The important parts being the irrelevancy of the 1,4 in the arguments of the menu entry, but picking them from the page call later, and $form=backdrop_get_form('mymodule_status_confirm' which gets the confirm_form to do it's thing. Now off to check that the logic flows through...

Looking at the gist you created, I see the following problems:

1. You are calling backdrop_get_form('vhb_status_confirm', $node), but you are never returning the form array for rendering. The important bit here is that, if you want to display the form, you MUST return the form array, so that Backdrop can render it

2. Second problem: you are still using backdrop_get_form within an if statement. This will never work. backdrop_get_form returns an array, which will ALWAYS be evaluated as true if you have it inside an if statement. From what you say before, you are trying to check whether the user confirmed or canceled. This can't be done by putting backdrop_get_form inside an if statement. 

I still see problem #2 in the second code you posted above.

So, the correct way to do this is:

1. Use backdrop_get_form in the menu callback (as you have in the second posting). But please notice you CAN pass additional parameters as you were doing before.

2. To check if the user confirmed or canceled you must do that in the submit handler. You can't use an if statement in the form builder to check for that. This will never work. The user will confirm or cancel during an additional page request, where the form will be shown to the user, who then will click confirm or cancel, producing a third page request. By then the if statement is far gone. 

There are special techniques to pass parameters between page requests, for example, to assure that the submit handler receives the parameters you first sent to the form builder. You must use $form_state to store these parameters. $form_state is PERSISTENT among page requests that deal with the same form.

In a nutshell, this is what it would look like:

https://gist.github.com/argiepiano/c9ac414e3874331f875c7cc057975637

Take a look and let me now if you have any questions.