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:
Will Rossiter 2010-07-07 09:17:37 +00:00
parent c408b632e3
commit 745b614710
5 changed files with 127 additions and 120 deletions

View File

@ -1,8 +1,11 @@
<?php <?php
/** /**
* User Defined Form Page type that lets users build a form in the CMS * User Defined Form Page type that lets users build a form in the CMS
* using the FieldEditor Field. * using the FieldEditor Field.
* *
* @todo Allow UserDefinedForm instances on Page subclasses (eg via decorator)
*
* @package userforms * @package userforms
*/ */
@ -280,6 +283,7 @@ class UserDefinedForm_Controller extends Page_Controller {
); );
} }
} }
return array( return array(
'Content' => DBField::create('HTMLText', $this->Content), 'Content' => DBField::create('HTMLText', $this->Content),
'Form' => $this->Form '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 * 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 * 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 * @return Form
*/ */
public function Form() { public function Form() {
$fields = new FieldSet(); $fields = new FieldSet();
$fieldValidation = array(); $fieldValidation = array();
$fieldValidationRules = array(); $fieldValidationRules = array();
$CustomDisplayRules = ""; $customDisplayRules = "";
$defaults = ""; $defaults = "";
$this->SubmitButtonText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit'); $this->SubmitButtonText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
if($this->Fields()) { if($this->Fields()) {
foreach($this->Fields() as $field) { foreach($this->Fields() as $field) {
@ -312,8 +321,14 @@ class UserDefinedForm_Controller extends Page_Controller {
// Set the Error Messages // Set the Error Messages
$errorMessage = sprintf(_t('Form.FIELDISREQUIRED').'.', strip_tags("'". ($field->Title ? $field->Title : $field->Name) . "'")); $errorMessage = sprintf(_t('Form.FIELDISREQUIRED').'.', strip_tags("'". ($field->Title ? $field->Title : $field->Name) . "'"));
$errorMessage = ($field->CustomErrorMessage) ? $field->CustomErrorMessage : $errorMessage; $errorMessage = ($field->CustomErrorMessage) ? $field->CustomErrorMessage : $errorMessage;
$fieldToAdd->setCustomValidationMessage($errorMessage); $fieldToAdd->setCustomValidationMessage($errorMessage);
// Set the right title on this field
if($right = $field->getSetting('RightTitle')) {
$fieldToAdd->setRightTitle($right);
}
// Is this field required // Is this field required
if($field->Required) { if($field->Required) {
$fieldValidation[$field->Name] = $errorMessage; $fieldValidation[$field->Name] = $errorMessage;
@ -424,7 +439,7 @@ class UserDefinedForm_Controller extends Page_Controller {
break; break;
} }
// put it all together // put it all together
$CustomDisplayRules .= $fieldToWatch.".$action(function() { $customDisplayRules .= $fieldToWatch.".$action(function() {
if(". $expression ." ) { if(". $expression ." ) {
$(\"#". $fieldId ."\").".$view."(); $(\"#". $fieldId ."\").".$view."();
} }
@ -477,7 +492,7 @@ class UserDefinedForm_Controller extends Page_Controller {
rules: rules:
$rules $rules
}); });
$CustomDisplayRules $customDisplayRules
}); });
})(jQuery); })(jQuery);
JS JS

View File

@ -16,17 +16,12 @@ class EditableFormField extends DataObject {
"Default" => "Varchar", "Default" => "Varchar",
"Sort" => "Int", "Sort" => "Int",
"Required" => "Boolean", "Required" => "Boolean",
"CanDelete" => "Boolean",
"CustomErrorMessage" => "Varchar(255)", "CustomErrorMessage" => "Varchar(255)",
"CustomRules" => "Text", "CustomRules" => "Text",
"CustomSettings" => "Text", "CustomSettings" => "Text",
"CustomParameter" => "Varchar(200)" "CustomParameter" => "Varchar(200)"
); );
static $defaults = array(
"CanDelete" => "1"
);
static $has_one = array( static $has_one = array(
"Parent" => "UserDefinedForm", "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 * @return bool
*/ */
@ -185,6 +180,7 @@ class EditableFormField extends DataObject {
public function Dependencies() { public function Dependencies() {
return ($this->CustomRules) ? unserialize($this->CustomRules) : array(); return ($this->CustomRules) ? unserialize($this->CustomRules) : array();
} }
/** /**
* Return the custom validation fields for the field * Return the custom validation fields for the field
* *
@ -208,7 +204,7 @@ class EditableFormField extends DataObject {
$outputFields->push($new); $outputFields->push($new);
} }
$output->push(new ArrayData(array( $output->push(new ArrayData(array(
'FieldName' => $this->FieldName(), 'FieldName' => $this->getFieldName(),
'Display' => $data['Display'], 'Display' => $data['Display'],
'Fields' => $outputFields, 'Fields' => $outputFields,
'ConditionField' => $data['ConditionField'], 'ConditionField' => $data['ConditionField'],
@ -230,19 +226,26 @@ class EditableFormField extends DataObject {
/** /**
* Return the base name for this form field in the * 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 * @return String
*/ */
public function FieldName() { public function getFieldName($field = false) {
return "Fields[".$this->ID."]"; 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() { public function getSettingFieldName($field) {
return $this->Name; $name = $this->getFieldName('CustomSettings');
return $name . '[' . $field .']';
} }
/** /**
@ -256,16 +259,16 @@ class EditableFormField extends DataObject {
* @access public * @access public
*/ */
public function populateFromPostData($data) { public function populateFromPostData($data) {
$this->Title = (isset($data['Title'])) ? $data['Title']: ""; $this->Title = (isset($data['Title'])) ? $data['Title']: "";
$this->Default = (isset($data['Default'])) ? $data['Default'] : ""; $this->Default = (isset($data['Default'])) ? $data['Default'] : "";
$this->Sort = (isset($data['Sort'])) ? $data['Sort'] : null; $this->Sort = (isset($data['Sort'])) ? $data['Sort'] : null;
$this->Required = !empty($data['Required']) ? 1 : 0; $this->Required = !empty($data['Required']) ? 1 : 0;
$this->CanDelete = (isset($data['CanDelete']) && !$data['CanDelete']) ? 0 : 1; $this->Name = $this->class.$this->ID;
$this->Name = $this->class.$this->ID; $this->ShowOnLoad = (isset($data['ShowOnLoad']) && $data['ShowOnLoad'] == "Show") ? 1 : 0;
$this->CustomErrorMessage = (isset($data['CustomErrorMessage'])) ? $data['CustomErrorMessage'] : ""; $this->CustomRules = "";
$this->CustomRules = ""; $this->CustomErrorMessage = (isset($data['CustomErrorMessage'])) ? $data['CustomErrorMessage'] : "";
$this->CustomSettings = ""; $this->CustomSettings = "";
$this->ShowOnLoad = (isset($data['ShowOnLoad']) && $data['ShowOnLoad'] == "Show") ? 1 : 0;
// custom settings // custom settings
if(isset($data['CustomSettings'])) { if(isset($data['CustomSettings'])) {
$this->setFieldSettings($data['CustomSettings']); $this->setFieldSettings($data['CustomSettings']);
@ -301,7 +304,13 @@ class EditableFormField extends DataObject {
* @return FieldSet * @return FieldSet
*/ */
public function getFieldConfiguration() { 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() { public function getFieldValidationOptions() {
$fields = new FieldSet( $fields = new FieldSet(
new CheckboxField("Fields[$this->ID][Required]", _t('EditableFormField.REQUIRED', 'Is this field Required?'), $this->Required), new CheckboxField($this->getFieldName('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 TextField($this->getFieldName('CustomErrorMessage'), _t('EditableFormField.CUSTOMERROR','Custom Error Message'), $this->CustomErrorMessage)
); );
if(!$this->canEdit()) { if(!$this->canEdit()) {
@ -321,6 +330,7 @@ class EditableFormField extends DataObject {
$fields->performReadonlyTransformation(); $fields->performReadonlyTransformation();
} }
} }
return $fields; return $fields;
} }
@ -342,46 +352,16 @@ class EditableFormField extends DataObject {
public function getSubmittedFormField() { public function getSubmittedFormField() {
return new SubmittedFormField(); return new SubmittedFormField();
} }
/**
* Show this form field (and its related value) in the reports and in emails.
*
* @return bool
*/
function showInReports() { function showInReports() {
return true; 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 * Return the validation information related to this field. This is

View File

@ -23,6 +23,11 @@
/*-------------------- FIELD EDITOR ----------------------- */ /*-------------------- FIELD EDITOR ----------------------- */
/**
* Update the Field sortable
*/
update_sortable();
/** /**
* Create a new instance of a field in the current form * Create a new instance of a field in the current form
* area. the type information should all be on this object * area. the type information should all be on this object
@ -42,7 +47,7 @@
var securityID = ($("#SecurityID").length > 0) ? '&SecurityID='+$("#SecurityID").attr("value") : ''; var securityID = ($("#SecurityID").length > 0) ? '&SecurityID='+$("#SecurityID").attr("value") : '';
var type = $(this).siblings("select").val(); var type = $(this).siblings("select").val();
//send ajax request to the page // send ajax request to the page
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: action, url: action,
@ -65,7 +70,7 @@
} }
}); });
$("#Fields_fields").sortable("refresh"); update_sortable();
return false; return false;
}); });
@ -83,7 +88,8 @@
$(domElement).text(value); $(domElement).text(value);
} }
}); });
}) });
/** /**
* Show the more options popdown. Or hide it if we * Show the more options popdown. Or hide it if we
* currently have it open * currently have it open
@ -147,7 +153,7 @@
var action = $("#Form_EditForm").attr("action") + '/field/Fields/addoptionfield'; var action = $("#Form_EditForm").attr("action") + '/field/Fields/addoptionfield';
var parent = $(this).attr("rel"); var parent = $(this).attr("rel");
//send ajax request to the page // send ajax request to the page
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: action, url: action,
@ -164,6 +170,9 @@
statusMessage(ss.i18n._t('UserForms.ERRORCREATINGFIELD', 'Error Creating Field')); statusMessage(ss.i18n._t('UserForms.ERRORCREATINGFIELD', 'Error Creating Field'));
} }
}); });
update_sortable();
return false; return false;
}); });
@ -181,52 +190,6 @@
return false; 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 * Custom Rules Interface
*/ */
@ -282,10 +245,60 @@
// append to the list // append to the list
currentRules.append(newRule); currentRules.append(newRule);
$(".editableOptions").sortable("refresh"); update_sortable();
return false; 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); (jQuery);

View File

@ -1,5 +1,5 @@
<!-- JS Relys on EditableFormField as a class - and the 3 ids in this order - do not change --> <!-- 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"> <div class="fieldInfo">
<% if isReadonly %> <% if isReadonly %>
<img class="fieldHandler" src="sapphire/images/drag_readonly.gif" alt="<% _t('LOCKED', 'These fields cannot be modified') %>" /> <img class="fieldHandler" src="sapphire/images/drag_readonly.gif" alt="<% _t('LOCKED', 'These fields cannot be modified') %>" />
@ -127,7 +127,6 @@
<% end_if %> <% end_if %>
<!-- Hidden option Fields --> <!-- 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="typeHidden" name="{$FieldName}[Type]" value="$ClassName" />
<input type="hidden" class="sortHidden" name="{$FieldName}[Sort]" value="$Sort" /> <input type="hidden" class="sortHidden" name="{$FieldName}[Sort]" value="$Sort" />
</li> </li>

View File

@ -7,7 +7,7 @@
<select class="fieldOption customRuleField" name="{$FieldName}[CustomRules][$Pos][ConditionField]"> <select class="fieldOption customRuleField" name="{$FieldName}[CustomRules][$Pos][ConditionField]">
<option value="" selected="selected"></option> <option value="" selected="selected"></option>
<% control Fields %> <% 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 %> <% end_control %>
</select> </select>