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.

Form Questions /

HiddenField on contactform throws a "get property of non-object"-error


Reply


5 Posts   1579 Views

Avatar
Pipifix

Community Member, 54 Posts

17 April 2012 at 4:09am

Edited: 17/04/2012 4:39am

Hi everybody.

I've got a simple contactform on a staff page. The goal is to enable the frontenduser to sent a mail directly to the staffmember of the company.
So i tweaked arams tutorial [url=http://www.ssbits.com/tutorials/2010/dataobjects-as-pages-part-1-keeping-it-simple/]dataobjects as pages[/url] a little. I added a contactform and wanted to extract the staffmembers mailadress via hiddenfield.

This is my code so far

...

class StaffPage_Controller extends Page_Controller {
   
   //add our 'show' function as an allowed URL action
   static $allowed_actions = array(
      'show',
      'ContactForm'
   );
   
function ContactForm() {
// Create fields
$fields = new FieldSet(
new TextField('Name', 'Ihr vollständiger Name *'),
new EmailField('Email', 'Ihre Mailadresse *'),
new TextField('Phone', 'Eine Rückrufnummer'),
new TextareaField('Comments','Ihre Nachricht *'),
new HiddenField('StaffMail', '', $this->StaffMember->Mail) //$this->ID
);

// Create action
$actions = new FieldSet(
new FormAction('SendContactForm', 'absenden')
);

// Create Validators
$validator = new RequiredFields('Name', 'Email', 'Comments');

return new Form($this, 'ContactForm', $fields, $actions, $validator);
}
   
   function SendContactForm($data, $form) {

//Set data
$From = $data['Email'];
$To = $data['StaffMail'];
$Subject = "E-Mail vom persönlichen Kontaktformular der Webseite";
$email = new Email($From, $To, $Subject);
//set template
$email->setTemplate('ContactEmail');
//populate template
$email->populateTemplate($data);
//send mail
$email->send();
//return to submitted message
Director::redirect($this->Link("?success=1"));
}

public function Success()
{
return isset($_REQUEST['success']) && $_REQUEST['success'] == "1";
}
   
   //Show the StaffMember detail page using the StaffPage_show.ss template
   function show()
   {      
      .
      .
      .
   }
   
   //Get the current staffMember from the URL, if any
   public function getStaffMember()
   {
      .
      .
      .
   }
   
   //Return our custom breadcrumbs
   public function Breadcrumbs() {
      .
      .
      .
   }      
}

Formgeneration and validation works as expected. With firefox i'm able to inspect the hiddenfield value. The value is seeded with the right mailadress (given by the DOM via Backend) of the member. But, there's this error [Notice] Trying to get property of non-object. Whats wrong with that?

Thanks for your help. Pipifix

EDIT: Obviously this code '$this->StaffMember->Mail' isn't correct? Additional question: is it possible to set the mailto with this code? $To = $data['StaffMail'];

Avatar
Pipifix

Community Member, 54 Posts

17 April 2012 at 5:54am

Edited: 17/04/2012 6:43pm

According to this [url=http://www.silverstripe.org/e-commerce-module-forum/show/18410#post309119]codeexample[/url] and by avoiding [url=http://www.leftandmain.com/silverstripe-tips/2010/09/08/8-common-silverstripe-errors-explained-and-solved/#highlighter_781566]daisy-chaining[/url], i edited my code to this:

function ContactForm() {
// Create fields

if($stfmmbr = $this->getStaffMember()) {
      
$fields = new FieldSet(
new TextField('Name', 'Ihr vollständiger Name *'),
new EmailField('Email', 'Ihre Mailadresse *'),
new TextField('Phone', 'Eine Rückrufnummer'),
new TextareaField('Comments','Ihre Nachricht *'),
new HiddenField('StaffMail', 'StaffMail', $stfmmbr->Mail) //Avoid daisy-chaining: $this->StaffMember->Mail
);

// Create action
$actions = new FieldSet(
new FormAction('SendContactForm', 'absenden')
);

// Create Validators
$validator = new RequiredFields('Name', 'Email', 'Comments');

return new Form($this, 'ContactForm', $fields, $actions, $validator);
}
}

...the getStaffMember method

   //Get the current staffMember from the URL, if any
   public function getStaffMember()
   {
      $Params = $this->getURLParams();
      
      if(is_numeric($Params['ID']) && $StaffMember = DataObject::get_by_id('StaffMember', $Params['ID']))
      {      
         return $StaffMember;
      }
   }

The form is rendered nicely. The hidden form value shows the correct mail but by sending the form, there is a white screen. Mhmm?
I seems the getStaffMember() method returns empty. But why the (html) hidden field value is showing the right mail?

Avatar
Pipifix

Community Member, 54 Posts

17 April 2012 at 11:49pm

Edited: 18/04/2012 2:30am

Nobody's got a clue?

I ask myself whether this is the right way? Because the complete mailadress is visible in the value of the hiddenfield. Are these hidden fields crawlable by robots? And if this is the case is there another way to bind a contactform on a dataobject (staffmembers)?

Despite of these questions i'm still interested in solving the issue with the non-object (empty hiddenField?) error.

Thanks, Pipifix

And sorry for my soliloquy. ;)

Avatar
Pipifix

Community Member, 54 Posts

25 April 2012 at 12:15am

ping…

Avatar
Willr

Forum Moderator, 5513 Posts

25 April 2012 at 3:39pm

When you submit a form it calls the form method first to get all the fields. If your form fields rely on a url parameter you'll run into issues as when you have submitted the form those parameters won't be there.

I would suggest changing your form method to something like

function ContactForm() {
$value = ($stfmmbr = $this->getStaffMember()) ? $stfmmbr->Email : "";

$fields = new FieldSet(
new TextField('Name', 'Ihr vollständiger Name *'),
new EmailField('Email', 'Ihre Mailadresse *'),
new TextField('Phone', 'Eine Rückrufnummer'),
new TextareaField('Comments','Ihre Nachricht *'),
new HiddenField('StaffMail', 'StaffMail', $value)
);

// Create action
$actions = new FieldSet(
new FormAction('SendContactForm', 'absenden')
);

// Create Validators
$validator = new RequiredFields('Name', 'Email', 'Comments');

return new Form($this, 'ContactForm', $fields, $actions, $validator);
}

So remember, your form function will run after you submit.