mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
Merge remote-tracking branch 'origin/4' into 4.3
This commit is contained in:
commit
893a28e0c6
@ -6,6 +6,10 @@
|
|||||||
*
|
*
|
||||||
* @method EditableFormField Parent()
|
* @method EditableFormField Parent()
|
||||||
* @package userforms
|
* @package userforms
|
||||||
|
*
|
||||||
|
* @property string Display
|
||||||
|
* @property string ConditionOption
|
||||||
|
* @property string FieldValue
|
||||||
*/
|
*/
|
||||||
class EditableCustomRule extends DataObject
|
class EditableCustomRule extends DataObject
|
||||||
{
|
{
|
||||||
@ -147,4 +151,91 @@ class EditableCustomRule extends DataObject
|
|||||||
{
|
{
|
||||||
return $this->canDelete($member);
|
return $this->canDelete($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Substitutes configured rule logic with it's JS equivalents and returns them as array elements
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function buildExpression()
|
||||||
|
{
|
||||||
|
/** @var EditableFormField $formFieldWatch */
|
||||||
|
$formFieldWatch = $this->ConditionField();
|
||||||
|
//Encapsulated the action to the object
|
||||||
|
$action = $formFieldWatch->getJsEventHandler();
|
||||||
|
|
||||||
|
// is this field a special option field
|
||||||
|
$checkboxField = $formFieldWatch->isCheckBoxField();
|
||||||
|
$radioField = $formFieldWatch->isRadioField();
|
||||||
|
$target = sprintf('$("%s")', $formFieldWatch->getSelectorFieldOnly());
|
||||||
|
$fieldValue = Convert::raw2js($this->FieldValue);
|
||||||
|
|
||||||
|
$conditionOptions = array(
|
||||||
|
'ValueLessThan' => '<',
|
||||||
|
'ValueLessThanEqual' => '<=',
|
||||||
|
'ValueGreaterThan' => '>',
|
||||||
|
'ValueGreaterThanEqual' => '>='
|
||||||
|
);
|
||||||
|
// and what should we evaluate
|
||||||
|
switch ($this->ConditionOption) {
|
||||||
|
case 'IsNotBlank':
|
||||||
|
case 'IsBlank':
|
||||||
|
$expression = ($checkboxField || $radioField) ? "!{$target}.is(\":checked\")" : "{$target}.val() == ''";
|
||||||
|
if ($this->ConditionOption == 'IsNotBlank') {
|
||||||
|
//Negate
|
||||||
|
$expression = "!({$expression})";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'HasValue':
|
||||||
|
case 'ValueNot':
|
||||||
|
if ($checkboxField) {
|
||||||
|
if ($formFieldWatch->isCheckBoxGroupField()) {
|
||||||
|
$expression = sprintf("$.inArray('%s', %s.filter(':checked').map(function(){ return $(this).val();}).get()) > -1",
|
||||||
|
$fieldValue, $target);
|
||||||
|
} else {
|
||||||
|
$expression = "{$target}.prop('checked')";
|
||||||
|
}
|
||||||
|
} elseif ($radioField) {
|
||||||
|
// We cannot simply get the value of the radio group, we need to find the checked option first.
|
||||||
|
$expression = sprintf('%s.closest(".field, .control-group").find("input:checked").val() == "%s"',
|
||||||
|
$target, $fieldValue);
|
||||||
|
} else {
|
||||||
|
$expression = sprintf('%s.val() == "%s"', $target, $fieldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->ConditionOption == 'ValueNot') {
|
||||||
|
//Negate
|
||||||
|
$expression = "!({$expression})";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ValueLessThan':
|
||||||
|
case 'ValueLessThanEqual':
|
||||||
|
case 'ValueGreaterThan':
|
||||||
|
case 'ValueGreaterThanEqual':
|
||||||
|
$expression = sprintf('%s.val() %s parseFloat("%s")', $target,
|
||||||
|
$conditionOptions[$this->ConditionOption], $fieldValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new LogicException("Unhandled rule {$this->ConditionOption}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array(
|
||||||
|
'operation' => $expression,
|
||||||
|
'event' => $action,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the opposite of the show/hide pairs of strings
|
||||||
|
*
|
||||||
|
* @param string $text
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function toggleDisplayText($text)
|
||||||
|
{
|
||||||
|
return (strtolower($text) === 'show') ? 'hide' : 'show';
|
||||||
|
}
|
||||||
}
|
}
|
@ -205,6 +205,20 @@ SQL;
|
|||||||
$config->addComponent($export = new GridFieldExportButton('buttons-after-left'));
|
$config->addComponent($export = new GridFieldExportButton('buttons-after-left'));
|
||||||
$config->addComponent($print = new GridFieldPrintButton('buttons-after-left'));
|
$config->addComponent($print = new GridFieldPrintButton('buttons-after-left'));
|
||||||
|
|
||||||
|
// show user form items in the summary tab
|
||||||
|
$summaryarray = array(
|
||||||
|
'ID' => 'ID',
|
||||||
|
'Created' => 'Created',
|
||||||
|
'LastEdited' => 'Last Edited'
|
||||||
|
);
|
||||||
|
foreach(EditableFormField::get()->filter(array("ParentID" => $parentID)) as $eff) {
|
||||||
|
if($eff->ShowInSummary) {
|
||||||
|
$summaryarray[$eff->Name] = $eff->Title ?: $eff->Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$config->getComponentByType('GridFieldDataColumns')->setDisplayFields($summaryarray);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for {@link https://github.com/colymba/GridFieldBulkEditingTools}
|
* Support for {@link https://github.com/colymba/GridFieldBulkEditingTools}
|
||||||
*/
|
*/
|
||||||
@ -440,180 +454,26 @@ class UserDefinedForm_Controller extends Page_Controller
|
|||||||
$rules = "";
|
$rules = "";
|
||||||
|
|
||||||
$watch = array();
|
$watch = array();
|
||||||
$watchLoad = array();
|
|
||||||
|
|
||||||
if ($this->Fields()) {
|
if ($this->Fields()) {
|
||||||
|
/** @var EditableFormField $field */
|
||||||
foreach ($this->Fields() as $field) {
|
foreach ($this->Fields() as $field) {
|
||||||
$holderSelector = $field->getSelectorHolder();
|
if ($result = $field->formatDisplayRules()) {
|
||||||
|
$watch[] = $result;
|
||||||
// Is this Field Show by Default
|
|
||||||
if (!$field->ShowOnLoad) {
|
|
||||||
$default .= "{$holderSelector}.hide().trigger('userform.field.hide');\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for field dependencies / default
|
|
||||||
foreach ($field->EffectiveDisplayRules() as $rule) {
|
|
||||||
|
|
||||||
// Get the field which is effected
|
|
||||||
$formFieldWatch = EditableFormField::get()->byId($rule->ConditionFieldID);
|
|
||||||
|
|
||||||
// Skip deleted fields
|
|
||||||
if (!$formFieldWatch) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fieldToWatch = $formFieldWatch->getSelectorField($rule);
|
|
||||||
$fieldToWatchOnLoad = $formFieldWatch->getSelectorField($rule, true);
|
|
||||||
|
|
||||||
// show or hide?
|
|
||||||
$view = ($rule->Display == 'Hide') ? 'hide' : 'show';
|
|
||||||
$opposite = ($view == "show") ? "hide" : "show";
|
|
||||||
|
|
||||||
// what action do we need to keep track of. Something nicer here maybe?
|
|
||||||
// @todo encapulsation
|
|
||||||
$action = "change";
|
|
||||||
|
|
||||||
if ($formFieldWatch instanceof EditableTextField) {
|
|
||||||
$action = "keyup";
|
|
||||||
}
|
|
||||||
|
|
||||||
// is this field a special option field
|
|
||||||
$checkboxField = false;
|
|
||||||
$radioField = false;
|
|
||||||
|
|
||||||
if (in_array($formFieldWatch->ClassName, array('EditableCheckboxGroupField', 'EditableCheckbox'))) {
|
|
||||||
$action = "click";
|
|
||||||
$checkboxField = true;
|
|
||||||
} elseif ($formFieldWatch->ClassName == "EditableRadioField") {
|
|
||||||
$radioField = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and what should we evaluate
|
|
||||||
switch ($rule->ConditionOption) {
|
|
||||||
case 'IsNotBlank':
|
|
||||||
$expression = ($checkboxField || $radioField) ? '$(this).is(":checked")' :'$(this).val() != ""';
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'IsBlank':
|
|
||||||
$expression = ($checkboxField || $radioField) ? '!($(this).is(":checked"))' : '$(this).val() == ""';
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'HasValue':
|
|
||||||
if ($checkboxField) {
|
|
||||||
$expression = '$(this).prop("checked")';
|
|
||||||
} elseif ($radioField) {
|
|
||||||
// We cannot simply get the value of the radio group, we need to find the checked option first.
|
|
||||||
$expression = '$(this).closest(".field, .control-group").find("input:checked").val()=="'. $rule->FieldValue .'"';
|
|
||||||
} else {
|
|
||||||
$expression = '$(this).val() == "'. $rule->FieldValue .'"';
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'ValueLessThan':
|
|
||||||
$expression = '$(this).val() < parseFloat("'. $rule->FieldValue .'")';
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'ValueLessThanEqual':
|
|
||||||
$expression = '$(this).val() <= parseFloat("'. $rule->FieldValue .'")';
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'ValueGreaterThan':
|
|
||||||
$expression = '$(this).val() > parseFloat("'. $rule->FieldValue .'")';
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'ValueGreaterThanEqual':
|
|
||||||
$expression = '$(this).val() >= parseFloat("'. $rule->FieldValue .'")';
|
|
||||||
|
|
||||||
break;
|
|
||||||
default: // ==HasNotValue
|
|
||||||
if ($checkboxField) {
|
|
||||||
$expression = '!$(this).prop("checked")';
|
|
||||||
} elseif ($radioField) {
|
|
||||||
// We cannot simply get the value of the radio group, we need to find the checked option first.
|
|
||||||
$expression = '$(this).parents(".field, .control-group").find("input:checked").val()!="'. $rule->FieldValue .'"';
|
|
||||||
} else {
|
|
||||||
$expression = '$(this).val() != "'. $rule->FieldValue .'"';
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($watch[$fieldToWatch])) {
|
|
||||||
$watch[$fieldToWatch] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$watch[$fieldToWatch][] = array(
|
|
||||||
'expression' => $expression,
|
|
||||||
'holder_selector' => $holderSelector,
|
|
||||||
'view' => $view,
|
|
||||||
'opposite' => $opposite,
|
|
||||||
'action' => $action
|
|
||||||
);
|
|
||||||
|
|
||||||
$watchLoad[$fieldToWatchOnLoad] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($watch) {
|
if ($watch) {
|
||||||
foreach ($watch as $key => $values) {
|
$rules .= $this->buildWatchJS($watch);
|
||||||
$logic = array();
|
|
||||||
$actions = array();
|
|
||||||
|
|
||||||
foreach ($values as $rule) {
|
|
||||||
// Assign action
|
|
||||||
$actions[$rule['action']] = $rule['action'];
|
|
||||||
|
|
||||||
// Assign behaviour
|
|
||||||
$expression = $rule['expression'];
|
|
||||||
$holder = $rule['holder_selector'];
|
|
||||||
$view = $rule['view']; // hide or show
|
|
||||||
$opposite = $rule['opposite'];
|
|
||||||
// Generated javascript for triggering visibility
|
|
||||||
$logic[] = <<<"EOS"
|
|
||||||
if({$expression}) {
|
|
||||||
{$holder}
|
|
||||||
.{$view}()
|
|
||||||
.trigger('userform.field.{$view}');
|
|
||||||
} else {
|
|
||||||
{$holder}
|
|
||||||
.{$opposite}()
|
|
||||||
.trigger('userform.field.{$opposite}');
|
|
||||||
}
|
|
||||||
EOS;
|
|
||||||
}
|
|
||||||
|
|
||||||
$logic = implode("\n", $logic);
|
|
||||||
$rules .= $key.".each(function() {\n
|
|
||||||
$(this).data('userformConditions', function() {\n
|
|
||||||
$logic\n
|
|
||||||
}); \n
|
|
||||||
});\n";
|
|
||||||
foreach ($actions as $action) {
|
|
||||||
$rules .= $key.".$action(function() {
|
|
||||||
$(this).data('userformConditions').call(this);\n
|
|
||||||
});\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($watchLoad) {
|
|
||||||
foreach ($watchLoad as $key => $value) {
|
|
||||||
$rules .= $key.".each(function() {
|
|
||||||
$(this).data('userformConditions').call(this);\n
|
|
||||||
});\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add customScript if $default or $rules is defined
|
// Only add customScript if $default or $rules is defined
|
||||||
if ($default || $rules) {
|
if ($rules) {
|
||||||
Requirements::customScript(<<<JS
|
Requirements::customScript(<<<JS
|
||||||
(function($) {
|
(function($) {
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$default
|
{$rules}
|
||||||
|
});
|
||||||
$rules
|
|
||||||
})
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
JS
|
JS
|
||||||
, 'UserFormsConditional');
|
, 'UserFormsConditional');
|
||||||
@ -871,12 +731,55 @@ JS
|
|||||||
Session::clear('FormProcessed');
|
Session::clear('FormProcessed');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->customise(array(
|
$data = array(
|
||||||
'Content' => $this->customise(array(
|
|
||||||
'Submission' => $submission,
|
'Submission' => $submission,
|
||||||
'Link' => $referrer
|
'Link' => $referrer
|
||||||
))->renderWith('ReceivedFormSubmission'),
|
);
|
||||||
|
|
||||||
|
$this->extend('updateReceivedFormSubmissionData', $data);
|
||||||
|
|
||||||
|
return $this->customise(array(
|
||||||
|
'Content' => $this->customise($data)->renderWith('ReceivedFormSubmission'),
|
||||||
'Form' => '',
|
'Form' => '',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs the required JS from the $watch input
|
||||||
|
*
|
||||||
|
* @param array $watch
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function buildWatchJS($watch)
|
||||||
|
{
|
||||||
|
$result = '';
|
||||||
|
foreach ($watch as $key => $rule) {
|
||||||
|
$events = implode(' ', $rule['events']);
|
||||||
|
$selectors = implode(', ', $rule['selectors']);
|
||||||
|
$conjunction = $rule['conjunction'];
|
||||||
|
$operations = implode(" {$conjunction} ", $rule['operations']);
|
||||||
|
$target = $rule['targetFieldID'];
|
||||||
|
$initialState = $rule['initialState'];
|
||||||
|
$view = $rule['view'];
|
||||||
|
$opposite = $rule['opposite'];
|
||||||
|
|
||||||
|
$result .= <<<EOS
|
||||||
|
\n
|
||||||
|
$('.userform').on('{$events}',
|
||||||
|
"{$selectors}",
|
||||||
|
function (){
|
||||||
|
if({$operations}) {
|
||||||
|
$('{$target}').{$view}();
|
||||||
|
} else {
|
||||||
|
$('{$target}').{$opposite}();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
EOS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ class EditableCheckbox extends EditableFormField
|
|||||||
|
|
||||||
private static $plural_name = 'Checkboxes';
|
private static $plural_name = 'Checkboxes';
|
||||||
|
|
||||||
|
protected $jsEventHandler = 'click';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'CheckedDefault' => 'Boolean' // from CustomSettings
|
'CheckedDefault' => 'Boolean' // from CustomSettings
|
||||||
);
|
);
|
||||||
@ -61,4 +63,8 @@ class EditableCheckbox extends EditableFormField
|
|||||||
|
|
||||||
parent::migrateSettings($data);
|
parent::migrateSettings($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isCheckBoxField() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ class EditableCheckboxGroupField extends EditableMultipleOptionField
|
|||||||
|
|
||||||
private static $plural_name = "Checkbox Groups";
|
private static $plural_name = "Checkbox Groups";
|
||||||
|
|
||||||
|
protected $jsEventHandler = 'click';
|
||||||
|
|
||||||
public function getFormField()
|
public function getFormField()
|
||||||
{
|
{
|
||||||
$field = new UserFormsCheckboxSetField($this->Name, $this->EscapedTitle, $this->getOptionsMap());
|
$field = new UserFormsCheckboxSetField($this->Name, $this->EscapedTitle, $this->getOptionsMap());
|
||||||
@ -59,4 +61,18 @@ class EditableCheckboxGroupField extends EditableMultipleOptionField
|
|||||||
return "$(\"input[name='{$this->Name}[]']:first\")";
|
return "$(\"input[name='{$this->Name}[]']:first\")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isCheckBoxField() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSelectorFieldOnly()
|
||||||
|
{
|
||||||
|
return "[name='{$this->Name}[]']";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isCheckBoxGroupField()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ class EditableDateField extends EditableFormField
|
|||||||
|
|
||||||
private static $plural_name = 'Date Fields';
|
private static $plural_name = 'Date Fields';
|
||||||
|
|
||||||
|
private static $has_placeholder = true;
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'DefaultToToday' => 'Boolean' // From customsettings
|
'DefaultToToday' => 'Boolean' // From customsettings
|
||||||
);
|
);
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EditableDropdown
|
* EditableDropdown
|
||||||
*
|
*
|
||||||
* Represents a modifiable dropdown (select) box on a form
|
* Represents a modifiable dropdown (select) box on a form
|
||||||
*
|
*
|
||||||
|
* @property bool $UseEmptyString
|
||||||
|
* @property string $EmptyString
|
||||||
|
*
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableDropdown extends EditableMultipleOptionField
|
class EditableDropdown extends EditableMultipleOptionField
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -14,6 +17,11 @@ class EditableDropdown extends EditableMultipleOptionField
|
|||||||
|
|
||||||
private static $plural_name = 'Dropdowns';
|
private static $plural_name = 'Dropdowns';
|
||||||
|
|
||||||
|
private static $db = array(
|
||||||
|
'UseEmptyString' => 'Boolean',
|
||||||
|
'EmptyString' => 'Varchar(255)',
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
@ -21,6 +29,18 @@ class EditableDropdown extends EditableMultipleOptionField
|
|||||||
{
|
{
|
||||||
$fields = parent::getCMSFields();
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
|
$fields->addFieldToTab(
|
||||||
|
'Root.Main',
|
||||||
|
CheckboxField::create('UseEmptyString')
|
||||||
|
->setTitle('Set default empty string')
|
||||||
|
);
|
||||||
|
|
||||||
|
$fields->addFieldToTab(
|
||||||
|
'Root.Main',
|
||||||
|
TextField::create('EmptyString')
|
||||||
|
->setTitle('Empty String')
|
||||||
|
);
|
||||||
|
|
||||||
$fields->removeByName('Default');
|
$fields->removeByName('Default');
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
@ -35,6 +55,10 @@ class EditableDropdown extends EditableMultipleOptionField
|
|||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
->setTemplate('UserFormsDropdownField');
|
->setTemplate('UserFormsDropdownField');
|
||||||
|
|
||||||
|
if ($this->UseEmptyString) {
|
||||||
|
$field->setEmptyString(($this->EmptyString) ? $this->EmptyString : '');
|
||||||
|
}
|
||||||
|
|
||||||
// Set default
|
// Set default
|
||||||
$defaultOption = $this->getDefaultOptions()->first();
|
$defaultOption = $this->getDefaultOptions()->first();
|
||||||
if ($defaultOption) {
|
if ($defaultOption) {
|
||||||
|
23
code/model/editableformfields/EditableEmailField.php
Executable file → Normal file
23
code/model/editableformfields/EditableEmailField.php
Executable file → Normal file
@ -14,24 +14,7 @@ class EditableEmailField extends EditableFormField
|
|||||||
|
|
||||||
private static $plural_name = 'Email Fields';
|
private static $plural_name = 'Email Fields';
|
||||||
|
|
||||||
private static $db = array(
|
private static $has_placeholder = true;
|
||||||
'Placeholder' => 'Varchar(255)'
|
|
||||||
);
|
|
||||||
|
|
||||||
public function getCMSFields()
|
|
||||||
{
|
|
||||||
$this->beforeUpdateCMSFields(function ($fields) {
|
|
||||||
$fields->addFieldToTab(
|
|
||||||
'Root.Main',
|
|
||||||
TextField::create(
|
|
||||||
'Placeholder',
|
|
||||||
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return parent::getCMSFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSetsOwnError()
|
public function getSetsOwnError()
|
||||||
{
|
{
|
||||||
@ -59,9 +42,5 @@ class EditableEmailField extends EditableFormField
|
|||||||
parent::updateFormField($field);
|
parent::updateFormField($field);
|
||||||
|
|
||||||
$field->setAttribute('data-rule-email', true);
|
$field->setAttribute('data-rule-email', true);
|
||||||
|
|
||||||
if ($this->Placeholder) {
|
|
||||||
$field->setAttribute('placeholder', $this->Placeholder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ use SilverStripe\Forms\SegmentField;
|
|||||||
* @property int $Sort
|
* @property int $Sort
|
||||||
* @property bool $Required
|
* @property bool $Required
|
||||||
* @property string $CustomErrorMessage
|
* @property string $CustomErrorMessage
|
||||||
|
* @property boolean $ShowOnLoad
|
||||||
|
* @property string $DisplayRulesConjunction
|
||||||
* @method UserDefinedForm Parent() Parent page
|
* @method UserDefinedForm Parent() Parent page
|
||||||
* @method DataList DisplayRules() List of EditableCustomRule objects
|
* @method DataList DisplayRules() List of EditableCustomRule objects
|
||||||
* @mixin Versioned
|
* @mixin Versioned
|
||||||
@ -60,6 +62,13 @@ class EditableFormField extends DataObject
|
|||||||
*/
|
*/
|
||||||
public static $allowed_css = array();
|
public static $allowed_css = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this to true to enable placeholder field for any given class
|
||||||
|
* @config
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private static $has_placeholder = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
@ -87,8 +96,12 @@ class EditableFormField extends DataObject
|
|||||||
"ExtraClass" => "Text", // from CustomSettings
|
"ExtraClass" => "Text", // from CustomSettings
|
||||||
"RightTitle" => "Varchar(255)", // from CustomSettings
|
"RightTitle" => "Varchar(255)", // from CustomSettings
|
||||||
"ShowOnLoad" => "Boolean(1)", // from CustomSettings
|
"ShowOnLoad" => "Boolean(1)", // from CustomSettings
|
||||||
|
"ShowInSummary" => "Boolean",
|
||||||
|
"Placeholder" => "Varchar(255)",
|
||||||
|
'DisplayRulesConjunction' => 'Enum("And,Or","Or")',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
private static $defaults = array(
|
private static $defaults = array(
|
||||||
'ShowOnLoad' => true,
|
'ShowOnLoad' => true,
|
||||||
);
|
);
|
||||||
@ -125,6 +138,22 @@ class EditableFormField extends DataObject
|
|||||||
*/
|
*/
|
||||||
protected $readonly;
|
protected $readonly;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property holds the JS event which gets fired for this type of element
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $jsEventHandler = 'change';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the jsEventHandler property for the current object. Bearing in mind it could've been overridden.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getJsEventHandler()
|
||||||
|
{
|
||||||
|
return $this->jsEventHandler;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the visibility of an individual form field
|
* Set the visibility of an individual form field
|
||||||
*
|
*
|
||||||
@ -161,6 +190,7 @@ class EditableFormField extends DataObject
|
|||||||
_t('EditableFormField.TYPE', 'Type'),
|
_t('EditableFormField.TYPE', 'Type'),
|
||||||
$this->i18n_singular_name()
|
$this->i18n_singular_name()
|
||||||
),
|
),
|
||||||
|
CheckboxField::create('ShowInSummary', _t('EditableFormField.SHOWINSUMMARY', 'Show in summary gridfield')),
|
||||||
LiteralField::create(
|
LiteralField::create(
|
||||||
'MergeField',
|
'MergeField',
|
||||||
_t(
|
_t(
|
||||||
@ -228,6 +258,17 @@ class EditableFormField extends DataObject
|
|||||||
$fields->addFieldsToTab('Root.DisplayRules', $displayFields);
|
$fields->addFieldsToTab('Root.DisplayRules', $displayFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Placeholder
|
||||||
|
if ($this->config()->has_placeholder) {
|
||||||
|
$fields->addFieldToTab(
|
||||||
|
'Root.Main',
|
||||||
|
TextField::create(
|
||||||
|
'Placeholder',
|
||||||
|
_t('EditableFormField.PLACEHOLDER', 'Placeholder')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$this->extend('updateCMSFields', $fields);
|
$this->extend('updateCMSFields', $fields);
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
@ -243,35 +284,27 @@ class EditableFormField extends DataObject
|
|||||||
// Check display rules
|
// Check display rules
|
||||||
if ($this->Required) {
|
if ($this->Required) {
|
||||||
return new FieldList(
|
return new FieldList(
|
||||||
LabelField::create(_t(
|
LabelField::create(
|
||||||
|
_t(
|
||||||
'EditableFormField.DISPLAY_RULES_DISABLED',
|
'EditableFormField.DISPLAY_RULES_DISABLED',
|
||||||
'Display rules are not enabled for required fields. ' .
|
'Display rules are not enabled for required fields. Please uncheck "Is this field Required?" under "Validation" to re-enable.'))
|
||||||
'Please uncheck "Is this field Required?" under "Validation" to re-enable.'
|
->addExtraClass('message warning'));
|
||||||
))->addExtraClass('message warning')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
$self = $this;
|
$self = $this;
|
||||||
$allowedClasses = array_keys($this->getEditableFieldClasses(false));
|
$allowedClasses = array_keys($this->getEditableFieldClasses(false));
|
||||||
$editableColumns = new GridFieldEditableColumns();
|
$editableColumns = new GridFieldEditableColumns();
|
||||||
$editableColumns->setDisplayFields(array(
|
$editableColumns->setDisplayFields(array(
|
||||||
'Display' => '',
|
|
||||||
'ConditionFieldID' => function ($record, $column, $grid) use ($allowedClasses, $self) {
|
'ConditionFieldID' => function ($record, $column, $grid) use ($allowedClasses, $self) {
|
||||||
return DropdownField::create(
|
return DropdownField::create($column, '', EditableFormField::get()->filter(array(
|
||||||
$column,
|
|
||||||
'',
|
|
||||||
EditableFormField::get()
|
|
||||||
->filter(array(
|
|
||||||
'ParentID' => $self->ParentID,
|
'ParentID' => $self->ParentID,
|
||||||
'ClassName' => $allowedClasses
|
'ClassName' => $allowedClasses,
|
||||||
))
|
))->exclude(array(
|
||||||
->exclude(array(
|
'ID' => $self->ID,
|
||||||
'ID' => $self->ID
|
))->map('ID', 'Title'));
|
||||||
))
|
|
||||||
->map('ID', 'Title')
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
'ConditionOption' => function ($record, $column, $grid) {
|
'ConditionOption' => function ($record, $column, $grid) {
|
||||||
$options = Config::inst()->get('EditableCustomRule', 'condition_options');
|
$options = Config::inst()->get('EditableCustomRule', 'condition_options');
|
||||||
|
|
||||||
return DropdownField::create($column, '', $options);
|
return DropdownField::create($column, '', $options);
|
||||||
},
|
},
|
||||||
'FieldValue' => function ($record, $column, $grid) {
|
'FieldValue' => function ($record, $column, $grid) {
|
||||||
@ -279,7 +312,7 @@ class EditableFormField extends DataObject
|
|||||||
},
|
},
|
||||||
'ParentID' => function ($record, $column, $grid) use ($self) {
|
'ParentID' => function ($record, $column, $grid) use ($self) {
|
||||||
return HiddenField::create($column, '', $self->ID);
|
return HiddenField::create($column, '', $self->ID);
|
||||||
}
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
// Custom rules
|
// Custom rules
|
||||||
@ -293,11 +326,20 @@ class EditableFormField extends DataObject
|
|||||||
);
|
);
|
||||||
|
|
||||||
return new FieldList(
|
return new FieldList(
|
||||||
CheckboxField::create('ShowOnLoad')
|
DropdownField::create('ShowOnLoad',
|
||||||
->setDescription(_t(
|
_t('EditableFormField.INITIALVISIBILITY', 'Initial visibility'),
|
||||||
'EditableFormField.SHOWONLOAD',
|
array(
|
||||||
'Initial visibility before processing these rules'
|
1 => 'Show',
|
||||||
)),
|
0 => 'Hide',
|
||||||
|
)
|
||||||
|
),
|
||||||
|
DropdownField::create('DisplayRulesConjunction',
|
||||||
|
_t('EditableFormField.DISPLAYIF', 'Toggle visibility when'),
|
||||||
|
array(
|
||||||
|
'Or' => _t('UserDefinedForm.SENDIFOR', 'Any conditions are true'),
|
||||||
|
'And' => _t('UserDefinedForm.SENDIFAND', 'All conditions are true'),
|
||||||
|
)
|
||||||
|
),
|
||||||
GridField::create(
|
GridField::create(
|
||||||
'DisplayRules',
|
'DisplayRules',
|
||||||
_t('EditableFormField.CUSTOMRULES', 'Custom Rules'),
|
_t('EditableFormField.CUSTOMRULES', 'Custom Rules'),
|
||||||
@ -819,6 +861,16 @@ class EditableFormField extends DataObject
|
|||||||
if ($this->ExtraClass) {
|
if ($this->ExtraClass) {
|
||||||
$field->addExtraClass($this->ExtraClass);
|
$field->addExtraClass($this->ExtraClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if ShowOnLoad is false hide the field
|
||||||
|
if (!$this->ShowOnLoad) {
|
||||||
|
$field->addExtraClass($this->ShowOnLoadNice());
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this field has a placeholder
|
||||||
|
if ($this->Placeholder) {
|
||||||
|
$field->setAttribute('placeholder', $this->Placeholder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -913,7 +965,17 @@ class EditableFormField extends DataObject
|
|||||||
*/
|
*/
|
||||||
public function getSelectorHolder()
|
public function getSelectorHolder()
|
||||||
{
|
{
|
||||||
return "$(\"#{$this->Name}\")";
|
return sprintf('$("%s")', $this->getSelectorOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns only the JS identifier of a string, less the $(), which can be inserted elsewhere, for example when you
|
||||||
|
* want to perform selections on multiple selectors
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSelectorOnly()
|
||||||
|
{
|
||||||
|
return "#{$this->Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -921,10 +983,20 @@ class EditableFormField extends DataObject
|
|||||||
*
|
*
|
||||||
* @param EditableCustomRule $rule Custom rule this selector will be used with
|
* @param EditableCustomRule $rule Custom rule this selector will be used with
|
||||||
* @param bool $forOnLoad Set to true if this will be invoked on load
|
* @param bool $forOnLoad Set to true if this will be invoked on load
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false)
|
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false)
|
||||||
{
|
{
|
||||||
return "$(\"input[name='{$this->Name}']\")";
|
return sprintf("$(%s)", $this->getSelectorFieldOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSelectorFieldOnly()
|
||||||
|
{
|
||||||
|
return "[name='{$this->Name}']";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -984,4 +1056,95 @@ class EditableFormField extends DataObject
|
|||||||
}
|
}
|
||||||
return $this->DisplayRules();
|
return $this->DisplayRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts info from DisplayRules into array so UserDefinedForm->buildWatchJS can run through it.
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public function formatDisplayRules()
|
||||||
|
{
|
||||||
|
$holderSelector = $this->getSelectorOnly();
|
||||||
|
$result = array(
|
||||||
|
'targetFieldID' => $holderSelector,
|
||||||
|
'conjunction' => $this->DisplayRulesConjunctionNice(),
|
||||||
|
'selectors' => array(),
|
||||||
|
'events' => array(),
|
||||||
|
'operations' => array(),
|
||||||
|
'initialState' => $this->ShowOnLoadNice(),
|
||||||
|
'view' => array(),
|
||||||
|
'opposite' => array(),
|
||||||
|
);
|
||||||
|
// Check for field dependencies / default
|
||||||
|
/** @var EditableCustomRule $rule */
|
||||||
|
foreach ($this->EffectiveDisplayRules() as $rule) {
|
||||||
|
// Get the field which is effected
|
||||||
|
/** @var EditableFormField $formFieldWatch */
|
||||||
|
$formFieldWatch = EditableFormField::get()->byId($rule->ConditionFieldID);
|
||||||
|
// Skip deleted fields
|
||||||
|
if (! $formFieldWatch) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$fieldToWatch = $formFieldWatch->getSelectorFieldOnly();
|
||||||
|
|
||||||
|
$expression = $rule->buildExpression();
|
||||||
|
if (! in_array($fieldToWatch, $result['selectors'])) {
|
||||||
|
$result['selectors'][] = $fieldToWatch;
|
||||||
|
}
|
||||||
|
if (! in_array($expression['event'], $result['events'])) {
|
||||||
|
$result['events'][] = $expression['event'];
|
||||||
|
}
|
||||||
|
$result['operations'][] = $expression['operation'];
|
||||||
|
|
||||||
|
//View/Show should read
|
||||||
|
$result['view'] = $rule->toggleDisplayText($result['initialState']);
|
||||||
|
$result['opposite'] = $rule->toggleDisplayText($result['view']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (count($result['selectors'])) ? $result : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the set DisplayRulesConjunction with their JS logical operators
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function DisplayRulesConjunctionNice()
|
||||||
|
{
|
||||||
|
return (strtolower($this->DisplayRulesConjunction) === 'or') ? '||' : '&&';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces boolean ShowOnLoad with its JS string equivalent
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function ShowOnLoadNice()
|
||||||
|
{
|
||||||
|
return ($this->ShowOnLoad) ? 'show' : 'hide';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this is of type EditableCheckBoxField
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isCheckBoxField()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this is of type EditableRadioField
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isRadioField()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determined is this is of type EditableCheckboxGroupField
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isCheckBoxGroupField()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
0
code/model/editableformfields/EditableFormHeading.php
Executable file → Normal file
0
code/model/editableformfields/EditableFormHeading.php
Executable file → Normal file
@ -145,7 +145,7 @@ class EditableLiteralField extends EditableFormField
|
|||||||
Convert::raw2htmlname($this->Name),
|
Convert::raw2htmlname($this->Name),
|
||||||
Convert::raw2att($classes),
|
Convert::raw2att($classes),
|
||||||
$label,
|
$label,
|
||||||
$this->Content
|
$this->dbObject('Content')->forTemplate()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -33,8 +33,7 @@ class EditableMultipleOptionField extends EditableFormField
|
|||||||
*/
|
*/
|
||||||
public function getCMSFields()
|
public function getCMSFields()
|
||||||
{
|
{
|
||||||
$fields = parent::getCMSFields();
|
$this->beforeUpdateCMSFields(function($fields) {
|
||||||
|
|
||||||
$editableColumns = new GridFieldEditableColumns();
|
$editableColumns = new GridFieldEditableColumns();
|
||||||
$editableColumns->setDisplayFields(array(
|
$editableColumns->setDisplayFields(array(
|
||||||
'Title' => array(
|
'Title' => array(
|
||||||
@ -77,6 +76,9 @@ class EditableMultipleOptionField extends EditableFormField
|
|||||||
|
|
||||||
$fields->insertAfter(new Tab('Options', _t('EditableMultipleOptionField.OPTIONSTAB', 'Options')), 'Main');
|
$fields->insertAfter(new Tab('Options', _t('EditableMultipleOptionField.OPTIONSTAB', 'Options')), 'Main');
|
||||||
$fields->addFieldToTab('Root.Options', $optionsGrid);
|
$fields->addFieldToTab('Root.Options', $optionsGrid);
|
||||||
|
});
|
||||||
|
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,11 @@ class EditableNumericField extends EditableFormField
|
|||||||
|
|
||||||
private static $plural_name = 'Numeric Fields';
|
private static $plural_name = 'Numeric Fields';
|
||||||
|
|
||||||
|
private static $has_placeholder = true;
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'MinValue' => 'Int',
|
'MinValue' => 'Int',
|
||||||
'MaxValue' => 'Int',
|
'MaxValue' => 'Int'
|
||||||
'Placeholder' => 'Varchar(255)'
|
|
||||||
);
|
);
|
||||||
|
|
||||||
public function getSetsOwnError()
|
public function getSetsOwnError()
|
||||||
@ -25,21 +26,6 @@ class EditableNumericField extends EditableFormField
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCMSFields()
|
|
||||||
{
|
|
||||||
$this->beforeUpdateCMSFields(function ($fields) {
|
|
||||||
$fields->addFieldToTab(
|
|
||||||
'Root.Main',
|
|
||||||
TextField::create(
|
|
||||||
'Placeholder',
|
|
||||||
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return parent::getCMSFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return NumericField
|
* @return NumericField
|
||||||
*/
|
*/
|
||||||
@ -85,9 +71,5 @@ class EditableNumericField extends EditableFormField
|
|||||||
if ($this->MaxValue) {
|
if ($this->MaxValue) {
|
||||||
$field->setAttribute('data-rule-max', $this->MaxValue);
|
$field->setAttribute('data-rule-max', $this->MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->Placeholder) {
|
|
||||||
$field->setAttribute('placeholder', $this->Placeholder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,4 +46,8 @@ class EditableRadioField extends EditableMultipleOptionField
|
|||||||
$first = $forOnLoad ? ':first' : '';
|
$first = $forOnLoad ? ':first' : '';
|
||||||
return "$(\"input[name='{$this->Name}']{$first}\")";
|
return "$(\"input[name='{$this->Name}']{$first}\")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isRadioField() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
54
code/model/editableformfields/EditableTextField.php
Executable file → Normal file
54
code/model/editableformfields/EditableTextField.php
Executable file → Normal file
@ -14,11 +14,45 @@ class EditableTextField extends EditableFormField
|
|||||||
|
|
||||||
private static $plural_name = 'Text Fields';
|
private static $plural_name = 'Text Fields';
|
||||||
|
|
||||||
|
private static $has_placeholder = true;
|
||||||
|
|
||||||
|
private static $autocomplete_options = array(
|
||||||
|
'off' => 'Off',
|
||||||
|
'on' => 'On',
|
||||||
|
'name' => 'Full name',
|
||||||
|
'honorific-prefix' => 'Prefix or title',
|
||||||
|
'given-name' => 'First name',
|
||||||
|
'additional-name' => 'Additional name',
|
||||||
|
'family-name' => 'Family name',
|
||||||
|
'honorific-suffix' => 'Suffix (e.g Jr.)',
|
||||||
|
'nickname' => 'Nickname',
|
||||||
|
'email' => 'Email',
|
||||||
|
'organization-title' => 'Job title',
|
||||||
|
'organization' => 'Organization',
|
||||||
|
'street-address' => 'Street address',
|
||||||
|
'address-line1' => 'Address line 1',
|
||||||
|
'address-line2' => 'Address line 2',
|
||||||
|
'address-line3' => 'Address line 3',
|
||||||
|
'address-level1' => 'Address level 1',
|
||||||
|
'address-level2' => 'Address level 2',
|
||||||
|
'address-level3' => 'Address level 3',
|
||||||
|
'address-level4' => 'Address level 4',
|
||||||
|
'country' => 'Country',
|
||||||
|
'country-name' => 'Country name',
|
||||||
|
'postal-code' => 'Postal code',
|
||||||
|
'bday' => 'Birthday',
|
||||||
|
'sex' => 'Gender identity',
|
||||||
|
'tel' => 'Telephone number',
|
||||||
|
'url' => 'Home page'
|
||||||
|
);
|
||||||
|
|
||||||
|
protected $jsEventHandler = 'keyup';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'MinLength' => 'Int',
|
'MinLength' => 'Int',
|
||||||
'MaxLength' => 'Int',
|
'MaxLength' => 'Int',
|
||||||
'Rows' => 'Int(1)',
|
'Rows' => 'Int(1)',
|
||||||
'Placeholder' => 'Varchar(255)'
|
'Autocomplete' => 'Varchar(255)'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $defaults = array(
|
private static $defaults = array(
|
||||||
@ -41,11 +75,16 @@ class EditableTextField extends EditableFormField
|
|||||||
|
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
TextField::create(
|
DropdownField::create(
|
||||||
'Placeholder',
|
'Autocomplete',
|
||||||
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
_t('EditableTextField.AUTOCOMPLETE', 'Autocomplete'),
|
||||||
)
|
$this->config()->get('autocomplete_options')
|
||||||
|
)->setDescription(_t(
|
||||||
|
'EditableTextField.AUTOCOMPLETE_DESCRIPTION',
|
||||||
|
'Supported browsers will attempt to populate this field automatically with the users information, use to set the value populated'
|
||||||
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return parent::getCMSFields();
|
return parent::getCMSFields();
|
||||||
@ -113,8 +152,9 @@ class EditableTextField extends EditableFormField
|
|||||||
$field->setAttribute('data-rule-maxlength', intval($this->MaxLength));
|
$field->setAttribute('data-rule-maxlength', intval($this->MaxLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->Placeholder) {
|
if ($this->Autocomplete) {
|
||||||
$field->setAttribute('placeholder', $this->Placeholder);
|
$field->setAttribute('autocomplete', $this->Autocomplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,7 @@ class UserFormsUpgradeService
|
|||||||
// - MinLength (EditableTextField)
|
// - MinLength (EditableTextField)
|
||||||
// - MaxLength (EditableTextField)
|
// - MaxLength (EditableTextField)
|
||||||
// - Rows (EditableTextField)
|
// - Rows (EditableTextField)
|
||||||
|
// - Placeholder (EditableTextField / EditableEmailField / EditableNumericField)
|
||||||
|
|
||||||
$customSettings = $field->CustomSettings
|
$customSettings = $field->CustomSettings
|
||||||
? unserialize($field->CustomSettings)
|
? unserialize($field->CustomSettings)
|
||||||
@ -142,6 +143,11 @@ class UserFormsUpgradeService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$field->migrateSettings($customSettings);
|
$field->migrateSettings($customSettings);
|
||||||
|
|
||||||
|
if ($field->config()->has_placeholder) {
|
||||||
|
$this->migratePlaceholder($field, $field->ClassName);
|
||||||
|
}
|
||||||
|
|
||||||
$field->write();
|
$field->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,4 +230,62 @@ class UserFormsUpgradeService
|
|||||||
{
|
{
|
||||||
return $this->quiet;
|
return $this->quiet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate Placeholder data from field specific table to the EditableFormField table
|
||||||
|
*
|
||||||
|
* @param EditableFormField $field
|
||||||
|
* @param string $tableName
|
||||||
|
*/
|
||||||
|
private function migratePlaceholder($field, $tableName)
|
||||||
|
{
|
||||||
|
// Migrate Placeholder setting from $tableName table to EditableFormField table
|
||||||
|
if ($field->Placeholder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check if draft table exists
|
||||||
|
if (!DB::get_schema()->hasTable($tableName)) {
|
||||||
|
// Check if _obsolete_ draft table exists
|
||||||
|
$tableName = '_obsolete_' . $tableName;
|
||||||
|
if (!DB::get_schema()->hasTable($tableName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if old Placeholder column exists
|
||||||
|
if (!DB::get_schema()->hasField($tableName, 'Placeholder')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Fetch existing draft Placeholder value
|
||||||
|
$query = "SELECT \"Placeholder\" FROM \"$tableName\" WHERE \"ID\" = '$field->ID'";
|
||||||
|
$draftPlaceholder = DB::query($query)->value();
|
||||||
|
|
||||||
|
if (!$draftPlaceholder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Update draft Placeholder value
|
||||||
|
DB::prepared_query(
|
||||||
|
"UPDATE \"EditableFormField\" SET \"Placeholder\" = ? WHERE \"ID\" = ?",
|
||||||
|
array($draftPlaceholder, $field->ID)
|
||||||
|
);
|
||||||
|
|
||||||
|
$livePlaceholder = $draftPlaceholder;
|
||||||
|
|
||||||
|
// Check if live table exists
|
||||||
|
$tableName = $tableName . '_Live';
|
||||||
|
if (DB::get_schema()->hasTable($tableName)) {
|
||||||
|
// Fetch existing live Placeholder value
|
||||||
|
$query = "SELECT \"Placeholder\" FROM \"$tableName\" WHERE \"ID\" = '" . $field->ID . "'";
|
||||||
|
$livePlaceholder = DB::query($query)->value();
|
||||||
|
if (!$livePlaceholder) {
|
||||||
|
$livePlaceholder = $draftPlaceholder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update live Placeholder value
|
||||||
|
DB::prepared_query(
|
||||||
|
"UPDATE \"EditableFormField_Live\" SET \"Placeholder\" = ? WHERE \"ID\" = ?",
|
||||||
|
array($draftPlaceholder, $field->ID)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,12 @@
|
|||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"colymba/gridfield-bulk-editing-tools": "Allows for bulk management of form submissions",
|
"colymba/gridfield-bulk-editing-tools": "Allows for bulk management of form submissions",
|
||||||
"silverstripe/secureassets": "Enables files uploaded via userforms to be secured from public access"
|
"silverstripe/secureassets": "Enables files uploaded via userforms to be secured from public access",
|
||||||
|
"silverstripe/gridfieldqueuedexport": "Export large submission as CSV through queued jobs in the background"
|
||||||
},
|
},
|
||||||
"extra": []
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-4.x-dev": "4.4.x-dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -72,3 +72,7 @@
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.userform .field.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@ -18,3 +18,10 @@ it then grabs the columns for the live database it will create a backup of the t
|
|||||||
are surplus.
|
are surplus.
|
||||||
|
|
||||||
To run the task login as Admin and go to to http://yoursite/dev/tasks/UserFormsColumnCleanTask
|
To run the task login as Admin and go to to http://yoursite/dev/tasks/UserFormsColumnCleanTask
|
||||||
|
|
||||||
|
## My CSV export times out or runs out of memory
|
||||||
|
|
||||||
|
You likely have too many submissions to fit within the PHP constraints
|
||||||
|
on your server (execution time and memory). If you can't increase these limits,
|
||||||
|
consider installing the [gridfieldqueuedexport](https://github.com/silverstripe/silverstripe-gridfieldqueuedexport) module. It uses [queuedjobs](https://github.com/silverstripe-australia/silverstripe-queuedjobs) to export
|
||||||
|
submissions in the background, providing users with a progress indicator.
|
@ -18,6 +18,7 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
|
|||||||
"UserForms.HIDE_OPTIONS": "Skryť možnosti",
|
"UserForms.HIDE_OPTIONS": "Skryť možnosti",
|
||||||
"UserForms.LEAVE_CONFIRMATION": "Máte neuložené zmeny!",
|
"UserForms.LEAVE_CONFIRMATION": "Máte neuložené zmeny!",
|
||||||
"UserForms.REMOVED_OPTION": "Voľba/možnosť odstránená",
|
"UserForms.REMOVED_OPTION": "Voľba/možnosť odstránená",
|
||||||
"UserForms.SHOW_OPTIONS": "Zobraziť možnosti"
|
"UserForms.SHOW_OPTIONS": "Zobraziť možnosti",
|
||||||
|
"UserForms.ERROR_CONTAINER_HEADER": "Opravte prosím nasledujúce chyby a skúste to znova:"
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -64,6 +64,7 @@ de_DE:
|
|||||||
NOTBLANK: 'Nicht leer'
|
NOTBLANK: 'Nicht leer'
|
||||||
NOTVALUE: 'Kein Wert'
|
NOTVALUE: 'Kein Wert'
|
||||||
OPTIONS: Optionen
|
OPTIONS: Optionen
|
||||||
|
PLACEHOLDER: Platzhalter
|
||||||
PLURALNAME: 'Editierbare Formularfelder'
|
PLURALNAME: 'Editierbare Formularfelder'
|
||||||
REQUIRED: 'Pflichtfeld?'
|
REQUIRED: 'Pflichtfeld?'
|
||||||
RIGHTTITLE: 'Titel rechts'
|
RIGHTTITLE: 'Titel rechts'
|
||||||
@ -108,8 +109,9 @@ de_DE:
|
|||||||
PLURALNAME: Radio-Buttons
|
PLURALNAME: Radio-Buttons
|
||||||
SINGULARNAME: Radio-Button
|
SINGULARNAME: Radio-Button
|
||||||
EditableTextField:
|
EditableTextField:
|
||||||
|
AUTOCOMPLETE: 'Automatisch vervollständigen'
|
||||||
|
AUTOCOMPLETE_DESCRIPTION: 'Unterstützte Browser versuchen, dieses Feld automatisch mit den Benutzerinformationen zu füllen, verwenden, um den gefüllten Wert festzulegen'
|
||||||
NUMBERROWS: 'Anzahl der Zeilen'
|
NUMBERROWS: 'Anzahl der Zeilen'
|
||||||
PLACEHOLDER: Platzhalter
|
|
||||||
PLURALNAME: Textfelder
|
PLURALNAME: Textfelder
|
||||||
SINGULARNAME: Textfeld
|
SINGULARNAME: Textfeld
|
||||||
TEXTLENGTH: Textlänge
|
TEXTLENGTH: Textlänge
|
||||||
|
@ -83,6 +83,7 @@ en:
|
|||||||
NOTBLANK: 'Not Blank'
|
NOTBLANK: 'Not Blank'
|
||||||
NOTVALUE: 'Not Value'
|
NOTVALUE: 'Not Value'
|
||||||
OPTIONS: Options
|
OPTIONS: Options
|
||||||
|
PLACEHOLDER: Placeholder
|
||||||
PLURALNAME: 'Editable Form Fields'
|
PLURALNAME: 'Editable Form Fields'
|
||||||
REQUIRED: 'Is this field Required?'
|
REQUIRED: 'Is this field Required?'
|
||||||
REQUIRED_DESCRIPTION: 'Please note that conditional fields can''t be required'
|
REQUIRED_DESCRIPTION: 'Please note that conditional fields can''t be required'
|
||||||
@ -140,9 +141,10 @@ en:
|
|||||||
PLURALNAME: 'Radio Groups'
|
PLURALNAME: 'Radio Groups'
|
||||||
SINGULARNAME: 'Radio Group'
|
SINGULARNAME: 'Radio Group'
|
||||||
EditableTextField:
|
EditableTextField:
|
||||||
|
AUTOCOMPLETE: 'Autocomplete'
|
||||||
|
AUTOCOMPLETE_DESCRIPTION: 'Supported browsers will attempt to populate this field automatically with the users information, use to set the value populated'
|
||||||
NUMBERROWS: 'Number of rows'
|
NUMBERROWS: 'Number of rows'
|
||||||
NUMBERROWS_DESCRIPTION: 'Fields with more than one row will be generated as a textarea'
|
NUMBERROWS_DESCRIPTION: 'Fields with more than one row will be generated as a textarea'
|
||||||
PLACEHOLDER: Placeholder
|
|
||||||
PLURALNAME: 'Text Fields'
|
PLURALNAME: 'Text Fields'
|
||||||
RANGE_TO: to
|
RANGE_TO: to
|
||||||
SINGULARNAME: 'Text Field'
|
SINGULARNAME: 'Text Field'
|
||||||
|
@ -83,6 +83,7 @@ eo:
|
|||||||
NOTBLANK: 'Ne vaka'
|
NOTBLANK: 'Ne vaka'
|
||||||
NOTVALUE: 'Ne valoro'
|
NOTVALUE: 'Ne valoro'
|
||||||
OPTIONS: Agordoj
|
OPTIONS: Agordoj
|
||||||
|
PLACEHOLDER: Lokokupilo
|
||||||
PLURALNAME: 'Redakteblaj formularaj kampoj'
|
PLURALNAME: 'Redakteblaj formularaj kampoj'
|
||||||
REQUIRED: 'Ĉu ĉi tiu kampo estas nepra?'
|
REQUIRED: 'Ĉu ĉi tiu kampo estas nepra?'
|
||||||
REQUIRED_DESCRIPTION: 'Bonvolu noti ke kondiĉaj kampoj ne povas esti nepraj'
|
REQUIRED_DESCRIPTION: 'Bonvolu noti ke kondiĉaj kampoj ne povas esti nepraj'
|
||||||
@ -142,7 +143,6 @@ eo:
|
|||||||
EditableTextField:
|
EditableTextField:
|
||||||
NUMBERROWS: 'Nombro da vicoj'
|
NUMBERROWS: 'Nombro da vicoj'
|
||||||
NUMBERROWS_DESCRIPTION: 'Kampoj kun pli ol unu vico generiĝos kiel tekstareo'
|
NUMBERROWS_DESCRIPTION: 'Kampoj kun pli ol unu vico generiĝos kiel tekstareo'
|
||||||
PLACEHOLDER: Lokokupilo
|
|
||||||
PLURALNAME: 'Tekstaj kampoj'
|
PLURALNAME: 'Tekstaj kampoj'
|
||||||
RANGE_TO: al
|
RANGE_TO: al
|
||||||
SINGULARNAME: 'Teksta kampo'
|
SINGULARNAME: 'Teksta kampo'
|
||||||
|
@ -106,6 +106,8 @@ es_ES:
|
|||||||
PLURALNAME: 'Opciones editables'
|
PLURALNAME: 'Opciones editables'
|
||||||
SINGULARNAME: 'Opciones editables'
|
SINGULARNAME: 'Opciones editables'
|
||||||
EditableTextField:
|
EditableTextField:
|
||||||
|
AUTOCOMPLETE: 'Autocompletar'
|
||||||
|
AUTOCOMPLETE_DESCRIPTION: 'Los navegadores compatibles intentarán rellenar este campo automáticamente con la información de los usuarios, usarla para establecer el valor poblado'
|
||||||
NUMBERROWS: 'Cantidad de filas'
|
NUMBERROWS: 'Cantidad de filas'
|
||||||
PLURALNAME: 'Campos de texto'
|
PLURALNAME: 'Campos de texto'
|
||||||
SINGULARNAME: 'Campo de texto'
|
SINGULARNAME: 'Campo de texto'
|
||||||
|
@ -83,6 +83,7 @@ fi_FI:
|
|||||||
NOTBLANK: 'Ei ole tyhjä'
|
NOTBLANK: 'Ei ole tyhjä'
|
||||||
NOTVALUE: 'Ei ole sama kuin'
|
NOTVALUE: 'Ei ole sama kuin'
|
||||||
OPTIONS: Valinnat
|
OPTIONS: Valinnat
|
||||||
|
PLACEHOLDER: Opastusteksti
|
||||||
PLURALNAME: 'Muokattavat lomakekentät'
|
PLURALNAME: 'Muokattavat lomakekentät'
|
||||||
REQUIRED: 'Onko tämä kenttä pakollinen?'
|
REQUIRED: 'Onko tämä kenttä pakollinen?'
|
||||||
REQUIRED_DESCRIPTION: 'Huomioithan, että ehdolliset kentät eivät voi olla pakollisia'
|
REQUIRED_DESCRIPTION: 'Huomioithan, että ehdolliset kentät eivät voi olla pakollisia'
|
||||||
@ -142,7 +143,6 @@ fi_FI:
|
|||||||
EditableTextField:
|
EditableTextField:
|
||||||
NUMBERROWS: 'Rivien määrä'
|
NUMBERROWS: 'Rivien määrä'
|
||||||
NUMBERROWS_DESCRIPTION: 'Kenttät, joissa on enemmän kuin yksi rivi, luodaan tekstialueena.'
|
NUMBERROWS_DESCRIPTION: 'Kenttät, joissa on enemmän kuin yksi rivi, luodaan tekstialueena.'
|
||||||
PLACEHOLDER: Opastusteksti
|
|
||||||
PLURALNAME: Tekstikentät
|
PLURALNAME: Tekstikentät
|
||||||
RANGE_TO: –
|
RANGE_TO: –
|
||||||
SINGULARNAME: Tekstikenttä
|
SINGULARNAME: Tekstikenttä
|
||||||
|
@ -60,6 +60,9 @@ fr_FR:
|
|||||||
DELETE: 'Remove this option'
|
DELETE: 'Remove this option'
|
||||||
DRAG: 'Drag to rearrange order of options'
|
DRAG: 'Drag to rearrange order of options'
|
||||||
LOCKED: 'These fields cannot be modified'
|
LOCKED: 'These fields cannot be modified'
|
||||||
|
EditableTextField:
|
||||||
|
AUTOCOMPLETE: 'Autocomplétion'
|
||||||
|
AUTOCOMPLETE_DESCRIPTION: 'Les navigateurs pris en charge essaieront de remplir automatiquement ce champ avec les informations des utilisateurs, utilisez pour définir la valeur remplie'
|
||||||
Form:
|
Form:
|
||||||
FIELDISREQUIRED: '%s is required'
|
FIELDISREQUIRED: '%s is required'
|
||||||
SubmittedFileField:
|
SubmittedFileField:
|
||||||
|
@ -83,6 +83,7 @@ it:
|
|||||||
NOTBLANK: 'Non vuoto'
|
NOTBLANK: 'Non vuoto'
|
||||||
NOTVALUE: 'Non valore'
|
NOTVALUE: 'Non valore'
|
||||||
OPTIONS: Opzioni
|
OPTIONS: Opzioni
|
||||||
|
PLACEHOLDER: Segnaposto
|
||||||
PLURALNAME: 'Campi modulo modificabili'
|
PLURALNAME: 'Campi modulo modificabili'
|
||||||
REQUIRED: 'Questo campo è obbligatorio?'
|
REQUIRED: 'Questo campo è obbligatorio?'
|
||||||
REQUIRED_DESCRIPTION: 'Prego nota che i campi condizionali non possono essere obbligatori'
|
REQUIRED_DESCRIPTION: 'Prego nota che i campi condizionali non possono essere obbligatori'
|
||||||
@ -140,9 +141,10 @@ it:
|
|||||||
PLURALNAME: 'Gruppi di pulsanti a scelta singola'
|
PLURALNAME: 'Gruppi di pulsanti a scelta singola'
|
||||||
SINGULARNAME: 'Gruppo di pulsanti a scelta singola'
|
SINGULARNAME: 'Gruppo di pulsanti a scelta singola'
|
||||||
EditableTextField:
|
EditableTextField:
|
||||||
|
AUTOCOMPLETE: 'completamento automatico'
|
||||||
|
AUTOCOMPLETE_DESCRIPTION: 'I browser supportati cercheranno di popolare automaticamente questo campo con l'informazione agli utenti, usare per impostare il valore popolata'
|
||||||
NUMBERROWS: 'Numero di righe'
|
NUMBERROWS: 'Numero di righe'
|
||||||
NUMBERROWS_DESCRIPTION: 'Campi con più di una riga verranno generati come area testo'
|
NUMBERROWS_DESCRIPTION: 'Campi con più di una riga verranno generati come area testo'
|
||||||
PLACEHOLDER: Segnaposto
|
|
||||||
PLURALNAME: 'Campi testo'
|
PLURALNAME: 'Campi testo'
|
||||||
RANGE_TO: a
|
RANGE_TO: a
|
||||||
SINGULARNAME: 'Campo testo'
|
SINGULARNAME: 'Campo testo'
|
||||||
|
@ -103,6 +103,8 @@ pl_PL:
|
|||||||
PLURALNAME: 'Pola wyboru'
|
PLURALNAME: 'Pola wyboru'
|
||||||
SINGULARNAME: 'Pole wyboru'
|
SINGULARNAME: 'Pole wyboru'
|
||||||
EditableTextField:
|
EditableTextField:
|
||||||
|
AUTOCOMPLETE: 'autouzupełnienie'
|
||||||
|
AUTOCOMPLETE_DESCRIPTION: 'Obsługiwane przeglądarki podejmie próbę wypełnienia tego pola automatycznie z informacji użytkowników, należy ustawić wartość zaludnionych'
|
||||||
NUMBERROWS: 'Liczba wierszy'
|
NUMBERROWS: 'Liczba wierszy'
|
||||||
PLURALNAME: 'Pola tekstowe'
|
PLURALNAME: 'Pola tekstowe'
|
||||||
SINGULARNAME: 'Pole tekstowe'
|
SINGULARNAME: 'Pole tekstowe'
|
||||||
|
@ -60,6 +60,9 @@ ru_RU:
|
|||||||
DELETE: 'Remove this option'
|
DELETE: 'Remove this option'
|
||||||
DRAG: 'Drag to rearrange order of options'
|
DRAG: 'Drag to rearrange order of options'
|
||||||
LOCKED: 'These fields cannot be modified'
|
LOCKED: 'These fields cannot be modified'
|
||||||
|
EditableTextField:
|
||||||
|
AUTOCOMPLETE: 'автозаполнения'
|
||||||
|
AUTOCOMPLETE_DESCRIPTION: 'Поддерживаемые браузеры будут пытаться автоматически заполнять это поле с информацией пользователей, используйте для установки значения населенную'
|
||||||
Form:
|
Form:
|
||||||
FIELDISREQUIRED: '%s is required'
|
FIELDISREQUIRED: '%s is required'
|
||||||
SubmittedFileField:
|
SubmittedFileField:
|
||||||
|
@ -83,6 +83,7 @@ sk:
|
|||||||
NOTBLANK: Vyplnené
|
NOTBLANK: Vyplnené
|
||||||
NOTVALUE: 'Nie zadanú hodnotu'
|
NOTVALUE: 'Nie zadanú hodnotu'
|
||||||
OPTIONS: Voľba/možnosť
|
OPTIONS: Voľba/možnosť
|
||||||
|
PLACEHOLDER: 'Zástupná/Ukážková hodnota (placeholder)'
|
||||||
PLURALNAME: 'Formulárové polia'
|
PLURALNAME: 'Formulárové polia'
|
||||||
REQUIRED: 'Je pole povinné/vyžadované?'
|
REQUIRED: 'Je pole povinné/vyžadované?'
|
||||||
REQUIRED_DESCRIPTION: 'Všimnite si prosím, že podmienené polia nemôžu byť vyžadované.'
|
REQUIRED_DESCRIPTION: 'Všimnite si prosím, že podmienené polia nemôžu byť vyžadované.'
|
||||||
@ -142,7 +143,6 @@ sk:
|
|||||||
EditableTextField:
|
EditableTextField:
|
||||||
NUMBERROWS: 'Počet riadkov'
|
NUMBERROWS: 'Počet riadkov'
|
||||||
NUMBERROWS_DESCRIPTION: 'Políčka s viac ako jedným riadkom sú generované ako textarea.'
|
NUMBERROWS_DESCRIPTION: 'Políčka s viac ako jedným riadkom sú generované ako textarea.'
|
||||||
PLACEHOLDER: 'Zástupná/Ukážková hodnota (placeholder)'
|
|
||||||
PLURALNAME: 'Textové polia'
|
PLURALNAME: 'Textové polia'
|
||||||
RANGE_TO: do
|
RANGE_TO: do
|
||||||
SINGULARNAME: 'Textové pole'
|
SINGULARNAME: 'Textové pole'
|
||||||
|
31
tests/EditableCustomRuleTest.php
Normal file
31
tests/EditableCustomRuleTest.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class EditableCustomRulesTest
|
||||||
|
*/
|
||||||
|
class EditableCustomRuleTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected static $fixture_file = 'userforms/tests/EditableCustomRuleTest.yml';
|
||||||
|
|
||||||
|
public function testBuildExpression()
|
||||||
|
{
|
||||||
|
/** @var EditableCustomRule $rule1 */
|
||||||
|
$rule1 = $this->objFromFixture('EditableCustomRule', 'rule1');
|
||||||
|
$result1 = $rule1->buildExpression();
|
||||||
|
|
||||||
|
//Dropdowns expect change event
|
||||||
|
$this->assertEquals('change', $result1['event']);
|
||||||
|
$this->assertNotEmpty($result1['operation']);
|
||||||
|
//Check for equals sign
|
||||||
|
$this->assertContains('==', $result1['operation']);
|
||||||
|
|
||||||
|
/** @var EditableCustomRule $rule2 */
|
||||||
|
$rule2 = $this->objFromFixture('EditableCustomRule', 'rule2');
|
||||||
|
$result2 = $rule2->buildExpression();
|
||||||
|
//TextField expect change event
|
||||||
|
$this->assertEquals('keyup', $result2['event']);
|
||||||
|
$this->assertNotEmpty($result2['operation']);
|
||||||
|
//Check for greater than sign
|
||||||
|
$this->assertContains('>', $result2['operation']);
|
||||||
|
}
|
||||||
|
}
|
30
tests/EditableCustomRuleTest.yml
Normal file
30
tests/EditableCustomRuleTest.yml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
EditableFormField:
|
||||||
|
countryDropdown:
|
||||||
|
ClassName: EditableCountryDropdownField
|
||||||
|
Name: CountrySelection
|
||||||
|
Title: "Choose your country"
|
||||||
|
DisplayRulesConjunction: And
|
||||||
|
ShowOnLoad: false
|
||||||
|
irdNumberField:
|
||||||
|
ClassName: EditableTextField
|
||||||
|
Name: IRDNumber
|
||||||
|
Title: "Enter your IRD Number"
|
||||||
|
countryTextField:
|
||||||
|
ClassName: EditableTextField
|
||||||
|
Name: CountryTextSelection
|
||||||
|
Title: "Enter your country (2 digit prefix)"
|
||||||
|
DisplayRulesConjunction: And
|
||||||
|
ShowOnLoad: false
|
||||||
|
EditableCustomRule:
|
||||||
|
rule1:
|
||||||
|
Display: Show
|
||||||
|
ConditionOption: HasValue
|
||||||
|
FieldValue: NZ
|
||||||
|
ConditionField: =>EditableFormField.countryDropdown
|
||||||
|
Parent: =>EditableFormField.irdNumberField
|
||||||
|
rule2:
|
||||||
|
Display: Show
|
||||||
|
ConditionOption: ValueGreaterThan
|
||||||
|
FieldValue: 1
|
||||||
|
ConditionField: =>EditableFormField.countryTextField
|
||||||
|
Parent: =>EditableFormField.irdNumberField
|
42
tests/EditableDropdownTest.php
Normal file
42
tests/EditableDropdownTest.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the {@see EditableDropdown} class
|
||||||
|
*/
|
||||||
|
class EditableDropdownTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
|
public static $fixture_file = 'userforms/tests/EditableFormFieldTest.yml';
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that the field sets the empty string if set
|
||||||
|
*/
|
||||||
|
public function testFormField()
|
||||||
|
{
|
||||||
|
if (!$dropdown = EditableDropdown::get()->filter('UseEmptyString', true)->first()) {
|
||||||
|
$dropdown = $this->objFromFixture('EditableDropdown', 'basic-dropdown');
|
||||||
|
|
||||||
|
$dropdown->UseEmptyString = true;
|
||||||
|
$dropdown->EmptyString = 'My Default Empty String';
|
||||||
|
$dropdown->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
$field = $dropdown->getFormField();
|
||||||
|
$this->assertEquals($field->getEmptyString(), 'My Default Empty String');
|
||||||
|
|
||||||
|
$alternateDropdown = $this->objFromFixture('EditableDropdown', 'department-dropdown');
|
||||||
|
$formField = $alternateDropdown->getFormField();
|
||||||
|
$this->assertFalse($formField->getHasEmptyDefault());
|
||||||
|
|
||||||
|
$alternateDropdown->UseEmptyString = true;
|
||||||
|
$alternateDropdown->write();
|
||||||
|
$this->assertEquals($formField->getEmptyString(), '');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -204,4 +204,13 @@ class EditableFormFieldTest extends FunctionalTest
|
|||||||
$this->assertEquals(10, $attributes['data-rule-minlength']);
|
$this->assertEquals(10, $attributes['data-rule-minlength']);
|
||||||
$this->assertEquals(20, $attributes['data-rule-maxlength']);
|
$this->assertEquals(20, $attributes['data-rule-maxlength']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFormatDisplayRules()
|
||||||
|
{
|
||||||
|
/** @var EditableCheckbox $checkbox */
|
||||||
|
$checkbox = $this->objFromFixture('EditableFormField', 'irdNumberField');
|
||||||
|
$displayRules = $checkbox->formatDisplayRules();
|
||||||
|
$this->assertNotNull($displayRules);
|
||||||
|
$this->assertCount(1, $displayRules['operations']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,25 @@
|
|||||||
|
EditableFormField:
|
||||||
|
irdNumberField:
|
||||||
|
ClassName: EditableTextField
|
||||||
|
Name: IRDNumber
|
||||||
|
Title: "Enter your IRD Number"
|
||||||
|
countryTextField:
|
||||||
|
ClassName: EditableTextField
|
||||||
|
Name: CountryTextSelection
|
||||||
|
Title: "Enter your country (2 digit prefix)"
|
||||||
|
DisplayRulesConjunction: And
|
||||||
|
ShowOnLoad: false
|
||||||
EditableCustomRule:
|
EditableCustomRule:
|
||||||
|
rule1:
|
||||||
|
Display: Show
|
||||||
|
ConditionOption: HasValue
|
||||||
|
FieldValue: NZ
|
||||||
|
ConditionField: =>EditableFormField.countryTextField
|
||||||
|
Parent: =>EditableFormField.irdNumberField
|
||||||
rule-1:
|
rule-1:
|
||||||
Display: Hide
|
Display: Hide
|
||||||
ConditionOption: HasValue
|
ConditionOption: HasValue
|
||||||
FieldValue: 6
|
FieldValue: 6
|
||||||
|
|
||||||
EditableOption:
|
EditableOption:
|
||||||
option-1:
|
option-1:
|
||||||
Name: Option1
|
Name: Option1
|
||||||
|
@ -50,6 +50,26 @@ class UserDefinedFormTest extends FunctionalTest
|
|||||||
$this->assertTrue($fields->dataFieldByName('OnCompleteMessage') != null);
|
$this->assertTrue($fields->dataFieldByName('OnCompleteMessage') != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testGetCMSFieldsShowInSummary()
|
||||||
|
{
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', 'summary-rules-form');
|
||||||
|
|
||||||
|
$fields = $form->getCMSFields();
|
||||||
|
|
||||||
|
$this->assertInstanceOf('GridField', $fields->dataFieldByName('Submissions'));
|
||||||
|
|
||||||
|
$submissionsgrid = $fields->dataFieldByName('Submissions');
|
||||||
|
$gridFieldDataColumns = $submissionsgrid->getConfig()->getComponentByType('GridFieldDataColumns');
|
||||||
|
|
||||||
|
$summaryFields = $gridFieldDataColumns->getDisplayFields($submissionsgrid);
|
||||||
|
|
||||||
|
$this->assertContains('SummaryShow', array_keys($summaryFields), 'Summary field not showing displayed field');
|
||||||
|
$this->assertNotContains('SummaryHide', array_keys($summaryFields), 'Summary field showing displayed field');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testEmailRecipientPopup()
|
public function testEmailRecipientPopup()
|
||||||
{
|
{
|
||||||
$this->logInWithPermission('ADMIN');
|
$this->logInWithPermission('ADMIN');
|
||||||
|
@ -107,6 +107,16 @@ EditableTextField:
|
|||||||
Required: true
|
Required: true
|
||||||
CustomErrorMessage: 'This field is required'
|
CustomErrorMessage: 'This field is required'
|
||||||
|
|
||||||
|
summary-show:
|
||||||
|
Name: SummaryShow
|
||||||
|
Title: Summary Text Field
|
||||||
|
ShowInSummary: true
|
||||||
|
|
||||||
|
summary-hide:
|
||||||
|
Name: SummaryHide
|
||||||
|
Title: Summary Text Field
|
||||||
|
ShowInSummary: false
|
||||||
|
|
||||||
EditableDropdown:
|
EditableDropdown:
|
||||||
basic-dropdown:
|
basic-dropdown:
|
||||||
Name: basic-dropdown
|
Name: basic-dropdown
|
||||||
@ -250,7 +260,12 @@ UserDefinedForm:
|
|||||||
|
|
||||||
custom-rules-form:
|
custom-rules-form:
|
||||||
Title: Custom Rules Form
|
Title: Custom Rules Form
|
||||||
Fields: =>EditableFormStep.form4step1,=>EditableCheckbox.checkbox-2, =>EditableTextField.basic-text-2
|
Fields: =>EditableCheckbox.checkbox-2, =>EditableTextField.basic-text-2
|
||||||
|
|
||||||
|
summary-rules-form:
|
||||||
|
Title: Summary Fields Form
|
||||||
|
Fields: =>EditableTextField.summary-show, =>EditableTextField.summary-hide
|
||||||
|
|
||||||
empty-form:
|
empty-form:
|
||||||
Title: Empty Form
|
Title: Empty Form
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user