3

I'm using the form_declaration() function in a module, and I fire a method when the form is submitted. I set the form's action to loop back to the sender so I can do some form validation serverside.

When I submit the form, the desired function fires, but the page content doesn't load. I can retrieve the POST data and call other functions to do checks on the data. Unfortunately the original page content doesn't load. I have nowhere to write where the user went wrong.

Of course I could echo out where the user went wrong, but I want the messages to appear next to the erring fields.

Below is my code and example output:

EE Form

{exp:database_add:form}
    <input class="text_box" type="text" name="username" id="username" />
    <input class="text_box" type="password" name="password" id="password" />
    <input type="submit" name="submit_button" value="Register" />
{/exp:database_add:form}

The form function to make the above code make sense in ExpressionEngine

function form(){
    $form_details = array(
        'action'        => '/expression_engine_practice/index.php/home/registration/',
        'hidden_fields' => array(
            'ACT' => ee()->functions->fetch_action_id('Database_add', 'register')
        )
    );

    $return_data = ee()->functions->form_declaration($form_details);
    $return_data .= ee()->TMPL->tagdata;
    $return_data .= '</form>';
    return $return_data;
}

The function that I want to fire (it does as is demonstrated by the example output to follow)

function register(){
    $username = $_POST['username'];
    $password = $_POST['password'];

    echo "Username: $username<br />";
    echo "Password: $password<br />";

    $data = array(
        'User_ID'       =>null,
        'User_Name'     =>$username,
        'User_Passhash' =>$password
    );
    $query = ee()->db->insert('exp_user', $data);

    //Prints out the contents of the table.
    $query = ee()->db->get('exp_user');
    foreach($query->result() as $row){
        echo "ID: $row->User_ID -- $row->User_Name -- $row->User_Passhash<br/>";
    }
}

Output generated from register() - I entered "happy" and "gilmore"

Username: gilmore
Password: happy
ID: 45 -- pizza -- icecream
ID: 46 -- napkins -- paper towels
ID: 47 -- google -- facebook
ID: 48 -- lafferty -- daniel
ID: 49 -- gilmore -- happy

I checked the form action after it renders. The action is "/expression_engine_practice/index.php/home/registration" which is exactly the name of the page the form is sent from. The desired function fires and tasks are completed.

Why doesn't the content of the 'registration' page load again after postback?

Secondary question that will also help me close this issue.

How do I do form validation through a module? I want the text of any errors found in the form to be displayed in the form page after a postback.

  • I'm still stuck on this issue. The purpose of this question is to learn form validation. My background is PHP, and I learned quickly that my previous server-side form validation techniques don't work the same way in EE. – John G Sep 13 '13 at 14:27
4

This is far from obvious how to achieve in EE, and it's not really documented at all. A long while ago I wrote up on Stack Overflow how we (used to) do this in Store, and this was in turn based on how SafeCracker (now Channel Form) did it. However, I've since figured out an even cleaner way to achieve it (Channel Form, FreeMember, and many other add-ons use this new pattern).

Without writing a 3 page answer it's hard to describe it completely. I suggest reading through the FreeMember module source code to get an idea for how this works.

The basic concept is to handle the form submission using an action (as usual), and if there are any errors then make a note of them in a static variable (so you can access them later in the page load). Finally, call ee()->core->generate_page();, which will let EE resume the page load. When EE's parser gets down to your template tag, you can check for the existence of inline errors, and output them as variables to display in your template.

You must also be sure that your original form simply posts to the current page, not a index.php?ACT=123 style URL. As long as an ACT parameter is part of the POST array, your action will still be called (EE allows the ACT parameter to passed via either POST or GET, it doesn't matter). This allows EE to continue rendering the correct page when you call ee()->core->generate_page();. In Store we achieve this by simply leaving the HTML form action="" parameter out entirely, as this is valid HTML5 and all browsers treat it as "post to the current page".

This method is a little convoluted, but it gives the designer maximum flexibility over how to display your module's error messages.

  • Thank you so much! After a week of no response and no votes, I was about to give up on this. Adding the 'ee()->core->generate_page();' call at the very end of my register() method accomplished exactly what I was trying to do! I haven't tried this yet, but I'm positive your static variable solution for errors will work splendidly. You've helped me a lot, and I'm sure this will be useful to others who have this same issue. – John G Sep 16 '13 at 12:47
  • No problem :) Glad it helped. – Adrian Macneil Sep 16 '13 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.