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.

Data Model Questions /

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

Making CMS-Fields required


Go to End


17 Posts   9222 Views

Avatar
henrik_

Community Member, 5 Posts

3 January 2014 at 9:44am

Hey there,

I have a banal problem but didn't find a working solution though googling it...
I have a simple DataObject and want to make sure that people using the CMS fill every field.

class ProgramItem extends DataObject {

	public static $has_one = array('AdditionalProgram' => 'AdditionalProgram');

	public static $db = array('Headline' => "Varchar", 'Description' => "HTMLText", 'ArchivingDate' => "Date");

	function getCMSValidator() {
		return new RequiredFields(array('Headline', 'Description', 'ArchivingDate'));
	}

}

I tried overwriting the getCMSValidator()-Function but it didn't work. How does it work using Silverstripe 3.1 ?

Regards,
henrik

Avatar
Willr

Forum Moderator, 5523 Posts

3 January 2014 at 6:20pm

Edited: 03/01/2014 6:20pm

getCMSValidator is the correct function so that should work. Is your editing interface a ModelAdmin subclass?

Avatar
henrik_

Community Member, 5 Posts

4 January 2014 at 1:30am

Hey,
thanks for your reply!

No, I think its not... I'm creating/editing the ProgramItems through a GridField. Might this be the problem?

Avatar
martimiz

Forum Moderator, 1391 Posts

5 January 2014 at 5:13am

It seems GridFieldDetailForm (#400) calls $this->component->getValidator() instead of $this->component->getCMSValidator()

Probably because the GridField isn't CMS perse?

Avatar
Willr

Forum Moderator, 5523 Posts

5 January 2014 at 9:08am

That is what GridField API method is called, but in ModelAdmin it calls the getCMSValidator.

https://github.com/silverstripe/silverstripe-framework/blob/3.1/admin/code/ModelAdmin.php#L152

Avatar
martimiz

Forum Moderator, 1391 Posts

5 January 2014 at 11:26am

@willr: Yes, but when you use a gridfield in, say, your pages getCMSFields(), getCMSValidator() wouldn't work I think. And that might be a bit confusing...

Does the gridfield 'know' if it's in the CMS? In tthat case could it be made to select the CMSValidator() instead of getValidator() do you think? Or am I totally wrong here?

Avatar
HARVS1789UK

Community Member, 31 Posts

11 January 2014 at 12:33am

Edited: 11/01/2014 12:34am

I have also been having the same issue as henrik_ for the last couple of hours and it had been driving me insane, so I am glad to have found this post.

As Willr and Martimiz has discussed it seems to be an issue caused by GridFieldDetailForm not giving any consideration to wether we are in the context of the CMS or not and/or wether the DataObject record being added/edited has a getCMSValidator() method (DataObject doesn't have one to fall back to as a default).

@Willr and @Martimiz what do you think to my suggested fix below, will it have any negative knock on effects when GridField is used outside of the CMS? If it looks OK to both of you I will make a pull request and register the issue as a bug.

Suggested Fix

		$toplevelController = $this->getToplevelController();
		if(
		    $toplevelController &&
		    $toplevelController instanceof LeftAndMain &&
		    $this->record->hasMethod('getCMSValidator')
		) {
		    $validator = $this->record->getCMSValidator();
		} else {
		    $validator =  $this->component->getValidator() ;
		}
		
		$form = new Form(
			$this,
			'ItemEditForm',
			$fields,
			$actions,
			$validator
		);

Current Code

		$form = new Form(
			$this,
			'ItemEditForm',
			$fields,
			$actions,
			$this->component->getValidator()
		);

Avatar
martimiz

Forum Moderator, 1391 Posts

11 January 2014 at 3:53am

Edited: 11/01/2014 3:56am

I really needed to educate myself a bit more on the GridField, triggered by Will's comments :) What ModelAdmin does is just configuring the GridField to use the proper validator. The GridFieldDetailForm doesn't actually do any validation out of the box so you need to tell it which validator to use.

So this is on a Page class:

	public function getCMSFields() {
		
		$fields = parent::getCMSFields();

		$fields->addFieldsToTab(
			"Root.Griddy", array(
				$gridField = new GridField(
					'MyObjects', 
					'My Objects', 
					$this->MyObjects(),
					GridFieldConfig_RecordEditor::create()
				)
		));

		// add the CMS validator
		if (singleton('MyObject')->hasMethod('getCMSValidator')) {
			$gridField->getConfig()
				  ->getComponentByType('GridFieldDetailForm')
				  ->setValidator(singleton('MyObject')->getCMSValidator());
		}
		return $fields;
	}

Basically this is how configuring a GridField would work anyway. So I'm not sure we should want to set the GridFieldDetailForm to a fixed validator based on the context. Creating a GridFieldConfig_RecordEditor extension to use in the CMS would be an option...

Go to Top