Merge 4 into master

This commit is contained in:
Damian Mooyman 2017-05-01 17:47:44 +12:00
commit c78942474c
32 changed files with 737 additions and 375 deletions

View File

@ -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';
}
}

View File

@ -392,27 +392,27 @@ class UserDefinedForm_Controller extends Page_Controller
// load the jquery // load the jquery
if (!$page->config()->block_default_userforms_js) { if (!$page->config()->block_default_userforms_js) {
$lang = i18n::get_lang_from_locale(i18n::get_locale()); $lang = i18n::get_lang_from_locale(i18n::get_locale());
Requirements::javascript(FRAMEWORK_DIR .'/thirdparty/jquery/jquery.js'); Requirements::javascript(FRAMEWORK_DIR .'/thirdparty/jquery/jquery.js');
Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery-validate/jquery.validate.min.js'); Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery-validate/jquery.validate.min.js');
Requirements::add_i18n_javascript(USERFORMS_DIR . '/javascript/lang'); Requirements::add_i18n_javascript(USERFORMS_DIR . '/javascript/lang');
Requirements::javascript(USERFORMS_DIR . '/javascript/UserForm.js'); Requirements::javascript(USERFORMS_DIR . '/javascript/UserForm.js');
Requirements::javascript( Requirements::javascript(
USERFORMS_DIR . "/thirdparty/jquery-validate/localization/messages_{$lang}.min.js" USERFORMS_DIR . "/thirdparty/jquery-validate/localization/messages_{$lang}.min.js"
); );
Requirements::javascript( Requirements::javascript(
USERFORMS_DIR . "/thirdparty/jquery-validate/localization/methods_{$lang}.min.js" USERFORMS_DIR . "/thirdparty/jquery-validate/localization/methods_{$lang}.min.js"
); );
if ($this->HideFieldLabels) { if ($this->HideFieldLabels) {
Requirements::javascript(USERFORMS_DIR . '/thirdparty/Placeholders.js/Placeholders.min.js'); Requirements::javascript(USERFORMS_DIR . '/thirdparty/Placeholders.js/Placeholders.min.js');
}
// Bind a confirmation message when navigating away from a partially completed form.
if ($page::config()->enable_are_you_sure) {
Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery.are-you-sure/jquery.are-you-sure.js');
}
} }
// Bind a confirmation message when navigating away from a partially completed form.
if ($page::config()->enable_are_you_sure) {
Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery.are-you-sure/jquery.are-you-sure.js');
}
}
} }
/** /**
@ -476,181 +476,27 @@ 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');
} }
@ -907,12 +753,58 @@ 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
//Initial state
$('{$target}').{$initialState}();
$('.userform').on('{$events}',
"{$selectors}",
function (){
if({$operations}) {
$('{$target}').{$view}();
} else {
$('{$target}').{$opposite}();
}
});
EOS;
}
return $result;
}
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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
); );

23
code/model/editableformfields/EditableEmailField.php Executable file → Normal file
View 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);
}
} }
} }

View File

@ -14,8 +14,11 @@ 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
*/ */
class EditableFormField extends DataObject class EditableFormField extends DataObject
{ {
@ -59,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 +97,11 @@ class EditableFormField extends DataObject
"RightTitle" => "Varchar(255)", // from CustomSettings "RightTitle" => "Varchar(255)", // from CustomSettings
"ShowOnLoad" => "Boolean(1)", // from CustomSettings "ShowOnLoad" => "Boolean(1)", // from CustomSettings
"ShowInSummary" => "Boolean", "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
* *
@ -231,6 +260,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;
@ -246,35 +286,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) {
@ -282,7 +314,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
@ -296,13 +328,18 @@ class EditableFormField extends DataObject
); );
return new FieldList( return new FieldList(
CheckboxField::create( DropdownField::create('ShowOnLoad',
'ShowOnLoad', _t('EditableFormField.INITIALVISIBILITY', 'Initial visibility'),
_t('EditableFormField.SHOWONLOAD_TITLE', 'Show on load') array(
)->setDescription( 1 => 'Show',
_t( 0 => 'Hide',
'EditableFormField.SHOWONLOAD', )
'Initial visibility before processing these rules' ),
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(
@ -490,32 +527,47 @@ class EditableFormField extends DataObject
* Publish this Form Field to the live site * Publish this Form Field to the live site
* *
* Wrapper for the {@link Versioned} publish function * Wrapper for the {@link Versioned} publish function
*
* @param string $fromStage
* @param string $toStage
* @param bool $createNewVersion
*/ */
public function doPublish($fromStage, $toStage, $createNewVersion = false) public function doPublish($fromStage, $toStage, $createNewVersion = false)
{ {
$this->publish($fromStage, $toStage, $createNewVersion); $this->publish($fromStage, $toStage, $createNewVersion);
$this->publishRules($fromStage, $toStage, $createNewVersion);
}
$seenIDs = array(); /**
* Publish all field rules
*
* @param string $fromStage
* @param string $toStage
* @param bool $createNewVersion
*/
protected function publishRules($fromStage, $toStage, $createNewVersion)
{
$seenRuleIDs = array();
// Don't forget to publish the related custom rules... // Don't forget to publish the related custom rules...
foreach ($this->DisplayRules() as $rule) { foreach ($this->DisplayRules() as $rule) {
$seenIDs[] = $rule->ID; $seenRuleIDs[] = $rule->ID;
$rule->doPublish($fromStage, $toStage, $createNewVersion); $rule->doPublish($fromStage, $toStage, $createNewVersion);
$rule->destroy(); $rule->destroy();
} }
// remove any orphans from the "fromStage" // remove any orphans from the "fromStage"
$rules = Versioned::get_by_stage('EditableCustomRule', $toStage) $rules = Versioned::get_by_stage('EditableCustomRule', $toStage)
->filter('ParentID', $this->ID); ->filter('ParentID', $this->ID);
if (!empty($seenIDs)) { if (!empty($seenRuleIDs)) {
$rules = $rules->exclude('ID', $seenIDs); $rules = $rules->exclude('ID', $seenRuleIDs);
} }
foreach ($rules as $rule) { foreach ($rules as $rule) {
$rule->deleteFromStage($toStage); $rule->deleteFromStage($toStage);
} }
} }
/** /**
* Delete this field from a given stage * Delete this field from a given stage
@ -536,7 +588,7 @@ class EditableFormField extends DataObject
} }
/** /**
* checks wether record is new, copied from Sitetree * checks whether record is new, copied from SiteTree
*/ */
public function isNew() public function isNew()
{ {
@ -601,7 +653,7 @@ class EditableFormField extends DataObject
/** /**
* Set the allowed css classes for the extraClass custom setting * Set the allowed css classes for the extraClass custom setting
* *
* @param array The permissible CSS classes to add * @param array $allowed The permissible CSS classes to add
*/ */
public function setAllowedCss(array $allowed) public function setAllowedCss(array $allowed)
{ {
@ -811,6 +863,11 @@ class EditableFormField extends DataObject
if ($this->ExtraClass) { if ($this->ExtraClass) {
$field->addExtraClass($this->ExtraClass); $field->addExtraClass($this->ExtraClass);
} }
// if this field has a placeholder
if ($this->Placeholder) {
$field->setAttribute('placeholder', $this->Placeholder);
}
} }
/** /**
@ -905,7 +962,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}";
} }
/** /**
@ -913,10 +980,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}']";
} }
@ -976,4 +1053,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
View File

View File

@ -89,25 +89,45 @@ class EditableMultipleOptionField extends EditableFormField
* When publishing it needs to handle copying across / publishing * When publishing it needs to handle copying across / publishing
* each of the individual field options * each of the individual field options
* *
* @return void * @param string $fromStage
* @param string $toStage
* @param bool $createNewVersion
*/ */
public function doPublish($fromStage, $toStage, $createNewVersion = false) public function doPublish($fromStage, $toStage, $createNewVersion = false)
{ {
$live = Versioned::get_by_stage("EditableOption", "Live", "\"EditableOption\".\"ParentID\" = $this->ID");
if ($live) {
foreach ($live as $option) {
$option->delete();
}
}
if ($this->Options()) {
foreach ($this->Options() as $option) {
$option->publish($fromStage, $toStage, $createNewVersion);
}
}
parent::doPublish($fromStage, $toStage, $createNewVersion); parent::doPublish($fromStage, $toStage, $createNewVersion);
$this->publishOptions($fromStage, $toStage, $createNewVersion);
}
/**
* Publish list options
*
* @param string $fromStage
* @param string $toStage
* @param bool $createNewVersion
*/
protected function publishOptions($fromStage, $toStage, $createNewVersion)
{
$seenIDs = array();
// Publish all options
foreach ($this->Options() as $option) {
$seenIDs[] = $option->ID;
$option->publish($fromStage, $toStage, $createNewVersion);
}
// remove any orphans from the "fromStage"
$options = Versioned::get_by_stage('EditableOption', $toStage)
->filter('ParentID', $this->ID);
if (!empty($seenIDs)) {
$options = $options->exclude('ID', $seenIDs);
}
foreach ($options as $rule) {
$rule->deleteFromStage($toStage);
}
} }
/** /**

View File

@ -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);
}
} }
} }

View File

@ -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;
}
} }

17
code/model/editableformfields/EditableTextField.php Executable file → Normal file
View File

@ -14,6 +14,8 @@ 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( private static $autocomplete_options = array(
'off' => 'Off', 'off' => 'Off',
'on' => 'On', 'on' => 'On',
@ -44,11 +46,12 @@ class EditableTextField extends EditableFormField
'url' => 'Home page' '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)' 'Autocomplete' => 'Varchar(255)'
); );
@ -70,14 +73,6 @@ class EditableTextField extends EditableFormField
)) ))
); );
$fields->addFieldToTab(
'Root.Main',
TextField::create(
'Placeholder',
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
)
);
$fields->addFieldToTab( $fields->addFieldToTab(
'Root.Main', 'Root.Main',
DropdownField::create( DropdownField::create(
@ -157,10 +152,6 @@ class EditableTextField extends EditableFormField
$field->setAttribute('data-rule-maxlength', intval($this->MaxLength)); $field->setAttribute('data-rule-maxlength', intval($this->MaxLength));
} }
if ($this->Placeholder) {
$field->setAttribute('placeholder', $this->Placeholder);
}
if ($this->Autocomplete) { if ($this->Autocomplete) {
$field->setAttribute('autocomplete', $this->Autocomplete); $field->setAttribute('autocomplete', $this->Autocomplete);
} }

View File

@ -42,10 +42,10 @@ class UserFormRecipientItemRequest extends GridFieldDetailForm_ItemRequest
foreach ($fields as $field) { foreach ($fields as $field) {
$data->push(new ArrayData(array( $data->push(new ArrayData(array(
'Name' => $field->Name, 'Name' => $field->dbObject('Name'),
'Title' => $field->Title, 'Title' => $field->dbObject('Title'),
'Value' => '$' . $field->Name, 'Value' => DBField::create_field('Varchar', '$' . $field->Name),
'FormattedValue' => '$' . $field->Name 'FormattedValue' => DBField::create_field('Varchar', '$' . $field->Name)
))); )));
} }

View File

@ -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)
);
}
} }

View File

@ -16,7 +16,7 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
"UserForms.ERROR_CREATING_FIELD": "Nastala chyba pri vytváraní poľa", "UserForms.ERROR_CREATING_FIELD": "Nastala chyba pri vytváraní poľa",
"UserForms.ERROR_CREATING_OPTION": "Nastala chyba pri vytváraní voľby/možnosti", "UserForms.ERROR_CREATING_OPTION": "Nastala chyba pri vytváraní voľby/možnosti",
"UserForms.HIDE_OPTIONS": "Skryť možnosti", "UserForms.HIDE_OPTIONS": "Skryť možnosti",
"UserForms.LEAVE_CONFIRMATION": "You have unsaved changes!", "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:" "UserForms.ERROR_CONTAINER_HEADER": "Opravte prosím nasledujúce chyby a skúste to znova:"

View File

@ -9,7 +9,7 @@
"UserForms.ERROR_CREATING_FIELD": "Nastala chyba pri vytváraní poľa", "UserForms.ERROR_CREATING_FIELD": "Nastala chyba pri vytváraní poľa",
"UserForms.ERROR_CREATING_OPTION": "Nastala chyba pri vytváraní voľby/možnosti", "UserForms.ERROR_CREATING_OPTION": "Nastala chyba pri vytváraní voľby/možnosti",
"UserForms.HIDE_OPTIONS": "Skryť možnosti", "UserForms.HIDE_OPTIONS": "Skryť možnosti",
"UserForms.LEAVE_CONFIRMATION": "You have unsaved changes!", "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"
} }

View File

@ -11,8 +11,8 @@ ar:
NOTBLANK: 'ليس بفراغ' NOTBLANK: 'ليس بفراغ'
NOTVALUE: 'ليست قيمة' NOTVALUE: 'ليست قيمة'
SHOWTHISFIELD: 'إظهار هذا الحقل' SHOWTHISFIELD: 'إظهار هذا الحقل'
VALUE: 'القيمة' VALUE: القيمة
WHEN: 'عندما' WHEN: عندما
EditableCheckbox: EditableCheckbox:
PLURALNAME: 'مربعات لوضع إشارة' PLURALNAME: 'مربعات لوضع إشارة'
SINGULARNAME: 'حقل ذات مربع لوضع إشارة' SINGULARNAME: 'حقل ذات مربع لوضع إشارة'
@ -51,7 +51,7 @@ ar:
FIELDONDEFAULT: 'القيمة المبدئية للحقل' FIELDONDEFAULT: 'القيمة المبدئية للحقل'
GREATERTHAN: 'القيمة أكبر من' GREATERTHAN: 'القيمة أكبر من'
GREATERTHANEQUAL: 'القيمة أكبر من أو تساوي' GREATERTHANEQUAL: 'القيمة أكبر من أو تساوي'
GROUP: 'مجموعة' GROUP: مجموعة
HIDE: إخفاء HIDE: إخفاء
HIDETHISFIELD: 'إخفاء هذا الحقل' HIDETHISFIELD: 'إخفاء هذا الحقل'
IS: إنه IS: إنه
@ -68,9 +68,9 @@ ar:
SHOWOPTIONS: 'إظهار الخيارات' SHOWOPTIONS: 'إظهار الخيارات'
SHOWTHISFIELD: 'أعرض هذه الحقل' SHOWTHISFIELD: 'أعرض هذه الحقل'
SINGULARNAME: 'حقل استمارة قابل للتحرير' SINGULARNAME: 'حقل استمارة قابل للتحرير'
VALIDATION: 'المصادقة' VALIDATION: المصادقة
VALUE: 'القيمة' VALUE: القيمة
WHEN: 'عندما' WHEN: عندما
EditableFormHeading: EditableFormHeading:
LEVEL: 'حدد مستوى العنوان' LEVEL: 'حدد مستوى العنوان'
PLURALNAME: عناوين PLURALNAME: عناوين
@ -122,16 +122,16 @@ ar:
SINGULARNAME: 'حقل الاستمارة الذي تمّ تقديمه' SINGULARNAME: 'حقل الاستمارة الذي تمّ تقديمه'
UserDefinedForm: UserDefinedForm:
ADDEMAILRECIPIENT: 'أضف متلقي البريد الإلكتروني' ADDEMAILRECIPIENT: 'أضف متلقي البريد الإلكتروني'
CONFIGURATION: 'مواصفات' CONFIGURATION: مواصفات
DESCRIPTION: 'يضيف استمارة مخصصة.' DESCRIPTION: 'يضيف استمارة مخصصة.'
EMAILADDRESS: 'البريد الإلكتروني' EMAILADDRESS: 'البريد الإلكتروني'
EMAILBODY: هيئة EMAILBODY: هيئة
EMAILFROM: 'من' EMAILFROM: من
EMAILRECIPIENTS: 'متلقي البريد الإلكتروني' EMAILRECIPIENTS: 'متلقي البريد الإلكتروني'
EMAILSUBJECT: 'موضوع البريد الإلكتروني' EMAILSUBJECT: 'موضوع البريد الإلكتروني'
ENABLELIVEVALIDATION: 'تفعيل المصادقة الآنية' ENABLELIVEVALIDATION: 'تفعيل المصادقة الآنية'
EmailFromContent: 'عنوان خانة المرسل يسمح لك بتعيين من الذي يأتي منه البريد الالكتروني. في معظم الخوادم هذا سوف يحتاج إلى أن يعين إلى عنوان بريد إلكتروني على نفس اسم مجال موقع الويب الخاص بك. على سبيل المثال على yoursite.com عنوان خانة المرسل قد يحتاج إلى أن يكون something@yoursite.com. يمكنك مع ذلك، تعيين أي عنوان بريد إلكتروني ترغب كعنوان للرد.' EmailFromContent: 'عنوان خانة المرسل يسمح لك بتعيين من الذي يأتي منه البريد الالكتروني. في معظم الخوادم هذا سوف يحتاج إلى أن يعين إلى عنوان بريد إلكتروني على نفس اسم مجال موقع الويب الخاص بك. على سبيل المثال على yoursite.com عنوان خانة المرسل قد يحتاج إلى أن يكون something@yoursite.com. يمكنك مع ذلك، تعيين أي عنوان بريد إلكتروني ترغب كعنوان للرد.'
FORM: 'نموذج' FORM: نموذج
FROMADDRESS: 'ارسل بريد إلكتروني من' FROMADDRESS: 'ارسل بريد إلكتروني من'
HIDEFIELDLABELS: 'إخفاء تسميات الحقول' HIDEFIELDLABELS: 'إخفاء تسميات الحقول'
HIDEFORMDATA: 'إخفاء بيانات النموذج من البريد الإلكتروني؟' HIDEFORMDATA: 'إخفاء بيانات النموذج من البريد الإلكتروني؟'
@ -144,8 +144,8 @@ ar:
SENDPLAIN: 'إرسال البريد الإلكتروني كنص عادي؟ (سيتم تجريد كود الHTML)' SENDPLAIN: 'إرسال البريد الإلكتروني كنص عادي؟ (سيتم تجريد كود الHTML)'
SHOWCLEARFORM: 'زر عرض النموذج ممسوحاً' SHOWCLEARFORM: 'زر عرض النموذج ممسوحاً'
SINGULARNAME: 'نموذج يحدده المستخدم' SINGULARNAME: 'نموذج يحدده المستخدم'
SUBMISSIONS: 'التقديمات' SUBMISSIONS: التقديمات
SUBMITBUTTON: 'تقديم' SUBMITBUTTON: تقديم
TEXTONSUBMIT: 'زر النص المتعلق بالتقديم:' TEXTONSUBMIT: 'زر النص المتعلق بالتقديم:'
UserDefinedForm_EmailRecipient: UserDefinedForm_EmailRecipient:
PLURALNAME: 'نموذج مستلمي البريد الإلكتروني يحدده المستخدم' PLURALNAME: 'نموذج مستلمي البريد الإلكتروني يحدده المستخدم'

View File

@ -78,7 +78,7 @@ ar_SA:
EMAILFROM: From EMAILFROM: From
EMAILRECIPIENTS: 'Email Recipients' EMAILRECIPIENTS: 'Email Recipients'
EMAILSUBJECT: 'Email Subject' EMAILSUBJECT: 'Email Subject'
FORM: 'النموذج' FORM: النموذج
FROMADDRESS: 'Send Email From' FROMADDRESS: 'Send Email From'
HIDEFORMDATA: 'Hide Form Data from Email' HIDEFORMDATA: 'Hide Form Data from Email'
ONCOMPLETELABEL: 'عرض الطلبات المكتملة' ONCOMPLETELABEL: 'عرض الطلبات المكتملة'

View File

@ -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'
@ -111,7 +112,6 @@ de_DE:
AUTOCOMPLETE: 'Automatisch vervollständigen' 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' 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

View File

@ -85,6 +85,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'
@ -147,7 +148,6 @@ en:
AUTOCOMPLETE_DESCRIPTION: 'Supported browsers will attempt to populate this field automatically with the users information, use to set the value populated' 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'

View File

@ -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'

View File

@ -46,12 +46,12 @@ fa_IR:
UserDefinedForm: UserDefinedForm:
CLEARBUTTON: پاک‌کردن CLEARBUTTON: پاک‌کردن
DISABLECSRFSECURITYTOKEN: 'غیر فعال کردن CSRF' DISABLECSRFSECURITYTOKEN: 'غیر فعال کردن CSRF'
EMAILADDRESS: 'ایمیل' EMAILADDRESS: ایمیل
EMAILFROM: از EMAILFROM: از
EMAILSUBJECT: 'موضوع پست الکترونیک' EMAILSUBJECT: 'موضوع پست الکترونیک'
EMAILTEMPLATE: 'قالب پست الکترونیک' EMAILTEMPLATE: 'قالب پست الکترونیک'
FIELDS: فیلدها FIELDS: فیلدها
FORM: 'فرم' FORM: فرم
PLURALNAME: 'صفحه اصلی' PLURALNAME: 'صفحه اصلی'
RECIPIENTS: 'دریافت کنندگان' RECIPIENTS: 'دریافت کنندگان'
SENDEMAILTO: 'ارسال ایمیل به' SENDEMAILTO: 'ارسال ایمیل به'

View File

@ -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ä

View File

@ -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'
@ -144,7 +145,6 @@ it:
AUTOCOMPLETE_DESCRIPTION: 'I browser supportati cercheranno di popolare automaticamente questo campo con l'informazione agli utenti, usare per impostare il valore popolata' 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'

View File

@ -12,23 +12,23 @@ ja:
UserDefinedForm: UserDefinedForm:
EMAILADDRESS: メール EMAILADDRESS: メール
EMAILBODY: ボディ EMAILBODY: ボディ
EMAILFROM: '送信者' EMAILFROM: 送信者
EMAILSUBJECT: メールの件名 EMAILSUBJECT: メールの件名
EmailFromContent: '送信元アドレスでどこからメールを送信するのか設定することができます。多くのサーバーではこれはあなたのサイトのドメイン名と同じメールアドレスに設定する必要があります。たとえば yoursite.com では送信元アドレスは something@yoursite.com としなければいけません。ただし、返信先アドレスは好きなメールアドレスを設定することができます。' EmailFromContent: '送信元アドレスでどこからメールを送信するのか設定することができます。多くのサーバーではこれはあなたのサイトのドメイン名と同じメールアドレスに設定する必要があります。たとえば yoursite.com では送信元アドレスは something@yoursite.com としなければいけません。ただし、返信先アドレスは好きなメールアドレスを設定することができます。'
FORM: 'フォーム' FORM: フォーム
FROMADDRESS: 'メールの送信元' FROMADDRESS: メールの送信元
HIDEFORMDATA: 'メールからフォームデータを見えないようにしますか?' HIDEFORMDATA: 'メールからフォームデータを見えないようにしますか?'
ONCOMPLETELABEL: 完成時に表示 ONCOMPLETELABEL: 完成時に表示
ORSELECTAFIELDTOUSEASFROM: '..またはフィールドを選択して返信先アドレスとして使用' ORSELECTAFIELDTOUSEASFROM: ..またはフィールドを選択して返信先アドレスとして使用
ORSELECTAFIELDTOUSEASTO: '..またはフィールドを選択して宛先アドレスとして使用' ORSELECTAFIELDTOUSEASTO: ..またはフィールドを選択して宛先アドレスとして使用
REPLYADDRESS: 以下への返信メール REPLYADDRESS: 以下への返信メール
SAVESUBMISSIONS: 提出物をサーバーに保存するのを無効化 SAVESUBMISSIONS: 提出物をサーバーに保存するのを無効化
SENDEMAILTO: メールを送信 SENDEMAILTO: メールを送信
SENDPLAIN: 'プレーンテキストとしてメールを送信しますか? (HTMLは取り除かれます)' SENDPLAIN: 'プレーンテキストとしてメールを送信しますか? (HTMLは取り除かれます)'
SHOWCLEARFORM: 'フォームをクリアーボタンを表示する' SHOWCLEARFORM: フォームをクリアーボタンを表示する
SINGULARNAME: 'ユーザー定義フォーム' SINGULARNAME: ユーザー定義フォーム
SUBMITBUTTON: 送信 SUBMITBUTTON: 送信
TEXTONSUBMIT: '送信ボタンのテキスト:' TEXTONSUBMIT: '送信ボタンのテキスト:'
UserDefinedForm_EmailRecipient: UserDefinedForm_EmailRecipient:
PLURALNAME: 'ユーザー定義フォームのメール受信者' PLURALNAME: ユーザー定義フォームのメール受信者
SINGULARNAME: 'ユーザー定義フォームのメール受信者' SINGULARNAME: ユーザー定義フォームのメール受信者

View File

@ -57,6 +57,7 @@ sk:
DEFAULT: 'Predvolená hodnota' DEFAULT: 'Predvolená hodnota'
DEFAULTTOTODAY: 'Zobraziť v predvolenom režime na dnešný dátum?' DEFAULTTOTODAY: 'Zobraziť v predvolenom režime na dnešný dátum?'
DELETE: Vymazať DELETE: Vymazať
DISPLAY_RULES_DISABLED: 'Pravidlá zobrazenia nie sú povolené pre povinné/vyžadované polia. Prosím odškrtnite "Je pole povinné/vyžadované?" na záložke "Validácia".'
DRAG: 'Ťahaním preskupiť poradie polí' DRAG: 'Ťahaním preskupiť poradie polí'
ENTERQUESTION: 'Zadajte otázku' ENTERQUESTION: 'Zadajte otázku'
EXTRACLASSA: 'Extra úprava/vzhľad' EXTRACLASSA: 'Extra úprava/vzhľad'
@ -82,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é.'
@ -91,7 +93,7 @@ sk:
SHOWOPTIONS: 'Zobraziť možnosti' SHOWOPTIONS: 'Zobraziť možnosti'
SHOWTHISFIELD: 'Zobraziť toto pole' SHOWTHISFIELD: 'Zobraziť toto pole'
SINGULARNAME: 'Formulárové pole' SINGULARNAME: 'Formulárové pole'
TITLE: Titulok TITLE: Názov
TYPE: Typ TYPE: Typ
VALIDATION: Validácia VALIDATION: Validácia
VALUE: 'Zadanú hodnotu' VALUE: 'Zadanú hodnotu'
@ -111,7 +113,7 @@ sk:
EditableLiteralField: EditableLiteralField:
CONTENT: HTML CONTENT: HTML
HIDEFROMREPORT: 'Skryť z reportu?' HIDEFROMREPORT: 'Skryť z reportu?'
HIDELABEL: 'Skryť titulok na FrontEnd-e?' HIDELABEL: 'Skryť ''Názov'' na FrontEnd-e?'
PLURALNAME: 'HTML bloky' PLURALNAME: 'HTML bloky'
SINGULARNAME: 'HTML blok' SINGULARNAME: 'HTML blok'
EditableMemberListField: EditableMemberListField:
@ -119,8 +121,11 @@ sk:
SINGULARNAME: 'Pole zoznamu členov' SINGULARNAME: 'Pole zoznamu členov'
EditableMultipleOptionField: EditableMultipleOptionField:
DEFAULT: 'Vybrané v predvolenom režime?' DEFAULT: 'Vybrané v predvolenom režime?'
OPTIONSTAB: Možnosti
PLURALNAME: 'Polia s viacerými možnosťami' PLURALNAME: 'Polia s viacerými možnosťami'
SINGULARNAME: 'Pole s viacerými možnosťami' SINGULARNAME: 'Pole s viacerými možnosťami'
TITLE: Názov
VALUE: Hodnota
EditableNumericField: EditableNumericField:
PLURALNAME: 'Numerické/číselné polia' PLURALNAME: 'Numerické/číselné polia'
RANGE: 'Povolený rozsah' RANGE: 'Povolený rozsah'
@ -138,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'
@ -189,6 +193,7 @@ sk:
FileUploadWarning: 'Súbory nahraté pomocou tohto políčka môžu byť verejné prístupné, pokiaľ je známa presná URL adresa.' FileUploadWarning: 'Súbory nahraté pomocou tohto políčka môžu byť verejné prístupné, pokiaľ je známa presná URL adresa.'
HIDEFIELDLABELS: 'Skyť popisky (menovky) polí?' HIDEFIELDLABELS: 'Skyť popisky (menovky) polí?'
HIDEFORMDATA: 'Skryť dáta z e-mailu?' HIDEFORMDATA: 'Skryť dáta z e-mailu?'
NORECIPIENTS: 'Varovanie: Nemáte pridaných žiadnych príjemcov. Podané formuláre môžu chýbať.'
ONCOMPLETELABEL: 'Správa po odoslaní formulára' ONCOMPLETELABEL: 'Správa po odoslaní formulára'
ORSELECTAFIELDTOUSEASFROM: '... alebo vyberte poľe, ktoré sa použije na odpoveď' ORSELECTAFIELDTOUSEASFROM: '... alebo vyberte poľe, ktoré sa použije na odpoveď'
ORSELECTAFIELDTOUSEASTO: '... alebo vyberte poľe, ktoré sa použije ako E-mail príjemcu' ORSELECTAFIELDTOUSEASTO: '... alebo vyberte poľe, ktoré sa použije ako E-mail príjemcu'
@ -205,6 +210,8 @@ sk:
SENDEMAILTO: 'E-mail príjemcu' SENDEMAILTO: 'E-mail príjemcu'
SENDEMAILTO_DESCRIPTION: 'Môžete zadať viac e-mailových adries, pričom jednotlivé adresy oddeľujte čiarkou.' SENDEMAILTO_DESCRIPTION: 'Môžete zadať viac e-mailových adries, pričom jednotlivé adresy oddeľujte čiarkou.'
SENDIF: 'Podmienka poslania' SENDIF: 'Podmienka poslania'
SENDIFAND: 'Všetky podmienky sú splnené'
SENDIFOR: 'Akékoľvek podmienky sú splnené'
SENDPLAIN: 'Poslať e-mail ako obyčajný text? (HTML značky budú odstránené)' SENDPLAIN: 'Poslať e-mail ako obyčajný text? (HTML značky budú odstránené)'
SHOWCLEARFORM: 'Zobraziť resetovacie tlačidlo?' SHOWCLEARFORM: 'Zobraziť resetovacie tlačidlo?'
SINGULARNAME: 'Jednoduchý formulár' SINGULARNAME: 'Jednoduchý formulár'
@ -216,6 +223,9 @@ sk:
TYPESUBJECT: 'Napíšte predmet' TYPESUBJECT: 'Napíšte predmet'
TYPETO: 'Napíšte adresu' TYPETO: 'Napíšte adresu'
UserDefinedForm_EmailRecipient: UserDefinedForm_EmailRecipient:
CUSTOMRULESTAB: 'Vlastné pravidlá'
EMAILCONTENTTAB: 'Obsah e-mailu'
EMAILDETAILSTAB: 'Detaily e-mailu'
PLURALNAME: 'Užívateľom definovaný formulár - príjemcovia e-mailu' PLURALNAME: 'Užívateľom definovaný formulár - príjemcovia e-mailu'
SINGULARNAME: 'Užívateľom definovaný formulár - príjemca e-mailu' SINGULARNAME: 'Užívateľom definovaný formulár - príjemca e-mailu'
UserDefinedForm_EmailRecipientCondition: UserDefinedForm_EmailRecipientCondition:
@ -234,4 +244,6 @@ sk:
WRONG_GROUP_END: '''{name}'' nájdený vrámci zle uzatvorenej obaľovacej skupiny ''{group}''' WRONG_GROUP_END: '''{name}'' nájdený vrámci zle uzatvorenej obaľovacej skupiny ''{group}'''
UserFormsGridFieldFilterHeader: UserFormsGridFieldFilterHeader:
FILTERSUBMISSIONS: 'Filtrovať ...' FILTERSUBMISSIONS: 'Filtrovať ...'
FROM: Od
TILL: Do
WHEREVALUEIS: 'kde hodnota je ...' WHEREVALUEIS: 'kde hodnota je ...'

View File

@ -1,7 +1,7 @@
zh: zh:
CustomRule: CustomRule:
BLANK: 空白 BLANK: 空白
DELETE: '删除' DELETE: 删除
GREATERTHAN: 值大于 GREATERTHAN: 值大于
GREATERTHANEQUAL: 值大于或等于 GREATERTHANEQUAL: 值大于或等于
HIDETHISFIELD: 隐藏这个字段 HIDETHISFIELD: 隐藏这个字段
@ -32,22 +32,22 @@ zh:
PLURALNAME: 电子邮件字段 PLURALNAME: 电子邮件字段
SINGULARNAME: 电子邮件字段 SINGULARNAME: 电子邮件字段
EditableFileField: EditableFileField:
PLURALNAME: '文件上传字段' PLURALNAME: 文件上传字段
SINGULARNAME: '文件上传字段' SINGULARNAME: 文件上传字段
EditableFormField: EditableFormField:
ADD: '添加' ADD: 添加
ADDRULE: '添加规则' ADDRULE: 添加规则
BLANK: 空白 BLANK: 空白
CHECKEDBYDEFAULT: 默认选中? CHECKEDBYDEFAULT: 默认选中?
CUSTOMERROR: 自定义错误消息 CUSTOMERROR: 自定义错误消息
CUSTOMRULES: 自定义规则 CUSTOMRULES: 自定义规则
DEFAULTTOTODAY: 默认为今天? DEFAULTTOTODAY: 默认为今天?
DELETE: '删除' DELETE: 删除
DRAG: 拖放来对字段进行重新排序 DRAG: 拖放来对字段进行重新排序
ENTERQUESTION: '键入问题' ENTERQUESTION: 键入问题
EXTRACLASSA: '额外的造型/布局' EXTRACLASSA: 额外的造型/布局
EXTRACLASSB: '额外的 css 类别 - 用空格来分开多项' EXTRACLASSB: '额外的 css 类别 - 用空格来分开多项'
FIELDCONFIGURATION: '字段配置' FIELDCONFIGURATION: 字段配置
FIELDONDEFAULT: 默认字段 FIELDONDEFAULT: 默认字段
GREATERTHAN: 值大于 GREATERTHAN: 值大于
GREATERTHANEQUAL: 值大于或等于 GREATERTHANEQUAL: 值大于或等于
@ -61,20 +61,20 @@ zh:
NOTBLANK: 不是空白 NOTBLANK: 不是空白
NOTVALUE: 没有值 NOTVALUE: 没有值
OPTIONS: 选项 OPTIONS: 选项
PLURALNAME: '可编辑的表格字段' PLURALNAME: 可编辑的表格字段
REQUIRED: '这个字段是必须的吗?' REQUIRED: 这个字段是必须的吗?
RIGHTTITLE: '右标题' RIGHTTITLE: 右标题
SHOW: 显示 SHOW: 显示
SHOWOPTIONS: 显示选项 SHOWOPTIONS: 显示选项
SHOWTHISFIELD: 显示该字段 SHOWTHISFIELD: 显示该字段
SINGULARNAME: '可编辑的表格字段' SINGULARNAME: 可编辑的表格字段
VALIDATION: 验证 VALIDATION: 验证
VALUE: VALUE:
WHEN: WHEN:
EditableFormHeading: EditableFormHeading:
LEVEL: '选择标题级别' LEVEL: 选择标题级别
PLURALNAME: '标题' PLURALNAME: 标题
SINGULARNAME: '标题' SINGULARNAME: 标题
EditableLiteralField: EditableLiteralField:
HIDEFROMREPORT: 从报告中隐藏? HIDEFROMREPORT: 从报告中隐藏?
PLURALNAME: 'HTML 模块' PLURALNAME: 'HTML 模块'
@ -86,7 +86,7 @@ zh:
PLURALNAME: 可编辑的多个选项字段 PLURALNAME: 可编辑的多个选项字段
SINGULARNAME: 可编辑的多个选项字段 SINGULARNAME: 可编辑的多个选项字段
EditableOption: EditableOption:
DELETE: '删除这个选项' DELETE: 删除这个选项
DRAG: 拖放来对选项进行重新排序 DRAG: 拖放来对选项进行重新排序
LOCKED: 这些字段不能被修改 LOCKED: 这些字段不能被修改
PLURALNAME: 可编辑的选项 PLURALNAME: 可编辑的选项
@ -100,7 +100,7 @@ zh:
SINGULARNAME: 文本字段 SINGULARNAME: 文本字段
TEXTLENGTH: 文本长度 TEXTLENGTH: 文本长度
FieldEditor: FieldEditor:
ADD: '添加' ADD: 添加
SELECTAFIELD: 选择一个字段 SELECTAFIELD: 选择一个字段
Form: Form:
FIELDISREQUIRED: '%s 是必须的' FIELDISREQUIRED: '%s 是必须的'
@ -115,41 +115,41 @@ zh:
PLURALNAME: 已提交的文件字段 PLURALNAME: 已提交的文件字段
SINGULARNAME: 已提交的文件字段 SINGULARNAME: 已提交的文件字段
SubmittedForm: SubmittedForm:
PLURALNAME: '已提交的表格' PLURALNAME: 已提交的表格
SINGULARNAME: '已提交的表格' SINGULARNAME: 已提交的表格
SubmittedFormField: SubmittedFormField:
PLURALNAME: '已提交的表格字段' PLURALNAME: 已提交的表格字段
SINGULARNAME: '已提交的表格字段' SINGULARNAME: 已提交的表格字段
UserDefinedForm: UserDefinedForm:
ADDEMAILRECIPIENT: '添加电子邮件收件人' ADDEMAILRECIPIENT: 添加电子邮件收件人
CONFIGURATION: '配置' CONFIGURATION: 配置
DESCRIPTION: '添加一个可定制的表格。' DESCRIPTION: 添加一个可定制的表格。
EMAILADDRESS: 电子邮件 EMAILADDRESS: 电子邮件
EMAILBODY: 正文 EMAILBODY: 正文
EMAILFROM: '表格' EMAILFROM: 表格
EMAILRECIPIENTS: 电子邮件收件人 EMAILRECIPIENTS: 电子邮件收件人
EMAILSUBJECT: 电子邮件主题 EMAILSUBJECT: 电子邮件主题
ENABLELIVEVALIDATION: 启用现场验证 ENABLELIVEVALIDATION: 启用现场验证
EmailFromContent: '表格地址允许您设置电子邮件的发送人。在大多数服务器上这必须要设置成域名与您的站点域名一致的电子邮件地址。例如在 yoursite.com 上,发送人的电子邮件地址必须为 something@yoursite.com。但是您可以随意设置回复的电子邮件地址。' EmailFromContent: '表格地址允许您设置电子邮件的发送人。在大多数服务器上这必须要设置成域名与您的站点域名一致的电子邮件地址。例如在 yoursite.com 上,发送人的电子邮件地址必须为 something@yoursite.com。但是您可以随意设置回复的电子邮件地址。'
FORM: '表格' FORM: 表格
FROMADDRESS: 发送人电子邮件 FROMADDRESS: 发送人电子邮件
HIDEFIELDLABELS: '隐藏字段标签' HIDEFIELDLABELS: 隐藏字段标签
HIDEFORMDATA: '从电子邮件中隐藏表格数据?' HIDEFORMDATA: 从电子邮件中隐藏表格数据?
ONCOMPLETELABEL: 完成时显示 ONCOMPLETELABEL: 完成时显示
ORSELECTAFIELDTOUSEASFROM: '.. 或选择某字段作为回复地址' ORSELECTAFIELDTOUSEASFROM: '.. 或选择某字段作为回复地址'
ORSELECTAFIELDTOUSEASTO: '.. 或选择某字段作为地址使用' ORSELECTAFIELDTOUSEASTO: '.. 或选择某字段作为地址使用'
REPLYADDRESS: 用于回复的电子邮件 REPLYADDRESS: 用于回复的电子邮件
SAVESUBMISSIONS: '禁用保存提交内容到服务器' SAVESUBMISSIONS: 禁用保存提交内容到服务器
SENDEMAILTO: 发送电子邮件到 SENDEMAILTO: 发送电子邮件到
SENDPLAIN: '以纯文本形式发送电子邮件HTML 将会被去除)' SENDPLAIN: '以纯文本形式发送电子邮件HTML 将会被去除)'
SHOWCLEARFORM: '显示清除表格按钮' SHOWCLEARFORM: 显示清除表格按钮
SINGULARNAME: '用户定义表格' SINGULARNAME: 用户定义表格
SUBMISSIONS: 提交 SUBMISSIONS: 提交
SUBMITBUTTON: 提交 SUBMITBUTTON: 提交
TEXTONSUBMIT: 提交按钮上的文本 TEXTONSUBMIT: 提交按钮上的文本
UserDefinedForm_EmailRecipient: UserDefinedForm_EmailRecipient:
PLURALNAME: '用户定义的表格电子邮件接受者' PLURALNAME: 用户定义的表格电子邮件接受者
SINGULARNAME: '用户定义的表格电子邮件接受者' SINGULARNAME: 用户定义的表格电子邮件接受者
UserFormsGridFieldFilterHeader: UserFormsGridFieldFilterHeader:
FILTERSUBMISSIONS: 筛选器提交…… FILTERSUBMISSIONS: 筛选器提交……
WHEREVALUEIS: 当值为…… WHEREVALUEIS: 当值为……

View 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']);
}
}

View 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

View File

@ -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']);
}
} }

View File

@ -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
@ -144,4 +160,4 @@ UserDefinedForm:
Title: Custom Rules Form Title: Custom Rules Form
Fields: =>EditableCheckbox.checkbox-with-rule, =>EditableTextField.basic-text-2 Fields: =>EditableCheckbox.checkbox-with-rule, =>EditableTextField.basic-text-2
empty-form: empty-form:
Title: Empty Form Title: Empty Form

View File

@ -0,0 +1,49 @@
<?php
class UserFormsVersionedTest extends SapphireTest
{
protected static $fixture_file = 'UserDefinedFormTest.yml';
public function setUp()
{
parent::setUp();
Versioned::reading_stage('Stage');
}
public function testPublishing()
{
/** @var UserDefinedForm $form */
$form = $this->objFromFixture('UserDefinedForm', 'filtered-form-page');
// Get id of options
$optionID = $this->idFromFixture('EditableOption', 'option-3');
$this->assertEmpty(Versioned::get_one_by_stage('EditableOption', 'Live', array('"ID" = ?' => $optionID)));
// Publishing writes this to live
$form->doPublish();
$liveVersion = Versioned::get_versionnumber_by_stage('EditableOption', 'Live', $optionID, false);
$this->assertNotEmpty($liveVersion);
// Add new option, and repeat publish process
/** @var EditableCheckboxGroupField $list */
$list = $this->objFromFixture('EditableCheckboxGroupField', 'checkbox-group');
$newOption = new EditableOption();
$newOption->Title = 'New option';
$newOption->Value = 'ok';
$newOption->write();
$newOptionID = $newOption->ID;
$list->Options()->add($newOption);
$form->doPublish();
// Un-modified option should not create a new version
$newLiveVersion = Versioned::get_versionnumber_by_stage('EditableOption', 'Live', $optionID, false);
$this->assertNotEmpty($newLiveVersion);
$this->assertEquals($liveVersion, $newLiveVersion);
// New option is successfully published
$newOptionLiveVersion = Versioned::get_versionnumber_by_stage('EditableOption', 'Live', $newOptionID, false);
$this->assertNotEmpty($newOptionLiveVersion);
}
}