Adding a 'Please select' option to a SilverStripe DropdownField when using a DataObject->toDropdownMap

Posted by Gav on 14 July 2010 | 4 Comments

Tags: , , ,

This is so easy to do, once you know how, its not funny, but it has taken me months to work out. I always thought there was a bug with the DataObject->toDropdownMap method.

1. First we need a DataObject.

We can create a simple DataObject by creating a file called MyDataObject.php which is saved into the mysite/code/ directory. The file will contain the following code.

<?php
class MyDataObject extends DataObject {
	static $db = array(
		'Title' => 'Varchar(100)'
	);
}

2. Fill the DataObject with some data.

We will be using the ModelAdmin to fill the MyDataObject with some data. Its quite easy to create an administrator page for this. To start create a file called MyDataAdmin.php and save this in the mysite/code/ directory. The file will contain the following code.

<?php
class MyDataAdmin extends ModelAdmin {
	static $managed_models = array(
		'MyDataObject'
	);

	static $url_segment = 'my-data-admin';
	static $menu_title = 'My Data Admin';
}

This will add another tab to the top of the admin interface called My Data Admin.

Don't forget to do a localhost/dev/build?flush=1 to rebuild the database. Now go and add some data using the new admin page. To create a record, click on Create 'My Data Object'. Add a few records.

3. Create a page with a form.

We are now going to create a page to demonstrate how to add the Please select text to the dropdownField. Create a file called MyDataPage.php and save it in the mysite/code/ directory. The file will contain the following code.

<?php
class MyDataPage extends Page {
	static $db = array();
	static $has_one = array();
}

class MyDataPage_Controller extends Page_Controller {

	function MyDataForm() {

		$fields = new Fieldset(
			new DropdownField('MyDataObjectID', 'My Data Object', array('' => 'Please select') + DataObject::get('MyDataObject', 'ID', 'Title')->toDropdownMap())
		);

		$actions = new Fieldset(
			new FormAction('MyDataFormAction', 'Submit')
		);

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

	function MyDataFormAction($data, $form) {

		//echo "process form";

	}

}

We will reqire another localhost/dev/build?flush=1 to rebuild the database.

We are also going to need to create file a file called MyDataPage.ss which will be saved in the themes/<themename>/templates/Layout/ directory. The file will contain the following code.

<h1>$Title</h1>
$Content
$MyDataForm

Now add a page to the site which is a My Data Page. The token $MyDataForm will inject the form into the page.

How it works:

What we are doing is adding two php arrays together using the + operator. The first array has one option:

array('' => 'Please select')

And the 2nd array is an array of the values from the MyDataObject Data object. To get this we are using the toDropdownMap method of the Data Object.

DataObject::get('MyDataObject', 'ID', 'Title')->toDropdownMap()

So to get the options for the DropdownField, we simply use:

$options = array('' => 'Please select') + DataObject::get('MyDataObject', 'ID', 'Title')->toDropdownMap()

Why I thought there was a bug in the toDropdownMap() method

Previously, I had been using the array_merge function to merge the two arrays together. This destroys the array keys are resets them back to a zero index.


Post your comment

Comments

gav says:

@John - cool, i just checked out the docos and saw your first post was incorrect. thanks for the comments.

http://api.silverstripe.org/2.4/forms/fields-basic/DropdownField.html#methodsetEmptyString

Posted by gav, 6th May 2011 9:13 am (4 years ago)

John says:

$field->setEmptyString('Please select ...');
must be
$update_fields->setEmptyString('Please select ...');

Posted by John, 6 May 2011 (4 years ago)

John says:

add a field with an empty value
...
$update_fields = $fields->getFormField();
$field->setEmptyString('Please select ...');
$fields->push($update_fields);

Posted by John, 6 May 2011 (4 years ago)

Gav says:

Another way to do this is to use the $emptyString parameter.

E.g.
$fields = new Fieldset(
new DropdownField('MyDataObjectID', 'My Data Object', DataObject::get('MyDataObject', 'ID', 'Title')->toDropdownMap(), '', '', 'Please select')
);

Posted by Gav, 19th August 2010 6:00 pm (4 years ago)

RSS feed for comments on this page | RSS feed for all comments