Creating forms that don't resubmit in Kohana

30 Mar 2011

It is definitely one of my pet peeves: reloading a page only to see the "Confirm Form Resubmission" alert box that wants me to find my mouse and click on something that could have easily been prevented by the developer.  This is 2011, for crying out loud, can't we have forms that don't suck?

The easiest solution to this problem is to load all posted form data into the session, and then reload the page internally.  This clears the POST request while maintaining the submission and makes for happier users (and less headaches about the same comment submitted 14 times in a row).

Using Kohana's Session class makes it even simpler to remedy this ill of the internet.  It really does not matter which driver you use, simply create a session and drop in the submission.  The following controller action demonstrates the basics of this feature:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Form extends Controller {

	public function action_test()
	{
		$session = Session::instance();

		$example = new Model_Example;

		$this->template->content = View::factory('form/test')
			->bind('post', $post)
			->bind('errors', $errors);

		if ($_POST)
		{

			$post = $example->validate($_POST);

			if ($post->check())
			{
				// Process Form
				$this->session->set('post', array());
				Request::instance()->redirect(url::site('somewhere'));
			}
			else
			{
				$this->session->set('errors', $e->errors());
				$this->session->set('post', $_POST);
				Request::instance()->redirect(url::site('back-here'));
			}
		}
		elseif ($this->session->get('post'))
		{
			$_POST = $this->session->get('post');
			$errors = $this->session->get('errors');
			$this->session->delete('post');
			$this->session->delete('errors');
		}
	}
}

Now a simple view script with a form is all that is needed to complete this exercise. Although this is really just pseudo-code, I hope you get the idea.

To see this in action, fill out the comment section below, but leave the email input blank.  The form will have errors, the messages will be displayed, the from will remain sticky (you other data will persist), but a refresh of the page will not show any resubmission warnings.  Hopefully, this makes you a happier user. If not, let me know by commenting below, and feel free to ask any questions.

Comments (2)
These comments are frozen, as they are archived from my previous blog.

gravatar
kemo
about a year ago

I like the way of writting but there's a catch with the session key you're using: you should point users to use the actual form's name for it so that they can still normally use other forms after validation in this one fails (example).

gravatar
JDStraughan
about a year ago

@kemo: That is a very good point. I named the session 'post' key as it is really just psuedo-code, and wanted people to understand the concept. I agree that in a real world scenario the session keys should be unique to the form being used.