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
/**
* 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

View File

@ -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 .']';
}
/**
@ -260,12 +263,12 @@ class EditableFormField extends DataObject {
$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->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;
}
@ -343,46 +353,16 @@ class EditableFormField extends DataObject {
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
* interrupted as a JSON object for validate plugin and used in the

View File

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

View File

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

View File

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