mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
BUGFIX: fixed sortable events not updated when loading new fields. ENHANCEMENT: Added RightTitle support to EditableFormFields. Removed parsePrepopulateValue() as usage is not clear and is broken
This commit is contained in:
parent
c408b632e3
commit
745b614710
@ -1,8 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* User Defined Form Page type that lets users build a form in the CMS
|
||||
* using the FieldEditor Field.
|
||||
*
|
||||
* @todo Allow UserDefinedForm instances on Page subclasses (eg via decorator)
|
||||
*
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
@ -280,6 +283,7 @@ class UserDefinedForm_Controller extends Page_Controller {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'Content' => DBField::create('HTMLText', $this->Content),
|
||||
'Form' => $this->Form
|
||||
@ -291,15 +295,20 @@ class UserDefinedForm_Controller extends Page_Controller {
|
||||
* form to appear in a custom location on the page you can use $UserDefinedForm
|
||||
* in the content area to describe where you want the form
|
||||
*
|
||||
* @todo Abstract the Conditional Logic from the Form. This should be tied
|
||||
* to the EditableFormField class so that fields (eg checkboxes)
|
||||
* can define their own logic
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
public function Form() {
|
||||
$fields = new FieldSet();
|
||||
$fieldValidation = array();
|
||||
$fieldValidationRules = array();
|
||||
$CustomDisplayRules = "";
|
||||
$customDisplayRules = "";
|
||||
$defaults = "";
|
||||
$this->SubmitButtonText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
|
||||
|
||||
if($this->Fields()) {
|
||||
foreach($this->Fields() as $field) {
|
||||
|
||||
@ -312,8 +321,14 @@ class UserDefinedForm_Controller extends Page_Controller {
|
||||
// Set the Error Messages
|
||||
$errorMessage = sprintf(_t('Form.FIELDISREQUIRED').'.', strip_tags("'". ($field->Title ? $field->Title : $field->Name) . "'"));
|
||||
$errorMessage = ($field->CustomErrorMessage) ? $field->CustomErrorMessage : $errorMessage;
|
||||
|
||||
$fieldToAdd->setCustomValidationMessage($errorMessage);
|
||||
|
||||
// Set the right title on this field
|
||||
if($right = $field->getSetting('RightTitle')) {
|
||||
$fieldToAdd->setRightTitle($right);
|
||||
}
|
||||
|
||||
// Is this field required
|
||||
if($field->Required) {
|
||||
$fieldValidation[$field->Name] = $errorMessage;
|
||||
@ -424,7 +439,7 @@ class UserDefinedForm_Controller extends Page_Controller {
|
||||
break;
|
||||
}
|
||||
// put it all together
|
||||
$CustomDisplayRules .= $fieldToWatch.".$action(function() {
|
||||
$customDisplayRules .= $fieldToWatch.".$action(function() {
|
||||
if(". $expression ." ) {
|
||||
$(\"#". $fieldId ."\").".$view."();
|
||||
}
|
||||
@ -477,7 +492,7 @@ class UserDefinedForm_Controller extends Page_Controller {
|
||||
rules:
|
||||
$rules
|
||||
});
|
||||
$CustomDisplayRules
|
||||
$customDisplayRules
|
||||
});
|
||||
})(jQuery);
|
||||
JS
|
||||
|
@ -16,17 +16,12 @@ class EditableFormField extends DataObject {
|
||||
"Default" => "Varchar",
|
||||
"Sort" => "Int",
|
||||
"Required" => "Boolean",
|
||||
"CanDelete" => "Boolean",
|
||||
"CustomErrorMessage" => "Varchar(255)",
|
||||
"CustomRules" => "Text",
|
||||
"CustomSettings" => "Text",
|
||||
"CustomParameter" => "Varchar(200)"
|
||||
);
|
||||
|
||||
static $defaults = array(
|
||||
"CanDelete" => "1"
|
||||
);
|
||||
|
||||
static $has_one = array(
|
||||
"Parent" => "UserDefinedForm",
|
||||
);
|
||||
@ -46,7 +41,7 @@ class EditableFormField extends DataObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this multipleoption field readonly to the user
|
||||
* Is this field readonly to the user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@ -185,6 +180,7 @@ class EditableFormField extends DataObject {
|
||||
public function Dependencies() {
|
||||
return ($this->CustomRules) ? unserialize($this->CustomRules) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the custom validation fields for the field
|
||||
*
|
||||
@ -208,7 +204,7 @@ class EditableFormField extends DataObject {
|
||||
$outputFields->push($new);
|
||||
}
|
||||
$output->push(new ArrayData(array(
|
||||
'FieldName' => $this->FieldName(),
|
||||
'FieldName' => $this->getFieldName(),
|
||||
'Display' => $data['Display'],
|
||||
'Fields' => $outputFields,
|
||||
'ConditionField' => $data['ConditionField'],
|
||||
@ -230,19 +226,26 @@ class EditableFormField extends DataObject {
|
||||
|
||||
/**
|
||||
* Return the base name for this form field in the
|
||||
* form builder
|
||||
* form builder. Optionally returns the name with the given field
|
||||
*
|
||||
* @param String Field Name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public function FieldName() {
|
||||
return "Fields[".$this->ID."]";
|
||||
public function getFieldName($field = false) {
|
||||
return ($field) ? "Fields[".$this->ID."][".$field."]" : "Fields[".$this->ID."]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Fix this - shouldn't name be returning name?!?
|
||||
* Generate a name for the Setting field
|
||||
*
|
||||
* @param String name of the setting
|
||||
* @return String
|
||||
*/
|
||||
public function BaseName() {
|
||||
return $this->Name;
|
||||
public function getSettingFieldName($field) {
|
||||
$name = $this->getFieldName('CustomSettings');
|
||||
|
||||
return $name . '[' . $field .']';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,16 +259,16 @@ class EditableFormField extends DataObject {
|
||||
* @access public
|
||||
*/
|
||||
public function populateFromPostData($data) {
|
||||
$this->Title = (isset($data['Title'])) ? $data['Title']: "";
|
||||
$this->Default = (isset($data['Default'])) ? $data['Default'] : "";
|
||||
$this->Sort = (isset($data['Sort'])) ? $data['Sort'] : null;
|
||||
$this->Required = !empty($data['Required']) ? 1 : 0;
|
||||
$this->CanDelete = (isset($data['CanDelete']) && !$data['CanDelete']) ? 0 : 1;
|
||||
$this->Name = $this->class.$this->ID;
|
||||
$this->CustomErrorMessage = (isset($data['CustomErrorMessage'])) ? $data['CustomErrorMessage'] : "";
|
||||
$this->CustomRules = "";
|
||||
$this->CustomSettings = "";
|
||||
$this->ShowOnLoad = (isset($data['ShowOnLoad']) && $data['ShowOnLoad'] == "Show") ? 1 : 0;
|
||||
$this->Title = (isset($data['Title'])) ? $data['Title']: "";
|
||||
$this->Default = (isset($data['Default'])) ? $data['Default'] : "";
|
||||
$this->Sort = (isset($data['Sort'])) ? $data['Sort'] : null;
|
||||
$this->Required = !empty($data['Required']) ? 1 : 0;
|
||||
$this->Name = $this->class.$this->ID;
|
||||
$this->ShowOnLoad = (isset($data['ShowOnLoad']) && $data['ShowOnLoad'] == "Show") ? 1 : 0;
|
||||
$this->CustomRules = "";
|
||||
$this->CustomErrorMessage = (isset($data['CustomErrorMessage'])) ? $data['CustomErrorMessage'] : "";
|
||||
$this->CustomSettings = "";
|
||||
|
||||
// custom settings
|
||||
if(isset($data['CustomSettings'])) {
|
||||
$this->setFieldSettings($data['CustomSettings']);
|
||||
@ -301,7 +304,13 @@ class EditableFormField extends DataObject {
|
||||
* @return FieldSet
|
||||
*/
|
||||
public function getFieldConfiguration() {
|
||||
return new FieldSet();
|
||||
return new FieldSet(
|
||||
new TextField(
|
||||
$this->getSettingFieldName('RightTitle'),
|
||||
_t('EditableFormField.RIGHTTITLE', 'Right Title'),
|
||||
$this->getSetting('RightTitle')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,8 +321,8 @@ class EditableFormField extends DataObject {
|
||||
*/
|
||||
public function getFieldValidationOptions() {
|
||||
$fields = new FieldSet(
|
||||
new CheckboxField("Fields[$this->ID][Required]", _t('EditableFormField.REQUIRED', 'Is this field Required?'), $this->Required),
|
||||
new TextField("Fields[$this->ID][CustomErrorMessage]", _t('EditableFormField.CUSTOMERROR','Custom Error Message'), $this->CustomErrorMessage)
|
||||
new CheckboxField($this->getFieldName('Required'), _t('EditableFormField.REQUIRED', 'Is this field Required?'), $this->Required),
|
||||
new TextField($this->getFieldName('CustomErrorMessage'), _t('EditableFormField.CUSTOMERROR','Custom Error Message'), $this->CustomErrorMessage)
|
||||
);
|
||||
|
||||
if(!$this->canEdit()) {
|
||||
@ -321,6 +330,7 @@ class EditableFormField extends DataObject {
|
||||
$fields->performReadonlyTransformation();
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
@ -342,46 +352,16 @@ class EditableFormField extends DataObject {
|
||||
public function getSubmittedFormField() {
|
||||
return new SubmittedFormField();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Show this form field (and its related value) in the reports and in emails.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function showInReports() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function prepopulate($value) {
|
||||
$this->prepopulateFromMap($this->parsePrepopulateValue($value));
|
||||
}
|
||||
|
||||
protected function parsePrepopulateValue($value) {
|
||||
$paramList = explode(',', $value);
|
||||
$paramMap = array();
|
||||
|
||||
foreach($paramList as $param) {
|
||||
|
||||
if(preg_match( '/([^=]+)=(.+)/', $param, $match)) {
|
||||
if(isset($paramMap[$match[1]]) && is_array($paramMap[$match[1]])) {
|
||||
$paramMap[$match[1]][] = $match[2];
|
||||
} else if(isset( $paramMap[$match[1]])) {
|
||||
$paramMap[$match[1]] = array($paramMap[$match[1]]);
|
||||
$paramMap[$match[1]][] = $match[2];
|
||||
} else {
|
||||
$paramMap[$match[1]] = $match[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $paramMap;
|
||||
}
|
||||
|
||||
protected function prepopulateFromMap($paramMap) {
|
||||
foreach($paramMap as $field => $fieldValue) {
|
||||
if(!is_array($fieldValue)) {
|
||||
$this->$field = $fieldValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Type() {
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the validation information related to this field. This is
|
||||
|
@ -23,6 +23,11 @@
|
||||
|
||||
/*-------------------- FIELD EDITOR ----------------------- */
|
||||
|
||||
/**
|
||||
* Update the Field sortable
|
||||
*/
|
||||
update_sortable();
|
||||
|
||||
/**
|
||||
* Create a new instance of a field in the current form
|
||||
* area. the type information should all be on this object
|
||||
@ -42,7 +47,7 @@
|
||||
var securityID = ($("#SecurityID").length > 0) ? '&SecurityID='+$("#SecurityID").attr("value") : '';
|
||||
var type = $(this).siblings("select").val();
|
||||
|
||||
//send ajax request to the page
|
||||
// send ajax request to the page
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: action,
|
||||
@ -65,7 +70,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
$("#Fields_fields").sortable("refresh");
|
||||
update_sortable();
|
||||
|
||||
return false;
|
||||
});
|
||||
@ -83,7 +88,8 @@
|
||||
$(domElement).text(value);
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Show the more options popdown. Or hide it if we
|
||||
* currently have it open
|
||||
@ -147,7 +153,7 @@
|
||||
var action = $("#Form_EditForm").attr("action") + '/field/Fields/addoptionfield';
|
||||
var parent = $(this).attr("rel");
|
||||
|
||||
//send ajax request to the page
|
||||
// send ajax request to the page
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: action,
|
||||
@ -164,6 +170,9 @@
|
||||
statusMessage(ss.i18n._t('UserForms.ERRORCREATINGFIELD', 'Error Creating Field'));
|
||||
}
|
||||
});
|
||||
|
||||
update_sortable();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
@ -181,52 +190,6 @@
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Sort Fields in the Field List
|
||||
*/
|
||||
$("#Fields_fields").sortable({
|
||||
handle : '.fieldHandler',
|
||||
cursor: 'pointer',
|
||||
items: 'li.EditableFormField',
|
||||
placeholder: 'removed-form-field',
|
||||
opacity: 0.6,
|
||||
revert: true,
|
||||
change : function (event, ui) {
|
||||
$("#Fields_fields").sortable('refreshPositions');
|
||||
},
|
||||
update : function (event, ui) {
|
||||
// get all the fields
|
||||
var sort = 1;
|
||||
$("li.EditableFormField").each(function() {
|
||||
$(this).find(".sortHidden").val(sort++);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Sort Options in a Field List - Such as options in a
|
||||
* dropdown field.
|
||||
*/
|
||||
$(".editableOptions").sortable({
|
||||
handle : '.handle',
|
||||
cursor: 'pointer',
|
||||
items: 'li',
|
||||
placeholder: 'removed-form-field',
|
||||
opacity: 0.6,
|
||||
revert: true,
|
||||
change : function (event, ui) {
|
||||
$(this).sortable('refreshPositions');
|
||||
},
|
||||
update : function (event, ui) {
|
||||
// get all the fields
|
||||
var sort = 1;
|
||||
$(".editableOptions li").each(function() {
|
||||
$(this).find(".sortOptionHidden").val(sort++);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Custom Rules Interface
|
||||
*/
|
||||
@ -282,10 +245,60 @@
|
||||
// append to the list
|
||||
currentRules.append(newRule);
|
||||
|
||||
$(".editableOptions").sortable("refresh");
|
||||
update_sortable();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Store the sortable as a function which we can call
|
||||
*/
|
||||
function update_sortable() {
|
||||
/**
|
||||
* Sort Fields in the Field List
|
||||
*/
|
||||
$("#Fields_fields").sortable({
|
||||
handle : '.fieldHandler',
|
||||
cursor: 'pointer',
|
||||
items: 'li.EditableFormField',
|
||||
placeholder: 'removed-form-field',
|
||||
opacity: 0.6,
|
||||
revert: true,
|
||||
change : function (event, ui) {
|
||||
$("#Fields_fields").sortable('refreshPositions');
|
||||
},
|
||||
update : function (event, ui) {
|
||||
// get all the fields
|
||||
var sort = 1;
|
||||
$("li.EditableFormField").each(function() {
|
||||
$(this).find(".sortHidden").val(sort++);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Sort Options in a Field List - Such as options in a
|
||||
* dropdown field.
|
||||
*/
|
||||
$(".editableOptions").sortable({
|
||||
handle : '.handle',
|
||||
cursor: 'pointer',
|
||||
items: 'li',
|
||||
placeholder: 'removed-form-field',
|
||||
opacity: 0.6,
|
||||
revert: true,
|
||||
change : function (event, ui) {
|
||||
$(this).sortable('refreshPositions');
|
||||
},
|
||||
update : function (event, ui) {
|
||||
// get all the fields
|
||||
var sort = 1;
|
||||
$(".editableOptions li").each(function() {
|
||||
$(this).find(".sortOptionHidden").val(sort++);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
(jQuery);
|
@ -1,5 +1,5 @@
|
||||
<!-- JS Relys on EditableFormField as a class - and the 3 ids in this order - do not change -->
|
||||
<li class="$ClassName EditableFormField" id="$Name.ATT EditableItem_$Pos $BaseName">
|
||||
<li class="$ClassName EditableFormField" id="$Name.ATT EditableItem_$Pos $Name">
|
||||
<div class="fieldInfo">
|
||||
<% if isReadonly %>
|
||||
<img class="fieldHandler" src="sapphire/images/drag_readonly.gif" alt="<% _t('LOCKED', 'These fields cannot be modified') %>" />
|
||||
@ -127,7 +127,6 @@
|
||||
<% end_if %>
|
||||
|
||||
<!-- Hidden option Fields -->
|
||||
<input type="hidden" class="canDeleteHidden" name="{$FieldName}[CanDelete]" value="$CanDelete" />
|
||||
<input type="hidden" class="typeHidden" name="{$FieldName}[Type]" value="$ClassName" />
|
||||
<input type="hidden" class="sortHidden" name="{$FieldName}[Sort]" value="$Sort" />
|
||||
</li>
|
@ -7,7 +7,7 @@
|
||||
<select class="fieldOption customRuleField" name="{$FieldName}[CustomRules][$Pos][ConditionField]">
|
||||
<option value="" selected="selected"></option>
|
||||
<% control Fields %>
|
||||
<option value="$BaseName" <% if isSelected %>selected="selected"<% end_if %>>$Title</option>
|
||||
<option value="$Name" <% if isSelected %>selected="selected"<% end_if %>>$Title</option>
|
||||
<% end_control %>
|
||||
</select>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user