"Varchar", "ClearButtonText" => "Varchar", "OnCompleteMessage" => "HTMLText", "ShowClearButton" => "Boolean", 'DisableSaveSubmissions' => 'Boolean', 'EnableLiveValidation' => 'Boolean', 'HideFieldLabels' => 'Boolean', 'DisplayErrorMessagesAtTop' => 'Boolean', 'DisableAuthenicatedFinishAction' => 'Boolean', 'DisableCsrfSecurityToken' => 'Boolean' ); /** * @var array Default values of variables when this page is created */ private static $defaults = array( 'Content' => '$UserDefinedForm', 'DisableSaveSubmissions' => 0, 'OnCompleteMessage' => '
Thanks, we\'ve received your submission.
' ); /** * @var array */ private static $has_many = array( "Submissions" => "SubmittedForm", "EmailRecipients" => "UserDefinedForm_EmailRecipient" ); /** * @var array * @config */ private static $casting = array( 'ErrorContainerID' => 'Text' ); /** * Error container selector which matches the element for grouped messages * * @var string * @config */ private static $error_container_id = 'error-container'; /** * The configuration used to determine whether a confirmation message is to * appear when navigating away from a partially completed form. * * @var boolean * @config */ private static $enable_are_you_sure = true; /** * @var bool * @config */ private static $recipients_warning_enabled = false; /** * Temporary storage of field ids when the form is duplicated. * Example layout: array('EditableCheckbox3' => 'EditableCheckbox14') * @var array */ protected $fieldsFromTo = array(); /** * @return FieldList */ public function getCMSFields() { Requirements::css(USERFORMS_DIR . '/css/UserForm_cms.css'); $self = $this; $this->beforeUpdateCMSFields(function ($fields) use ($self) { // define tabs $fields->findOrMakeTab('Root.FormOptions', _t('UserDefinedForm.CONFIGURATION', 'Configuration')); $fields->findOrMakeTab('Root.Recipients', _t('UserDefinedForm.RECIPIENTS', 'Recipients')); $fields->findOrMakeTab('Root.Submissions', _t('UserDefinedForm.SUBMISSIONS', 'Submissions')); // text to show on complete $onCompleteFieldSet = new CompositeField( $label = new LabelField('OnCompleteMessageLabel', _t('UserDefinedForm.ONCOMPLETELABEL', 'Show on completion')), $editor = new HtmlEditorField('OnCompleteMessage', '', _t('UserDefinedForm.ONCOMPLETEMESSAGE', $self->OnCompleteMessage)) ); $onCompleteFieldSet->addExtraClass('field'); $editor->setRows(3); $label->addExtraClass('left'); // Define config for email recipients $emailRecipientsConfig = GridFieldConfig_RecordEditor::create(10); $emailRecipientsConfig->getComponentByType('GridFieldAddNewButton') ->setButtonName( _t('UserDefinedForm.ADDEMAILRECIPIENT', 'Add Email Recipient') ); // who do we email on submission $emailRecipients = new GridField( 'EmailRecipients', _t('UserDefinedForm.EMAILRECIPIENTS', 'Email Recipients'), $self->EmailRecipients(), $emailRecipientsConfig ); $emailRecipients ->getConfig() ->getComponentByType('GridFieldDetailForm') ->setItemRequestClass('UserFormRecipientItemRequest'); $fields->addFieldsToTab('Root.FormOptions', $onCompleteFieldSet); $fields->addFieldToTab('Root.Recipients', $emailRecipients); $fields->addFieldsToTab('Root.FormOptions', $self->getFormOptions()); // view the submissions $submissions = new GridField( 'Submissions', _t('UserDefinedForm.SUBMISSIONS', 'Submissions'), $self->Submissions()->sort('Created', 'DESC') ); // make sure a numeric not a empty string is checked against this int column for SQL server $parentID = (!empty($self->ID)) ? (int) $self->ID : 0; // get a list of all field names and values used for print and export CSV views of the GridField below. $columnSQL = <<]*>)?\\$UserDefinedForm(<\\/p>)?/i', $form->forTemplate(), $this->Content);
return array(
'Content' => DBField::create_field('HTMLText', $content),
'Form' => ""
);
}
}
return array(
'Content' => DBField::create_field('HTMLText', $this->Content),
'Form' => $this->Form()
);
}
/**
* Keep the session alive for the user.
*
* @return int
*/
public function ping()
{
return 1;
}
/**
* Get the form for the page. Form can be modified by calling {@link updateForm()}
* on a UserDefinedForm extension.
*
* @return Forms
*/
public function Form()
{
$form = UserForm::create($this);
$this->generateConditionalJavascript();
return $form;
}
/**
* Generate the javascript for the conditional field show / hiding logic.
*
* @return void
*/
public function generateConditionalJavascript()
{
$default = "";
$rules = "";
$watch = array();
$watchLoad = array();
if ($this->Fields()) {
foreach ($this->Fields() as $field) {
$holderSelector = $field->getSelectorHolder();
// 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) {
foreach ($watch as $key => $values) {
$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
if ($default || $rules) {
Requirements::customScript(<<