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.

Template Questions /

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

Creating Form w/ Dropdown List From Fields In Pages


Go to End


7 Posts   6404 Views

Avatar
morris

Community Member, 4 Posts

26 June 2013 at 9:18am

Edited: 26/06/2013 9:29am

I have a page type, Boatpage.php

I'd like to create a form with a few dropdown lists, on my homepage for instance, that will populate their options from the Manufacturer and Model fields in existing pages. Here's an example

When the form is submitted I'd like to show a filtered list of the BoatPage's in my BoatHolder page type that meet the criteria selected in the dropdowns.

I've been reading through a lot of tutorials and documentation, and I'm a bit stuck. Could someone point me in the right direction.

Boatpage.php

<?php
class BoatPage extends Page {
	 static $db = array(
	 	'Manufacturer' => 'Text',
	 	'Model' => 'Text',
	 	'Stockno' => 'Text',
	 	'Length' => 'Text',
	 	'Type' => 'Text',
	 	'Dryweight' => 'Text',
	 	'Options' => 'Text',
	 	'Status' => 'Text',
	 	'Price' => 'Text',
	 	'Location' => 'Text',
	 	'Year' => 'Text'
        );
        static $has_one = array(
        'Photo' => 'Image'
    );
        
         public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->addFieldToTab('Root.Main', new TextField('Manufacturer'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Model'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Stockno'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Length'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Type'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Dryweight'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Options'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Status'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Price'), 'Content');
        $fields->addFieldToTab('Root.Main', new TextField('Location'), 'Content'); 
        $fields->addFieldToTab('Root.Main', new TextField('Year'), 'Content'); 
         $fields->addFieldToTab("Root.Images", new UploadField('Photo'));
     
        return $fields;
    }
}
class BoatPage_Controller extends Page_Controller {
}
?>

BoatHolder.php

<?php
class BoatHolder extends Page {
    static $allowed_children = array('BoatPage');
}
class BoatHolder_Controller extends Page_Controller {
}
?>

(side note: I am a noob.)

Avatar
copernican

Community Member, 189 Posts

27 June 2013 at 12:45am

Hey Morris,

I'll help you get started with the form & dropdowns, and will try and continue to help. So, the first step is to create a function that will return a form you can use in your template. In your HomePage.php (or Page.php if you plan on using it on other pages)

public class HomePage_Controller extends Page_Controller {

public function BoatForm(){
                //Fields
		$fields = new FieldList(
			//put form fields here					   
		);
		
		//action field
		$actions = new FieldList(
			new FormAction('BoatFormHandler', 'Post')					
		);
		
		//required Fields
		$requiredFields = new RequiredFields(
			//enter required fields here									 
		);
		
		//creating form
		$form = new Form(
			$this,
			'BoatForm', //this needs to match your function name
			$fields,
			$actions,
			$requiredFields				 
		);
		
		return $form;	
}
// form handler
public function BoatFormHandler($data,$form){
var_dump($data);//good way to see what data the form is submitting.
}

}

This is the start of a basic form. Simply add $BoatForm anywhere on your HomePage.ss template to display the form. The next step is to add the fields you want to the $fields FieldList object. Creating a dynamic dropdown is pretty easy.

$boatPages= BoatPage::get(); //get a DataList of BoatPages
$fields = new FieldList(
			new DropdownField('Manufacturer', 'Select a Manufacturer', $boatPages->map('ID','Manufacturer', 'Select One...'));
                        new DropdownField('Model','Select a Model', $boatPages->map('ID','Model', 'Select One...'));
		);

It's a good idea to add some conditional logic to the above code otherwise the page will break if no BoatPages exist. Every time a new boat page is created in the CMS, it's manufacturer and model will automatically get added to the dropdowns. Test this out and see if the var_dump($data) returns the data you want. If you can get that working I will try and continue to help.

Please note my code isn't tested, but should work :)

Avatar
morris

Community Member, 4 Posts

27 June 2013 at 3:12am

Edited: 27/06/2013 3:27am

Thanks for your reply IOTI!

I've got the form on the page now, but does not appear to be pulling data from BoatPages. I'm just using one field for simplicity's sake right now. See here

I went ahead and put your code in page.php so I could use it on more than one page.

Here's what my page.php file looks like now.

<?php
class Page extends SiteTree {
	public static $db = array(
	);
	public static $has_one = array(
	);
}
class Page_Controller extends ContentController {

private static $allowed_actions = array(
        // someaction can be accessed by anyone, any time
        'BoatForm'
    );

	public function init() {
		parent::init();

		// Note: you should use SS template require tags inside your templates 
		// instead of putting Requirements calls here.  However these are 
		// included so that our older themes still work
		Requirements::themedCSS('reset');
		Requirements::themedCSS('layout'); 
		Requirements::themedCSS('typography'); 
		Requirements::themedCSS('form'); 
	}
	
	// Start ioti's code
	public function BoatForm(){ 
		
		$boatPages= BoatPage::get(); //get a DataList of BoatPages 
		//Fields 
     $fields = new FieldList( 
     	new DropdownField('Manufacturer', $boatPages->map('ID','Manufacturer')) );
       
      //action field 
      $actions = new FieldList( 
         new FormAction('BoatFormHandler', 'Post')                
      ); 
       
      //required Fields 
      	$requiredFields = new RequiredFields( 
      	new DropdownField('Manufacturer', $boatPages->map('ID','Manufacturer')) 
      	//enter required fields here
      	);
       
      //creating form 
      $form = new Form( 
         $this, 
         'BoatForm', //this needs to match your function name 
         $fields, 
         $actions, 
         $requiredFields             
      ); 
       
      return $form;    
		} 
		// form handler 
		public function BoatFormHandler($data,$form){ 
		var_dump($data);//good way to see what data the form is submitting. 
		}
// end ioti's code

}

Avatar
copernican

Community Member, 189 Posts

27 June 2013 at 3:39am

Edited: 27/06/2013 3:40am

In your code you have

new DropdownField('Manufacturer', $boatPages->map('ID','Manufacturer')) );

But it's important that the "$boatPages->map('ID','Manufacturer')" is the 3rd argument. It should look like

new DropdownField('Manufacturer', '', $boatPages->map('ID','Manufacturer')) );

See http://api.silverstripe.org/3.0/class-DropdownField.html#___construct for a list of arguments when declaring a new DropdownField. the 2nd one being a "Title" field.

One other thing to note is that in your $requiredFields you would just enter the fields title like so

   //required Fields 
   $requiredFields = new RequiredFields( 
   'Manufacturer'
   );

let me know if that works!

Avatar
morris

Community Member, 4 Posts

27 June 2013 at 3:47am

Edited: 27/06/2013 3:51am

You are magical, sir! I have data in my dropdown. Now I'll try to 'group by' somehow so I don't get duplicates

Avatar
copernican

Community Member, 189 Posts

27 June 2013 at 3:53am

That's great!

So the next step is building out the rest of form with the other fields you want, and then making sure the data is getting sent to your BoatFormHandler() function. You'll then want to use that data to return a list of BoatPages.

Is that something you also need help with or are you going to try and tackle that on your own first?

Avatar
morris

Community Member, 4 Posts

27 June 2013 at 4:00am

I am sure I will need help, but right now I've got less fun stuff to deal with. I'm the only computer guy where I work. I'll post again when I get back to work on it, probably this evening. Thank you for your help.