Form & shortcode 4 - multiple forms

Multiple forms on one page with shortcodes

Earlier articles:

Form and shortcode 1 set up a subscription form saving submitted data to the database, using a custom controller and shortcode
Form and shortcode 2 - email send the subscription forms' submitted data via e-mail, using an e-mail alias via shortcode
Form and shortcode 3 - customize customize the shortcode name and arguments using a map

This article builds on the structure of the previous articles, but now makes it possible to use multiple subscriptionforms on one and the same page. Baically what we do is:

  • Use a static counter to count the forms created on the page to provide a unique id  (1, 2, 3, ...)
  • create an unique name for the form, based on the original name plus the counter
  • store the results in session using the correct form name

The Counter and the FormID

We start with a static counter that is incremented every time a new form is instantiated and the FormID is set.

In SubscriptionForm

function __construct($controller, $name, $arguments=array()) {

	$this->FormID = self::$counter++;

	$fields = singleton('Subscription')->getFrontEndFields();

	$fields->push(new HiddenField('FormID', 'FormID', $this->FormID));

	...
}

Unique form name

Next we use the FormID to create a unique name for the new form. For this we override the Form::FormName() function

In SubscriptionForm

function FormName() {
	return $this->class . '_' . 
	       str_replace(array('.','/'),'',$this->name) . 
	       $this->formID;
}

Note: I'm not sure on what the official SilverStripe approach would be on the naming issue, but I found adapting FormName() to work well: it provides for unique form names and it leaves the URL action intact. The only thing is that the form id itself is not submitted. And on submission the counter value will always be 1 for the submitted form. This doesn't hinder the submission as such, but it will display all messages on the first form, regardless. That's why the FormID value is posted with the form, so the correct FormName can be retreived...

On Submission

On form submission we need to set the FormID property based on the posted FormID, so sessionMessage() (that uses FormName()) will store the result for the right form.

In SubscriptionForm

function SubmitForm($data, $form) {

	$this->FormID = intval($data['FormID']);
	...
}

MathSpamProtection??

Yep, MathSpamProtection will work, but it stores the results without the formname, so if the wrong value is entered, the resultmessage will appear on (again) the first form.I don't know about other spamprotection modules, the module on this website needs to be updated...

@TODO

Next article: enable jQuery validation on multiple forms

Comments

Het versturen van reacties is uitgeschakeld.

RSS feed voor reacties op deze pagina