mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Allow setting of specific form actions that do not require validation
Move validation exemptions into CMSForm Also fix buttonClicked() to skip CompositeField Whitespace Adding unit tests
This commit is contained in:
parent
bb7c973e34
commit
3172c7732e
@ -3,6 +3,23 @@
|
||||
* Deals with special form handling in CMS, mainly around {@link PjaxResponseNegotiator}
|
||||
*/
|
||||
class CMSForm extends Form {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $validationExemptActions = array();
|
||||
|
||||
/**
|
||||
* Always return true if the current form action is exempt from validation
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate() {
|
||||
return (
|
||||
in_array($this->buttonClicked()->actionName(), $this->getValidationExemptActions())
|
||||
|| parent::validate()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route validation error responses through response negotiator,
|
||||
@ -19,6 +36,25 @@ class CMSForm extends Form {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set actions that are exempt from validation
|
||||
*
|
||||
* @param array
|
||||
*/
|
||||
public function setValidationExemptActions($actions) {
|
||||
$this->validationExemptActions = $actions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of actions that are exempt from validation
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValidationExemptActions() {
|
||||
return $this->validationExemptActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response negotiator
|
||||
* @param ResponseNegotiator $negotiator The response negotiator to use
|
||||
|
127
admin/tests/CMSFormTest.php
Normal file
127
admin/tests/CMSFormTest.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package framework
|
||||
* @subpackage tests
|
||||
*/
|
||||
class CMSFormTest extends FunctionalTest {
|
||||
|
||||
public function testValidationExemptActions() {
|
||||
$response = $this->get('CMSFormTest_Controller');
|
||||
|
||||
$response = $this->submitForm(
|
||||
'Form_Form',
|
||||
'action_doSubmit',
|
||||
array(
|
||||
'Email' => 'test@test.com'
|
||||
)
|
||||
);
|
||||
|
||||
// Firstly, assert that required fields still work when not using an exempt action
|
||||
$this->assertPartialMatchBySelector(
|
||||
'#SomeRequiredField span.required',
|
||||
array(
|
||||
'"Some Required Field" is required'
|
||||
),
|
||||
'Required fields show a notification on field when left blank'
|
||||
);
|
||||
|
||||
// Re-submit the form using validation-exempt button
|
||||
$response = $this->submitForm(
|
||||
'Form_Form',
|
||||
'action_doSubmitValidationExempt',
|
||||
array(
|
||||
'Email' => 'test@test.com'
|
||||
)
|
||||
);
|
||||
|
||||
// The required message should be empty if validation was skipped
|
||||
$items = $this->cssParser()->getBySelector('#SomeRequiredField span.required');
|
||||
$this->assertEmpty($items);
|
||||
|
||||
// And the session message should show up is submitted successfully
|
||||
$this->assertPartialMatchBySelector(
|
||||
'#Form_Form_error',
|
||||
array(
|
||||
'Validation skipped'
|
||||
),
|
||||
'Form->sessionMessage() shows up after reloading the form'
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetValidationExemptActions() {
|
||||
$form = $this->getStubForm();
|
||||
|
||||
$form->setValidationExemptActions(array('exemptaction'));
|
||||
$exemptActions = $form->getValidationExemptActions();
|
||||
$this->assertEquals('exemptaction', $exemptActions[0]);
|
||||
}
|
||||
|
||||
protected function getStubForm() {
|
||||
$form = new CMSForm(
|
||||
new CMSFormTest_Controller(),
|
||||
'CMSForm',
|
||||
new FieldList(),
|
||||
new FieldList()
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CMSFormTest_Controller extends Controller implements TestOnly {
|
||||
|
||||
private static $allowed_actions = array('Form');
|
||||
|
||||
private static $url_handlers = array(
|
||||
'$Action//$ID/$OtherID' => "handleAction",
|
||||
);
|
||||
|
||||
protected $template = 'BlankPage';
|
||||
|
||||
public function Link($action = null) {
|
||||
return Controller::join_links('CMSFormTest_Controller', $this->request->latestParam('Action'),
|
||||
$this->request->latestParam('ID'), $action);
|
||||
}
|
||||
|
||||
public function Form() {
|
||||
$form = new CMSForm(
|
||||
$this,
|
||||
'Form',
|
||||
new FieldList(
|
||||
new EmailField('Email'),
|
||||
new TextField('SomeRequiredField'),
|
||||
new CheckboxSetField('Boxes', null, array('1'=>'one','2'=>'two'))
|
||||
),
|
||||
new FieldList(
|
||||
new FormAction('doSubmit'),
|
||||
new FormAction('doSubmitValidationExempt')
|
||||
),
|
||||
new RequiredFields(
|
||||
'Email',
|
||||
'SomeRequiredField'
|
||||
)
|
||||
);
|
||||
$form->setValidationExemptActions(array('doSubmitValidationExempt'));
|
||||
$form->setResponseNegotiator('foo'); // We aren't testing AJAX responses, so just set anything
|
||||
$form->disableSecurityToken(); // Disable CSRF protection for easier form submission handling
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
public function doSubmit($data, $form, $request) {
|
||||
$form->sessionMessage('Test save was successful', 'good');
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
public function doSubmitValidationExempt($data, $form, $request) {
|
||||
$form->sessionMessage('Validation skipped', 'good');
|
||||
return $this->redirectBack();
|
||||
}
|
||||
|
||||
public function getViewer($action = null) {
|
||||
return new SSViewer('BlankPage');
|
||||
}
|
||||
|
||||
}
|
@ -1380,8 +1380,10 @@ class Form extends RequestHandler {
|
||||
}
|
||||
|
||||
public function buttonClicked() {
|
||||
foreach($this->actions as $action) {
|
||||
if($this->buttonClickedFunc == $action->actionName()) return $action;
|
||||
foreach($this->actions->dataFields() as $action) {
|
||||
if($action->hasMethod('actionname') && $this->buttonClickedFunc == $action->actionName()) {
|
||||
return $action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user