Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Archive /

Our old forums are still available as a read-only archive.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo

Custom Forms and Errors


Go to End


9 Posts   3739 Views

Avatar
StuM

Community Member, 59 Posts

29 August 2008 at 5:28pm

Hi all,

I'm currently building my first SS site and have came up against a problem with the forms.

I've created a custom form, and it renders ok.

The controller is RegistrationPage_Controller. I create the form and name it RegForm.

I created a basic class RegistrationForm which extends Form, and is pretty much c&p'd from here: http://doc.silverstripe.com/doku.php?id=form#using_a_custom_template - except the constructor is just:

public function __construct($controller, $name, $fields, $actions)
{
	parent::__construct($controller, $name, $fields, $actions);
}

All of the field names then have ids RegistrationForm_RegForm_<field_name> which looks as it should, and it submits to RegForm.

So I've created RegistrationPage_Controller::RegForm($data, $form), but it doesn't seem to submit properly.

I put it into dev mode, and it's calling that function without any arguments, and then complaining that no form is returned.

The page then has a fatal error: Call to a member function securityTokenEnabled() on a non-object in /var/www/ss/sapphire/core/control/Controller.php on line 217

Have I missed a step in the form tutorial, or is there a step missing

running version 2.2.2

Avatar
Sean

Forum Moderator, 922 Posts

29 August 2008 at 6:06pm

Edited: 29/08/2008 6:14pm

So you're adding the fields and actions to your form class from the controller?

Usually we have them in the construct itself, so:


class MyCustomForm extends Form {

	function __construct($controller, $name) {

		$fields = new FieldSet(
			new TextField('Name', 'Name')
		);

		$actions = new FieldSet(
			new FormAction('doForm', 'Submit')
		);

		parent::__construct($controller, $name, $fields, $actions);
	}

	function doForm($data, $form) {
		// do procedures after form is submitted here
	}

}

In this case, doForm($data, $form) - which is the Submit button form action handler is on the same class too.

This way of laying out the code means the form is tucked away in it's own class, free from the clutter of littering it around the controller. :)

Also, are you using a custom form template? If this is the case, the issue may be that you don't have the hidden field "SecurityID" in the form fields when the form is submitted.

Sean

Avatar
StuM

Community Member, 59 Posts

29 August 2008 at 6:28pm

Hi Sean,

I was originally using a regular Form so still do have all the form elements coded through the controller.

I also have a custom template, the form was too complex to render with the regular Form.

I had placed $dataFieldByName(SecurityID) into the form, but on checking, it hasn't appeared. There is a note 'you must use sapphire/trunk ...' but I don't know what that means?

Avatar
Sean

Forum Moderator, 922 Posts

29 August 2008 at 7:13pm

It'll be because you're missing SecurityID in your forms.

You've got two options:

1. Turn off security on forms (using $form->disableSecurityToken() where $form is a Form or Form subclass object)

2. Replace your sapphire module (directory) with the trunk version using SVN.

If you don't know about SVN or what trunk means the second option probably won't be the best.

Avatar
Sean

Forum Moderator, 922 Posts

29 August 2008 at 7:52pm

Actually, there's another option I forgot:

You could add another loop in your form template like this:


<% control Fields %>
	<% if class = HiddenField %>
		$Field
	<% end_if %>
<% end_control %>

That should do the trick. Not the best solution, but it'll do for now until the next version of SS is released!

Sean

Avatar
StuM

Community Member, 59 Posts

1 September 2008 at 8:32am

Edited: 01/09/2008 8:32am

Hi Sean,

I've tried all of your tips, except getting the latest core files because the daily builds server is not working, but it's still calling RegistrationPage_Controller-><form_name> rather than the submit action in the form class.

Error in dev mode is:

FATAL ERROR: No form () returned by RegistrationPage_Controller->RForm
At line 208 in /var/www/ss/sapphire/core/control/Controller.php

the page url is:

ss/register/?executeForm=RForm

and it is posted

and action now added through the RegistrationForm subclass of Form is doSubmit. I've added tracing code in doSubmit, and it never gets called.

I even copied the MyCustomForm code you wrote, exact same result.

Code in RegistrationPage_Controller is:

public function RegistrationForm()
{	
	// build the form
	$form = new MyCustomForm($this, 'RForm');
	$form->disableSecurityToken();
	return $form;
}

Avatar
StuM

Community Member, 59 Posts

1 September 2008 at 10:08am

Edited: 01/09/2008 10:09am

Have downloaded and added latest source, and rebuilt the database.

Security ID appears now

Submit url changed to /ss/register/RForm

Still not going anywhere near MyCustomForm::doSubmit(), it's just redisplaying the form every time it submits, so it's obviously calling RegistrationPage_Controller::RegistrationForm

I've also added a piece of code in both the Form subclass and controller to capture undefined functions that may be causing it:

public function __call($function, $args)
	{
		echo __CLASS__ . '::' . $function . '<br />';
	}
}

the only missing function found being RegistrationPage_Controller::getTitle

Seems it's not even detecting that a form has been submitted.

Avatar
(deleted)

Community Member, 473 Posts

1 September 2008 at 10:48am

public function RegistrationForm() 
{    
   // build the form 
   $form = new MyCustomForm($this, 'RForm'); 
   $form->disableSecurityToken(); 
   return $form; 
} 

should be

public function RegistrationForm() 
{    
   // build the form 
   $form = new MyCustomForm($this, 'RegistrationForm'); 
   $form->disableSecurityToken(); 
   return $form; 
} 

Go to Top