From 83d1f2fe869b5b26a650cdfab8cc5417dc6383db Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 17 Apr 2009 02:26:40 +0000 Subject: [PATCH] ENHANCEMENT: rewrote the user defined forms cms JS into jquery. ENHANCEMENT: rewrote templates and removed dulicate code. APICHANGE: created parent class for EditableFormField, EditableOption and EditableMultiOption to prevent code duplication. MINOR: added icon for literal field. MINOR: added quick unit test. MINOR: removed dulicate images --- code/editor/EditableButton.php | 6 +- code/editor/EditableCheckbox.php | 4 +- code/editor/EditableCheckboxGroupField.php | 102 +--- code/editor/EditableCheckboxOption.php | 82 --- code/editor/EditableDateField.php | 20 +- code/editor/EditableDropdown.php | 113 +--- code/editor/EditableDropdownOption.php | 77 --- code/editor/EditableEmailField.php | 5 +- code/editor/EditableFileField.php | 6 +- code/editor/EditableFormField.php | 140 +++-- code/editor/EditableFormHeading.php | 11 +- code/editor/EditableLiteralField.php | 32 +- code/editor/EditableMemberListField.php | 4 +- code/editor/EditableMultipleOptionField.php | 160 +++++ code/editor/EditableOption.php | 71 +++ code/editor/EditableRadioField.php | 154 +---- code/editor/EditableRadioOption.php | 84 --- code/editor/EditableTextField.php | 7 +- code/editor/FieldEditor.php | 157 ++--- css/FieldEditor.css | 9 +- images/{fe_icons => }/editablecheckbox.png | Bin ...xes.png => editablecheckboxgroupfield.png} | Bin images/{fe_icons => }/editabledatefield.png | Bin .../dropdown.png => editabledropdown.png} | Bin images/{fe_icons => }/editableemailfield.png | Bin images/{fe_icons => }/editablefilefield.png | Bin images/{fe_icons => }/editableformheading.png | Bin images/editableliteralfield.png | Bin 0 -> 731 bytes images/fe_icons/checkbox.png | Bin 1479 -> 0 bytes images/fe_icons/date-time.png | Bin 1606 -> 0 bytes .../{radio.png => editableradiofield.png} | Bin images/fe_icons/file-upload.png | Bin 1730 -> 0 bytes images/fe_icons/heading.png | Bin 3601 -> 0 bytes images/fe_icons/text-email.png | Bin 1532 -> 0 bytes images/fe_icons/text-numbers.png | Bin 1514 -> 0 bytes images/fe_icons/text-password.png | Bin 1522 -> 0 bytes images/fe_icons/text.png | Bin 1485 -> 0 bytes javascript/FieldEditor.js | 555 ------------------ javascript/UserForm.js | 141 ++++- templates/EditableCheckbox.ss | 26 - templates/EditableCheckboxGroupField.ss | 51 -- templates/EditableCheckboxOption.ss | 10 - templates/EditableDateField.ss | 20 - templates/EditableDropdown.ss | 50 -- templates/EditableDropdownOption.ss | 10 - templates/EditableEmailField.ss | 25 - templates/EditableFileField.ss | 20 - templates/EditableFormField.ss | 81 ++- templates/EditableFormFieldOption.ss | 15 - templates/EditableFormHeading.ss | 17 - templates/EditableLiteralField.ss | 20 - templates/EditableOption.ss | 11 + templates/EditableRadioField.ss | 51 -- templates/EditableRadioOption.ss | 10 - templates/EditableTextField.ss | 20 - tests/UserDefinedFormTest.php | 28 + 56 files changed, 683 insertions(+), 1722 deletions(-) delete mode 100755 code/editor/EditableCheckboxOption.php delete mode 100755 code/editor/EditableDropdownOption.php create mode 100644 code/editor/EditableMultipleOptionField.php create mode 100644 code/editor/EditableOption.php delete mode 100755 code/editor/EditableRadioOption.php rename images/{fe_icons => }/editablecheckbox.png (100%) rename images/{fe_icons/checkboxes.png => editablecheckboxgroupfield.png} (100%) rename images/{fe_icons => }/editabledatefield.png (100%) rename images/{fe_icons/dropdown.png => editabledropdown.png} (100%) rename images/{fe_icons => }/editableemailfield.png (100%) rename images/{fe_icons => }/editablefilefield.png (100%) rename images/{fe_icons => }/editableformheading.png (100%) create mode 100644 images/editableliteralfield.png delete mode 100755 images/fe_icons/checkbox.png delete mode 100755 images/fe_icons/date-time.png rename images/fe_icons/{radio.png => editableradiofield.png} (100%) delete mode 100755 images/fe_icons/file-upload.png delete mode 100755 images/fe_icons/heading.png delete mode 100755 images/fe_icons/text-email.png delete mode 100755 images/fe_icons/text-numbers.png delete mode 100755 images/fe_icons/text-password.png delete mode 100755 images/fe_icons/text.png delete mode 100755 templates/EditableCheckbox.ss delete mode 100755 templates/EditableCheckboxGroupField.ss delete mode 100755 templates/EditableCheckboxOption.ss delete mode 100755 templates/EditableDateField.ss delete mode 100755 templates/EditableDropdown.ss delete mode 100755 templates/EditableDropdownOption.ss delete mode 100755 templates/EditableEmailField.ss delete mode 100755 templates/EditableFileField.ss delete mode 100755 templates/EditableFormFieldOption.ss delete mode 100755 templates/EditableFormHeading.ss delete mode 100644 templates/EditableLiteralField.ss create mode 100644 templates/EditableOption.ss delete mode 100755 templates/EditableRadioField.ss delete mode 100755 templates/EditableRadioOption.ss delete mode 100755 templates/EditableTextField.ss create mode 100644 tests/UserDefinedFormTest.php diff --git a/code/editor/EditableButton.php b/code/editor/EditableButton.php index b03d97d..ae796f7 100755 --- a/code/editor/EditableButton.php +++ b/code/editor/EditableButton.php @@ -1,9 +1,9 @@ readonly = true; - return $this->Option(); - } - - function isReadonly() { - return $this->readonly; - } - - static $has_many = array( - "Options" => "EditableCheckboxOption" - ); - static $singular_name = "Checkbox group"; + static $plural_name = "Checkbox groups"; - - function duplicate() { - $clonedNode = parent::duplicate(); - - foreach( $this->Options() as $field ) { - $newField = $field->duplicate(); - $newField->ParentID = $clonedNode->ID; - $newField->write(); - } - - return $clonedNode; - } - - function delete() { - $options = $this->Options(); - - foreach( $options as $option ) - $option->delete(); - - parent::delete(); - } - - function EditSegment() { - return $this->renderWith( $this->class ); - } - - function populateFromPostData( $data ) { - parent::populateFromPostData( $data ); - - $fieldSet = $this->Options(); - - $deletedOptions = explode( ',', $data['Deleted'] ); - $optionNumber = 0; - - // store default, etc - foreach($fieldSet as $option) { - if($deletedOptions && array_search($option->ID, $deletedOptions) !== false) { - $option->delete(); - continue; - } - - if(isset($data[$option->ID])) { - $option->populateFromPostData( $data[$option->ID] ); - } - - unset( $data[$option->ID] ); - } - - foreach($data as $tempID => $optionData) { - if(!$tempID || !is_array($optionData) || empty($optionData) || !preg_match('/^_?\d+$/', $tempID)) { - continue; - } - - // what will we name the new option? - $newOption = new EditableCheckboxOption(); - $newOption->Name = 'option' . (string)$optionNumber++; - $newOption->ParentID = $this->ID; - $newOption->populateFromPostData($optionData); - } - } - + function DefaultOption() { $defaultOption = 0; @@ -98,14 +25,6 @@ class EditableCheckboxGroupField extends EditableFormField { return -1; } - function getFormField() { - return $this->createField(); - } - - function getFilterField() { - return $this->createField( true ); - } - function createField($asFilter = false) { $optionSet = $this->Options(); $options = array(); @@ -127,7 +46,7 @@ class EditableCheckboxGroupField extends EditableFormField { $entries = array($data[$this->Name]); } - $selectedOptions = DataObject::get('EditableCheckboxOption', "ParentID={$this->ID} AND ID IN (" . implode(',', $entries) . ")"); + $selectedOptions = DataObject::get('EditableOption', "ParentID={$this->ID} AND ID IN (" . implode(',', $entries) . ")"); foreach($selectedOptions as $selected) { if(!$result) { $result = $selected->Title; @@ -138,11 +57,6 @@ class EditableCheckboxGroupField extends EditableFormField { return $result; } - - function TemplateOption() { - $option = new EditableCheckboxOption(); - return $option->EditSegment(); - } } ?> \ No newline at end of file diff --git a/code/editor/EditableCheckboxOption.php b/code/editor/EditableCheckboxOption.php deleted file mode 100755 index 24a4f3f..0000000 --- a/code/editor/EditableCheckboxOption.php +++ /dev/null @@ -1,82 +0,0 @@ - "Varchar", - "Title" => "Varchar", - "Default" => "Boolean", - "Sort" => "Int" - ); - static $has_one = array( - "Parent" => "EditableCheckboxGroupField", - ); - - static $singular_name = "Checkbox option"; - static $plural_name = "Checkbox options"; - - function EditSegment() { - return $this->renderWith('EditableFormFieldOption'); - } - - function TitleField() { - return new TextField( "Fields[{$this->ParentID}][{$this->ID}][Title]", null, $this->Title ); - } - - function Name() { - return "Fields[{$this->ParentID}][{$this->ID}]"; - } - - function populateFromPostData($data) { - $this->Title = $data['Title']; - if(isset($data['Default'])) { - $this->setField('Default', $data['Default']); - } - $this->Sort = $data['Sort']; - $this->write(); - } - - function Option() { - // return new radio field - /*$title = Convert::raw2att( $this->Title ); - - $default = ""; - - if( $this->getField('Default') ) - $default = '+'; - else - $default = '-'; - - //Debug::show($this); - return '';*/ - - return $this->EditSegment(); - } - - function ReadonlyOption() { - $this->readonly = true; - return $this->EditSegment(); - } - - function DefaultSelect() { - if( $this->readonly ) - $disabled = " disabled=\"disabled\""; - else - $disabled = ''; - - if( $this->getField('Default') ) - $default = " checked=\"checked\""; - else - $default = ''; - - return "ParentID}][{$this->ID}][Default]\" value=\"1\"".$disabled.$default." />"; - } -} -?> \ No newline at end of file diff --git a/code/editor/EditableDateField.php b/code/editor/EditableDateField.php index ae21e3a..b982fe1 100755 --- a/code/editor/EditableDateField.php +++ b/code/editor/EditableDateField.php @@ -1,9 +1,10 @@ "EditableDropdownOption" - ); +class EditableDropdown extends EditableMultipleOptionField { static $singular_name = 'Dropdown'; + static $plural_name = 'Dropdowns'; - - function delete() { - $options = $this->Options(); - foreach( $options as $option ) - $option->delete(); - - parent::delete(); - } - function EditSegment() { - return $this->renderWith( $this->class ); - } - - function populateFromPostData( $data ) { - - parent::populateFromPostData( $data ); - - $fieldSet = $this->Options(); - - $deletedOptions = explode( ',', $data['Deleted'] ); - - // store default, etc - foreach( $fieldSet as $option ) { - - if( $deletedOptions && array_search( $option->ID, $deletedOptions ) !== false ) { - $option->delete(); - continue; - } - - if(isset($option) && isset($data[$option->ID])) { - $option->setField('Default', isset($data['Default']) ? ($option->ID == $data['Default']) : false); - $option->populateFromPostData( $data[$option->ID] ); - } - - unset( $data[$option->ID] ); - } - - $optionNumber = 0; - foreach( $data as $tempID => $optionData ) { - - if( !$tempID || !is_array( $optionData ) || empty( $optionData ) || !preg_match('/^_?\d+$/', $tempID ) ) - continue; - - // what will we name the new option? - $newOption = new EditableDropdownOption(); - $newOption->Name = 'option' . (string)$optionNumber++; - $newOption->ParentID = $this->ID; - if(isset($data['Default'])) { - $newOption->setField('Default', $tempID == $data['Default']); - } - - if( Director::is_ajax() ) { - $fieldID = $this->ID; - $fieldEditorName = $this->editor ? $this->editor->Name() : 'Fields'; - $prefix = $fieldEditorName . '[' . $fieldID . ']'; - $newID = $newOption->ID; - $newSort = $newOption->Sort; - echo "\$('". $fieldEditorName . "[$fieldID]').updateOption('$prefix','$tempID','$newID','$newSort');"; - } - - if( !$optionData['Sort'] ) { - - } - - $newOption->populateFromPostData( $optionData ); - } - } - - function getFormField() { - return $this->createField(); - } - - function getFilterField() { - return $this->createField( true ); - } - - function createField( $asFilter = false ) { + function createField($asFilter = false) { $optionSet = $this->Options(); $options = array(); - if( $asFilter ) + if($asFilter) { $options['-1'] = "(Any)"; - + } $defaultOption = '-1'; foreach( $optionSet as $option ) { $options[$option->Title] = $option->Title; - if( $option->getField('Default') && !$asFilter ) $defaultOption = $option->Title; + if($option->getField('Default') && !$asFilter) $defaultOption = $option->Title; } return new DropdownField( $this->Name, $this->Title, $options, $defaultOption ); } - - function TemplateOption() { - $option = new EditableDropdownOption(); - return $option->EditSegment(); - } - - function duplicate() { - $clonedNode = parent::duplicate(); - - foreach( $this->Options() as $field ) { - $newField = $field->duplicate(); - $newField->ParentID = $clonedNode->ID; - $newField->write(); - } - - return $clonedNode; - } + } ?> diff --git a/code/editor/EditableDropdownOption.php b/code/editor/EditableDropdownOption.php deleted file mode 100755 index 7d1bfd0..0000000 --- a/code/editor/EditableDropdownOption.php +++ /dev/null @@ -1,77 +0,0 @@ -readonly = true; - return $this->EditSegment(); - } - - function isReadonly() { - return $this->readonly; - } - - static $default_sort = "Sort"; - - // add required here? - static $db = array( - "Name" => "Varchar", - "Title" => "Varchar", - "Default" => "Boolean", - "Sort" => "Int" - ); - static $has_one = array( - "Parent" => "EditableDropdown", - ); - - static $singular_name = 'Dropdown option'; - static $plural_name = 'Dropdown options'; - - function EditSegment() { - return $this->renderWith('EditableFormFieldOption'); - } - - function TitleField() { - return new TextField( "Fields[{$this->ParentID}][{$this->ID}][Title]", null, $this->Title ); - } - - function Name() { - return "Fields[{$this->ParentID}][{$this->ID}]"; - } - - function populateFromPostData( $data ) { - $this->Title = $data['Title']; - $this->Sort = $data['Sort']; - $this->write(); - } - - function Option() { - // return new radio field - /*$title = $this->Title; - - $default = ""; - - if( $this->getField('Default') ) - $default = 'class="default"'; - - //Debug::show($this); - return '';*/ - - return $this->EditSegment(); - } - - function DefaultSelect() { - $disabled = ($this->readonly) ? " disabled=\"disabled\"" : ''; - - $default = ($this->Parent()->getField('Default') == $this->ID) ? " checked=\"checked\"" : ""; - - return "ParentID}][Default]\" value=\"{$this->ID}\"".$disabled.$default." />"; - } -} -?> diff --git a/code/editor/EditableEmailField.php b/code/editor/EditableEmailField.php index 7c247de..cf96398 100755 --- a/code/editor/EditableEmailField.php +++ b/code/editor/EditableEmailField.php @@ -1,9 +1,10 @@ "Int", "Required" => "Boolean", "CanDelete" => "Boolean", - "CustomParameter" => "Varchar" + "CustomParameter" => "Varchar", + "OptionallyDisplay" => "Boolean" ); static $defaults = array( @@ -26,19 +28,36 @@ class EditableFormField extends DataObject { "Parent" => "SiteTree", ); + /** + * @var bool Is this field readonly to the user + */ protected $readonly; + /** + * @var FieldEditor The current editor + */ protected $editor; - - function setEditor( $editor ) { - $this->editor = $editor; - } - - function __construct( $record = null, $isSingleton = false ) { + + /** + * Construct a new EditableFormField Object. + * + * @param array|null $record This will be null for a new database record. + * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods. + */ + public function __construct($record = null, $isSingleton = false) { $this->setField('Default', -1); parent::__construct( $record, $isSingleton ); } + /** + * Set the FieldEditor object for this field. + * + * @param FieldEditor The Editor window you wish to use + */ + protected function setEditor($editor) { + $this->editor = $editor; + } + function EditSegment() { return $this->renderWith('EditableFormField'); } @@ -51,6 +70,26 @@ class EditableFormField extends DataObject { return $this->class; } + /** + * Return whether or not this field has addable options + * such as a dropdown field or radio set + * + * @return bool + */ + public function hasAddableOptions() { + return false; + } + + /** + * Return whether or not this field needs to show the extra + * options dropdown list + * + * @return bool + */ + public function showExtraOptions() { + return true; + } + function makeReadonly() { $this->readonly = true; return $this; @@ -62,15 +101,8 @@ class EditableFormField extends DataObject { } function TitleField() { - // return new TextField( "Fields[".$this->ID."][Title]", null, $this->Title ); $titleAttr = Convert::raw2att($this->Title); - $readOnlyAttr = ''; - - if( $this->readonly ) { - $readOnlyAttr = ' disabled="disabled"'; - } else { - $readOnlyAttr = ''; - } + $readOnlyAttr = ($this->readonly) ? ' disabled="disabled"' : ''; return "ID}][Title]\"$readOnlyAttr />"; } @@ -79,25 +111,23 @@ class EditableFormField extends DataObject { return "Fields[".$this->ID."]"; } - /*function getName() { - return "field" . $this->ID; - }*/ - - function populateFromPostData( $data ) { - - $this->Title = isset($data['Title']) ? $data['Title']: ""; - - if(isset($data['Default'])) { - $this->setField('Default', $data['Default']); - } - + /** + * How to save the data submitted in this field into + * the database object which this field represents. + * + * Any class's which call this should also call + * {@link parent::populateFromPostData()} to ensure + * that this method is called + * + * @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->CustomParameter = isset($data['CustomParameter']) ? $data['CustomParameter'] : null; $this->Required = !empty($data['Required']) ? 1 : 0; $this->CanDelete = (isset($data['CanDelete']) && !$data['CanDelete']) ? 0 : 1; - $this->write(); - - // The field must be written to ensure a unique ID. $this->Name = $this->class.$this->ID; $this->write(); } @@ -107,22 +137,28 @@ class EditableFormField extends DataObject { $baseName = "Fields[$this->ID]"; $extraOptions = new FieldSet(); - if( !$this->Parent()->hasMethod( 'hideExtraOption' ) ){ - $extraOptions->push( new CheckboxField($baseName . "[Required]", _t('EditableFormField.REQUIRED', 'Required?'), $this->Required) ); - }elseif( !$this->Parent()->hideExtraOption( 'Required' ) ){ - $extraOptions->push( new CheckboxField($baseName . "[Required]", _t('EditableFormField.REQUIRED', 'Required?'), $this->Required) ); + if(!$this->Parent()->hasMethod('hideExtraOption')){ + $extraOptions->push(new CheckboxField($baseName . "[Required]", _t('EditableFormField.REQUIRED', 'Required?'), $this->Required)); + } + elseif(!$this->Parent()->hideExtraOption('Required')){ + $extraOptions->push(new CheckboxField($baseName . "[Required]", _t('EditableFormField.REQUIRED', 'Required?'), $this->Required)); } - if( $this->Parent()->hasMethod( 'getExtraOptionsForField' ) ) { - $extraFields = $this->Parent()->getExtraOptionsForField( $this ); + if($this->Parent()->hasMethod('getExtraOptionsForField')) { + $extraFields = $this->Parent()->getExtraOptionsForField($this); - foreach( $extraFields as $extraField ) - $extraOptions->push( $extraField ); + foreach($extraFields as $extraField) { + $extraOptions->push($extraField); + } } - if( $this->readonly ) + if($this->readonly) { $extraOptions = $extraOptions->makeReadonly(); - + } + + // support for optionally display field + // $extraOptions->push(new CheckboxField($baseName ."[OptionallyDisplay]", _t('EditableFormField.OPTIONALLYDISPLAY', 'Optionally Display Field'), $this->OptionallyDisplay)); + return $extraOptions; } @@ -159,7 +195,6 @@ class EditableFormField extends DataObject { protected function parsePrepopulateValue( $value ) { $paramList = explode( ',', $value ); - $paramMap = array(); foreach( $paramList as $param ) { @@ -170,33 +205,20 @@ class EditableFormField extends DataObject { } else if( isset( $paramMap[$match[1]] ) ) { $paramMap[$match[1]] = array( $paramMap[$match[1]] ); $paramMap[$match[1]][] = $match[2]; - //Debug::message( $match[1] . '[]=' . $match[2] ); } else { $paramMap[$match[1]] = $match[2]; - //Debug::message( $match[1] . '=' . $match[2] ); } - } else { - //Debug::message('Invalid: ' . $param ); } } - - //Debug::show( $paramMap ); - return $paramMap; } protected function prepopulateFromMap( $paramMap ) { - //Debug::show( $paramMap ); - //Debug::show( $this->stat('db') ); - - foreach( $paramMap as $field => $fieldValue ) { - if( /*$this->hasField( $field ) &&*/ !is_array( $fieldValue ) ) { + foreach($paramMap as $field => $fieldValue) { + if(!is_array($fieldValue)) { $this->$field = $fieldValue; - // Debug::message( 'Set ' . $field . ':'. $fieldValue ); } } - - // exit(); } function Type() { diff --git a/code/editor/EditableFormHeading.php b/code/editor/EditableFormHeading.php index 7f61a53..8055d2e 100755 --- a/code/editor/EditableFormHeading.php +++ b/code/editor/EditableFormHeading.php @@ -1,15 +1,16 @@ Title); $labelField->addExtraClass('FormHeading'); return $labelField; @@ -18,5 +19,9 @@ class EditableFormHeading extends EditableFormField { function showInReports() { return false; } + + function showExtraOptions() { + return false; + } } ?> \ No newline at end of file diff --git a/code/editor/EditableLiteralField.php b/code/editor/EditableLiteralField.php index 001f4ef..ed503ae 100644 --- a/code/editor/EditableLiteralField.php +++ b/code/editor/EditableLiteralField.php @@ -1,10 +1,10 @@ ID]"; @@ -33,32 +28,13 @@ class EditableLiteralField extends EditableFormField { } function populateFromPostData($data) { - $this->Content = $data['Content']; parent::populateFromPostData($data); } - function getFormField() { - return $this->createField(); - } - - function getFilterField() { - return $this->createField(true); - } - function createField() { return new LiteralField("LiteralField[$this->ID]", "
". $this->Content."
"); } - /** - * Populates the default fields. - */ - function DefaultField() { - return ""; - } - - function EditSegment() { - return $this->renderWith( $this->class ); - } } ?> \ No newline at end of file diff --git a/code/editor/EditableMemberListField.php b/code/editor/EditableMemberListField.php index eeb6f95..653bec7 100644 --- a/code/editor/EditableMemberListField.php +++ b/code/editor/EditableMemberListField.php @@ -1,8 +1,8 @@ "EditableOption" + ); + + protected $readonly; + + /** + * Deletes all the options attached to this field before + * deleting the field. Keeps stray options from floating + * around + * + * @return void + */ + public function delete() { + $options = $this->Options(); + if($options) { + foreach($options as $option) { + $option->delete(); + } + } + parent::delete(); + } + + /** + * Duplicate a pages content. We need to make sure all + * the fields attached to that page go with it + * + * @return DataObject a Clone of this node + */ + public function duplicate() { + $clonedNode = parent::duplicate(); + + if($this->Options()) { + foreach($this->Options() as $field) { + $newField = $field->duplicate(); + $newField->ParentID = $clonedNode->ID; + $newField->write(); + } + } + return $clonedNode; + } + + /** + * On before saving this object we need to go through and keep + * an eye on all our option fields that are related to this + * field in the form + * + * @param Array Data + */ + public function populateFromPostData($data) { + parent::populateFromPostData($data); + + // get the current options + $fieldSet = $this->Options(); + + // go over all the current options and check if ID and Title still exists + foreach($fieldSet as $option) { + if(isset($data[$option->ID]) && isset($data[$option->ID]['Title']) && $data[$option->ID]['Title'] != "field-node-deleted") { + $option->populateFromPostData($data[$option->ID]); + } + else { + $option->delete(); + } + } + } + + /** + * Return whether or not this field has addable options + * such as a dropdown field or radio set + * + * @return bool + */ + public function hasAddableOptions() { + return true; + } + + /** + * Set this multipleoptionfield to readonly + */ + protected function ReadonlyOption() { + $this->readonly = true; + } + + /** + * Is this multipleoption field readonly to the user + * + * @return bool + */ + public function isReadonly() { + return $this->readonly; + } + + /** + * Return the form field for this object in the front + * end form view + * + * @return FormField + */ + public function getFormField() { + return $this->createField(); + } + + /** + * Return the form field as a field suitable for insertion + * into the filter form + * + * @return FormField + */ + public function getFilterField() { + return $this->createField(true); + } + + /** + * Return the correct form field for this object. Note this + * does a transformation between being a field on the form and + * a field in the filter search form + * + * This should be extended on your subclass + * + * @param bool - Filter Field? + * @return UserError - You should implement it on your subclass + */ + public function createField($filter = false) { + return user_error('Please implement createField() on '. $this->class, E_USER_ERROR); + } + + /** + * Checkbox to show if this option is the default option selected + * in the form + * + * @return HTML + */ + public function DefaultSelect() { + $disabled = ($this->readonly) ? " disabled=\"disabled\"" : ''; + $default = ($this->Parent()->getField('Default') == $this->ID) ? " checked=\"checked\"" : ''; + + return "ParentID}][Default]\" value=\"{$this->ID}\"".$disabled.$default." />"; + } +} +?> \ No newline at end of file diff --git a/code/editor/EditableOption.php b/code/editor/EditableOption.php new file mode 100644 index 0000000..97c227c --- /dev/null +++ b/code/editor/EditableOption.php @@ -0,0 +1,71 @@ + "Varchar", + "Title" => "Varchar", + "Default" => "Boolean", + "Sort" => "Int" + ); + + static $has_one = array( + "Parent" => "EditableMultipleOptionField", + ); + + /** + * Template for the editing view of this option field + */ + public function EditSegment() { + return $this->renderWith('EditableOption'); + } + + /** + * The Title Field for this object + * + * @return FormField + */ + public function TitleField() { + return new TextField("Fields[{$this->ParentID}][{$this->ID}][Title]", null, $this->Title ); + } + + /** + * Name of this field in the form + * + * @return String + */ + public function Name() { + return "Fields[{$this->ParentID}][{$this->ID}]"; + } + + /** + * Populate this option from the form field + * + * @param Array Data + */ + 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'] : 0; + $this->write(); + } + + /** + * Make this option readonly + */ + public function ReadonlyOption() { + $this->readonly = true; + return $this->EditSegment(); + } + +} +?> \ No newline at end of file diff --git a/code/editor/EditableRadioField.php b/code/editor/EditableRadioField.php index 820464c..bc26925 100755 --- a/code/editor/EditableRadioField.php +++ b/code/editor/EditableRadioField.php @@ -1,101 +1,16 @@ "EditableRadioOption" - ); +class EditableRadioField extends EditableMultipleOptionField { static $singular_name = 'Radio field'; + static $plural_name = 'Radio fields'; - - function delete() { - $options = $this->Options(); - - foreach( $options as $option ) - $option->delete(); - - parent::delete(); - } - - function duplicate() { - $clonedNode = parent::duplicate(); - - foreach( $this->Options() as $field ) { - $newField = $field->duplicate(); - $newField->ParentID = $clonedNode->ID; - $newField->write(); - } - - return $clonedNode; - } - - function EditSegment() { - return $this->renderWith( $this->class ); - } - - function populateFromPostData( $data ) { - parent::populateFromPostData( $data ); - - $fieldSet = $this->Options(); - $deletedOptions = explode( ',', $data['Deleted'] ); - - //Debug::show( $deletedOptions ); - - // store default, etc - foreach( $fieldSet as $option ) { - - //Debug::show( $option ); - - if( $deletedOptions && array_search( $option->ID, $deletedOptions ) !== false ) { - $option->delete(); - continue; - } - - if( $data[$option->ID] ) { - $option->setField( 'Default', $option->ID == $data['Default'] ); - $option->populateFromPostData( $data[$option->ID] ); - } - - unset( $data[$option->ID] ); - } - - // Debug::show( $data ); - - foreach( $data as $tempID => $optionData ) { - - $optionNumber = 0; - - if( !$tempID || !is_array( $optionData ) || empty( $optionData ) || !preg_match('/^_?\d+$/', $tempID ) ) - continue; - - // what will we name the new option? - $newOption = new EditableRadioOption(); - $newOption->Name = sprintf( 'option%d', $optionNumber++ ); - $newOption->ParentID = $this->ID; - $newOption->setField( 'Default', $tempID == $data['Default'] ); - $newOption->populateFromPostData( $optionData ); - - // $mail .= "NEW: " . $optionData['Title'] . "\n"; - - if( Director::is_ajax() ) { - $fieldID = $this->ID; - $fieldEditorName = $this->editor ? $this->editor->Name() : 'Fields'; - $prefix = $fieldEditorName . '[' . $fieldID . ']'; - $newID = $newOption->ID; - $newSort = $newOption->Sort; - echo "\$('". $fieldEditorName . "[$fieldID]').updateOption('$prefix','$tempID','$newID','$newSort');"; - } - - if( !$newOption->Title ) - user_error('Added blank option '.$tempID, E_USER_ERROR); - } - } function DefaultOption() { $defaultOption = 0; @@ -110,14 +25,6 @@ class EditableRadioField extends EditableFormField { return -1; } - function getFormField() { - return $this->createField(); - } - - function getFilterField() { - return $this->createField( true ); - } - function createField( $asFilter = false ) { $optionSet = $this->Options(); $options = array(); @@ -136,52 +43,5 @@ class EditableRadioField extends EditableFormField { // return radiofields return new OptionsetField($this->Name, $this->Title, $options, $defaultOption); } - - function prepopulate( $value ) { - - $options = $this->Options(); - - $paramMap = $this->parsePrepopulateValue( $value ); - - // find options and add them - $optionNumber = 0; - foreach( $paramMap['Options'] as $newOption ) { - if( preg_match( '/([^:]+)[:](.*)/', $newOption, $match ) ) { - $newOptionValue = $match[1]; - $newOptionTitle = $match[2]; - - $newOptionTitle = preg_replace('/__/', ' ', $newOptionTitle ); - - $newOption = $this->createOption( - 'option' . (string)$optionNumber, - $newOptionTitle, - 'new-' . (string)$optionNumber, - $newOption['Sort'], - $optionNumber == 1, - false - ); - - $optionNumber++; - $options->addWithoutWrite( $newOption ); - } - } - } - -protected function createOption( $name, $title, $id, $sort = 0, $isDefault = false ) { - $newOption = new EditableRadioOption(); - $newOption->Name = $name; - $newOption->Title = $title; - $newOption->ID = $id; - $newOption->Sort = $sort; - $newOption->setField('Default', $isDefault ? '1' : '0'); - - return $newOption; - } - - function TemplateOption() { - $option = new EditableRadioOption(); - $option->ParentID = $this->ID; - return $option->EditSegment(); - } - } +} ?> diff --git a/code/editor/EditableRadioOption.php b/code/editor/EditableRadioOption.php deleted file mode 100755 index 2c40464..0000000 --- a/code/editor/EditableRadioOption.php +++ /dev/null @@ -1,84 +0,0 @@ -readonly = true; - return $this->EditSegment(); - } - - function isReadonly() { - return $this->readonly; - } - - static $default_sort = "Sort"; - - // add required here? - static $db = array( - "Name" => "Varchar", - "Title" => "Varchar", - "Default" => "Boolean", - "Value" => "Varchar", - "Sort" => "Int" - ); - static $has_one = array( - "Parent" => "EditableRadioField", - ); - - static $singular_name = 'Radio option'; - static $plural_name = 'Radio options'; - - function EditSegment() { - return $this->renderWith('EditableFormFieldOption'); - } - - function TitleField() { - return new TextField( "Fields[{$this->ParentID}][{$this->ID}][Title]", null, $this->Title ); - } - - function Name() { - return "Fields[{$this->ParentID}][{$this->ID}]"; - } - - function populateFromPostData( $data ) { - $this->Title = $data['Title']; - $this->Sort = $data['Sort']; - $this->write(); - } - - function Option() { - // return new radio field - /*$title = Convert::raw2att( $this->Title ); - - $default = ""; - - if( $this->getField('Default') ) - $default = '+'; - else - $default = '-'; - - //Debug::show($this); - return '';*/ - - return $this->EditSegment(); - } - - function DefaultSelect() { - $disabled = ($this->readonly) ? " disabled=\"disabled\"" : ''; - - if($this->Parent()->getField('Default') == $this->ID) { - $default = " checked=\"checked\""; - } else { - $default = ''; - } - - return "ParentID}][Default]\" value=\"{$this->ID}\"".$disabled.$default." />"; - } -} -?> \ No newline at end of file diff --git a/code/editor/EditableTextField.php b/code/editor/EditableTextField.php index c3f6ff2..40bcfa6 100755 --- a/code/editor/EditableTextField.php +++ b/code/editor/EditableTextField.php @@ -1,9 +1,10 @@ name; @@ -75,10 +75,16 @@ class FieldEditor extends FormField { return false; } - + /** + * Handles saving the page. Needs to keep an eye on fields + * and options which have been removed / added + * + * @param DataObject Record to Save it In + */ function saveInto(DataObject $record) { $name = $this->name; + $fieldSet = $record->$name(); // @todo shouldn't we deal with customFormActions on that object? @@ -90,104 +96,109 @@ class FieldEditor extends FormField { // store the field IDs and delete the missing fields // alternatively, we could delete all the fields and re add them $missingFields = array(); - - foreach( $fieldSet as $existingField ){ + + foreach($fieldSet as $existingField){ $missingFields[$existingField->ID] = $existingField; } - - // write the new fields to the database + if($_REQUEST[$name]){ foreach( array_keys( $_REQUEST[$name] ) as $newEditableID ) { $newEditableData = $_REQUEST[$name][$newEditableID]; + + $editable = DataObject::get_one('EditableFormField', "(`ParentID`='{$record->ID}' OR `ParentID`=0) AND `EditableFormField`.`ID`='$newEditableID'" ); + + // check if we are updating an existing field. One odd thing is a 'deleted' field + // still exists in the post data (ID) so we need to check for type. + if($editable && isset($missingFields[$editable->ID]) && isset($newEditableData['Type'])) { + // check if it has been labelled as deleted + if(isset($newEditableData['Title']) && $newEditableData['Title'] != 'field-node-deleted') { + unset($missingFields[$editable->ID]); + } + } - // `ParentID`=0 is for the new page - $editable = DataObject::get_one( 'EditableFormField', "(`ParentID`='{$record->ID}' OR `ParentID`=0) AND `EditableFormField`.`ID`='$newEditableID'" ); - - // check if we are updating an existing field - if( $editable && isset($missingFields[$editable->ID])) - unset( $missingFields[$editable->ID] ); - - // create a new object - // this should now be obsolete - if(!$editable && !empty($newEditableData['Type']) && class_exists($newEditableData['Type'])) { - $editable = new $newEditableData['Type'](); - $editable->ID = 0; - $editable->ParentID = $record->ID; - - if(!is_subclass_of($editable, 'EditableFormField')) { - $editable = null; - } - } - - if($editable) { - if($editable->ParentID == 0) { - $editable->ParentID = $record->ID; - } - $editable->populateFromPostData($newEditableData); - //$editable->write(); - } + if($editable) { + if($editable->ParentID == 0) { + $editable->ParentID = $record->ID; + } + $editable->populateFromPostData($newEditableData); + } } } - + // remove the fields not saved foreach($missingFields as $removedField) { if(is_numeric($removedField->ID)) $removedField->delete(); } - + if($record->hasMethod('customFormSave')) { $record->customFormSave( $_REQUEST[$name], $record ); } - //$record->writeWithoutVersion(); if($record->hasMethod( 'processNewFormFields')) { $record->processNewFormFields(); } } - - function addfield() { + + /** + * Add a field to the field editor. Called via a ajax get request + * from the userdefinedform javascript + * + * @return bool|html + */ + public function addfield() { // get the last field in this form editor $parentID = $this->form->getRecord()->ID; - $lastField = DataObject::get('EditableFormField', "`ParentID`='$parentID'", "`Sort` DESC", null, 1 ); - $nextSort = 1; - - // the new sort value is the value of the last sort + 1 if a field exists - if( $lastField ) - $nextSort += $lastField->Sort; - - $className = "Editable" . ucfirst($_REQUEST['Type']); - $name = $this->name; - if(is_subclass_of($className, "EditableFormField")) { - $e = new $className(); - // $fields = $this->form->getRecord()->$name()->Count(); - // $e->Name = $this->name . "[NewFields][]"; - // Debug::show($fields); - - /*if( $this->form->getRecord()->hasMethod('addField') ) - $this->form->getRecord()->addField( $e ); - else*/ + if($parentID) { + $parentID = Convert::raw2sql($parentID); // who knows what could happen + $highestSort = DB::query("SELECT MAX(Sort) FROM EditableFormField WHERE ParentID = '$parentID'"); + $sort = $highestSort->value() + 1; + + $className = "Editable" . ucfirst($_REQUEST['Type']); + $name = $this->name; + if(is_subclass_of($className, "EditableFormField")) { + $e = new $className(); + $e->write(); $e->ParentID = $this->form->getRecord()->ID; - - //Debug::show($e); - $e->write(); - //$e->ID = "new-" . ( $_REQUEST['NewID'] + 1 ); - $e->Name = $e->class . $e->ID; - $e->write(); - - return $e->EditSegment(); - } else { - user_error("FieldEditor::addfield: Tried to create a field of class '$className'", E_USER_ERROR); + $e->Name = $e->class . $e->ID; + $e->write(); + return $e->EditSegment(); + } } + return false; } - function adddropdownfield() { - return $this->addNewField( new EditableDropdown() ); + /** + * Return the html for a field option such as a + * dropdown field or a radio check box field + * + * @return bool|html + */ + public function addoptionfield() { + // passed via the ajax + $parent = (isset($_REQUEST['Parent'])) ? $_REQUEST['Parent'] : false; + $text = (isset($_REQUEST['Text'])) ? $_REQUEST['Text'] : ""; + + // work out the sort by getting the sort of the last field in the form +1 + if($parent) { + $sql_parent = Convert::raw2sql($parent); + $highestSort = DB::query("SELECT MAX(Sort) FROM EditableOption WHERE ParentID = '$sql_parent'"); + $sort = $highestSort->value() + 1; + + if($parent) { + $object = new EditableOption(); + $object->write(); + $object->ParentID = $parent; + $object->Sort = $sort; + $object->Name = 'option' . $object->ID; + $object->Title = $text; + $object->write(); + return $object->EditSegment(); + } + } + return false; } - - function addcheckboxfield() { - return $this->addNewField( new EditableCheckbox() ); - } - + protected $haveFormOptions = true; function setHaveFormOptions($bool){ diff --git a/css/FieldEditor.css b/css/FieldEditor.css index 131f980..bf1a363 100755 --- a/css/FieldEditor.css +++ b/css/FieldEditor.css @@ -73,7 +73,7 @@ div.FieldEditor div.MenuHolder { border: 0; } -div.FieldEditor ul li { +div.FieldEditor .MenuHolder ul li { display: inline; } @@ -121,12 +121,10 @@ div.EditableFormField.mouseOver { margin-left: 0px; } - div.EditableFormField div.ExtraOptions { + div.EditableFormField div.extraOptions { display: none; margin: 3px 0px 3px 57px; background-color: #EEEEEE; - /* IE has background issues without this */ - /*position: relative;*/ padding: 3px; } @@ -151,10 +149,7 @@ div.EditableDateField div.FieldDefault input { ********************************************************************/ #right #Form_EditForm div.EditableMultiOptionFormField div.FieldDefault ul.EditableDropdownOptions { - border: solid 1px #7F9DB9; - /* IE */ margin: 0px; - /* display: none; */ display: block; position: relative; } diff --git a/images/fe_icons/editablecheckbox.png b/images/editablecheckbox.png similarity index 100% rename from images/fe_icons/editablecheckbox.png rename to images/editablecheckbox.png diff --git a/images/fe_icons/checkboxes.png b/images/editablecheckboxgroupfield.png similarity index 100% rename from images/fe_icons/checkboxes.png rename to images/editablecheckboxgroupfield.png diff --git a/images/fe_icons/editabledatefield.png b/images/editabledatefield.png similarity index 100% rename from images/fe_icons/editabledatefield.png rename to images/editabledatefield.png diff --git a/images/fe_icons/dropdown.png b/images/editabledropdown.png similarity index 100% rename from images/fe_icons/dropdown.png rename to images/editabledropdown.png diff --git a/images/fe_icons/editableemailfield.png b/images/editableemailfield.png similarity index 100% rename from images/fe_icons/editableemailfield.png rename to images/editableemailfield.png diff --git a/images/fe_icons/editablefilefield.png b/images/editablefilefield.png similarity index 100% rename from images/fe_icons/editablefilefield.png rename to images/editablefilefield.png diff --git a/images/fe_icons/editableformheading.png b/images/editableformheading.png similarity index 100% rename from images/fe_icons/editableformheading.png rename to images/editableformheading.png diff --git a/images/editableliteralfield.png b/images/editableliteralfield.png new file mode 100644 index 0000000000000000000000000000000000000000..9c30878bdc2b709a94ec4113ebc8e46418d405c6 GIT binary patch literal 731 zcmV<10wn#3P)m>RR~z^t|sEmw~0- z>AKq;F zQAg>_I-g1f;$mz7aLIpyzt@K zrX0nS^Fza_@jjooUzi^RSP6aQlDkXgc}R2M-7@vOe&zl+J@VGuuN0(hphA2q^5^+C zbMHqQ?jN0sf&%`Do-V2R?!^*RgLYNpaFX&o`RJS`3w`cwIbj1U21y`~*8U-{mCymL zQppjLHrhFj{hpZ`1Fr;v)yT<}lOllLWbfSS0@#55!~>l+mAH`Dl@5K{MpbBaVb z2A@{I+x2a#*9Xz%jKf$6NyBrR6^5P ztyZVgsrswcYCIl?zf!44l7vy7m(S;8v6#hTL0q@nO?jD2265rRGLDx@rH~4u!!P6& z3I${-;9(4tkPdj92ymhZyrh}f-sV{;ef1CYLq|Y?(ub@NsXbyZ<<6# za3OV-!)A~?Lu?(x)5d9!!+D;6d!|l;pK(ukC{1=Ioy%-RZXb`L!(xp&V2d}2pTk~= zHHo!bcb3C?m&0+B!)uVkf2vVsjl*}MN_UoHMQr9IDuN~c|9q%Vv&_cj@A1Uq z|74Fk+3f${@BdDBCv%=hc%)2gmOxvEGkciB!p`Bx+y4+NXX>> zOm!uJtyGA#S*^mVZIQ!=vEhWUR*JIWji$?`zu}CyT~m9shMmKZu$+sxT#vNjr@-N; zzp8VT!;GhY*z5nCyWzLg!+j-kHcT7gH}>G7__;m6V8?)LvGc1_(BXoj zf56S*%i{5UsZgD~;h(+Xn!4fF=<#oo!-cTnz})epzTt(kS8JX)!vFvRO-V#SRCwBA zFee5u41_8R`~aqEMNv`FpG8ZS99hH7J@eX@pPRn_IPq`US`Lo=r!OvrtIEmGFGvgx z^7Hi$2#Ipa?Vjdg=kDU{u#t(OulNy?DilRt5Jh=cfQnk5AygqN@`Nfn9<9H#xb^-M zxGF7#A|IHdnnul=`ls%FWJjpNP?Q;ITEBQ=zuv3_gsQ_3MgB;NKK!qfoG__BN$fUU zl{iRI9I_&1m3d92ytO5|(GL)+e7&<#6dBCt+1{3{c-4$^-xs(l4HQKVHPZE(+Jf&4 zSd(^TSWZQ#LQ(X&dEPgE#%q57D5#L1uNR4tKBiXqNh1&K^ahy?I*aZ zr$9xwb{~yil@jid$HoZsTrI2KWuPJ}TgNkSRlg;+v9V6>NPZmd5FDup^qirb6knM= zNRhb>T$Q>6t87e6Ow}ES;D)&q+ma`XzCY^}bc7yx^Nlc8u_I*0%O002ovPDHLkV1g%cD`o%y diff --git a/images/fe_icons/date-time.png b/images/fe_icons/date-time.png deleted file mode 100755 index d3ddaa44d7b0d944b9fdf3a1886e38d4ea5dd85f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1606 zcmV-M2D$l(P)-&k^!w4-*2Koc?eOVRcrM)K?qh~L$j{eBSUF{SQq0oWnXkKBTw7LrFxA}Sf`of&o{ZeN2u@%H?Jp;-C)`EiF@N^vA(g+`95X8Zj9TUqo$o zZJoQ_oSdAOyW{x!{j994%G&I#x1m959OLZm?C$cCs(rf8jjpn{slwi)q@$9Yir(ed z#nYi`gC=3^Y-!R?c<=Op0C7+sHmv@{r>3a=+4j3hN#aE4-cxnnjRk>eW}~M z(~f9qYFc7l*5A(b`26+u_V4xkmX?;z*~F&9Xw_4J6A1gl*QTM(QA%Fe1Cua{rpyIMst))m#uZ|^ZQC_EwRF( zf}Luu#NRkfEBE;I%FD@>u5Z4=yX58Pu)>Unpm4y(&2*vDh>DAEk5tgw$Hdx}QgStU zno$4$|6h#1Mn*;3u&~$Q z&&Sy7;OFn}@9%G!$zya_Jz*V|t%Cjj{ce#)kB^W0{QCL({j|QTn5%nCSY%yjQf7%l z?CtB0x8(Tw_uc9Dfrx^do|ao?P+5bspu2SE@cDP1%8HGK$kyhav3mah|BI7}a)@Do zfq$8!khjLExW}qETo}2&!i=VUd!fu`a9&_}OOdtSXK;BSH4c@t*8cwe$<@D4QcY%t zORmM=agbH2u(qnm>$1s+p}yaSh>BZ)HQVFVxVgD@f|2U#?7F|U$ji^k%+F_kQ)_@- zp|+33(9Fx%#lgFSsvx{|ic!iFAvCi`M`1s-M_@cIfsJ?-Mm2v+6{y#uJWRSvQ zWoV|UtY>LthoEMQrDjr6QgWNfca&Y6wR4HE+~4Nez00shNJCX&SXXwLKtMpl(6`as z$kW`))ZNVc`}}v9PEc(&#m?8W#HF^yr{U<^z{9=Z;^VBt-p3OBZ2$lQ%t=H+RCwBA zs3rz5U=eHd1_E*Xs%{lHBq}Q_FEr}=hEr8zf#7>CuJaNS=aVO_If+YEfk$?vT;a24 z(s_k5w_mWvs;cpyN9>)uY=K1+CKNGB*`$V8V^ek7Besx%aYJKuOH1`0XGX=;^VXQE z#IMJ$Vvw=~vVf`@C&x3sdb$=<)#+VT6^xc$4%O8f8k3WRbH8fqOWnXw<*=!OV`FvS zM~C}+lBV%Fu|#F2geF&$ZiT|Rt-uTBe5#u%_Rra;DM&$`^QsO{0tX6+ceD#Y6&M?!KW{g31m!-CX zqzO=s>J>50IUa(ls?APD<}#a` zq*?suy;qdCU7Qpy&o7z4xIzO-)#^^5qUoifDOV-+K5fj{HalGYAX^xRyXlF*7WJ^t>l z+W%HBFHun+CZKKR=F1#qZXazf0jfgFkA`4Hn+14!*#!hR9T%uHySidg1vbdQpt!jB z(4l~>Kt=O*U{eM3T5m58J3A-)&y^3GUDXczW2)M%sj1o1(_?CC8XXLpl|_4i|xIUnk<00QL~aitt>RRIJT0IYad=9n6YCjbBd07*qoM6N<$ Ef;x43iU0rr diff --git a/images/fe_icons/radio.png b/images/fe_icons/editableradiofield.png similarity index 100% rename from images/fe_icons/radio.png rename to images/fe_icons/editableradiofield.png diff --git a/images/fe_icons/file-upload.png b/images/fe_icons/file-upload.png deleted file mode 100755 index 4f16b13676f0af66f15dc1cbf3f0b96b69c6ffc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1730 zcmV;z20i(SP)WIYL^|xXerMuiKpqD1yg~Bje67sw@U%Y0 z)8%Mgm)ph3bT$e|hKY|hENYF7dc@^6iq=xp$XG z6Vm1R+w1(Tv$LyfSi92gwbJsk&h7U4{$PZJ#J|~zLQ1p4+`G%$iF1XTSU8r;$w*{q z%&oGb#q0S0|ICal^x0FEQ&fXwdBvlsXl|p(rDx~Ea>AUV``ePVgNR+3oVlEbc(Syv ze1pl<-ob7iY-FHyFgB`oez}g6+_Fkkk(5~(9s1RZ^0aFF+K!uCWYoF6ZK$e@T34;X z+wx4gT~p;_3XR##h|mS}e5$&;9Bcdv(S^Uj8!Z+l~K zthk4Zx{Hodb#|O-OVz-Bta5jr!smdFe(~_~)Tf8$?ewpCe)RYy(f|MhNJ&INRCwBA zSVjzBpt`DfS!A%17rQFaSJjIA5tbXIx%lQVvWQ|gt6X-QA`}0Fz7AyeI?*H6=nEP*tmdMlnUC zOaU6TZcW=fU1Yn;mO)jOE4PD<0=k`XM%aR)BG>7a>%AR{#bB z7cfMPc-oXI&bHdI=g)Pm51rYcT7ys(-+OEdBt&`I-X&F?O?nMh)Ld}Xq+}XY)z0#j zzF?!4tl{Cg<5*SI-o9gQBT&(-LkCR^RAFX`Dx~xQje54mnkUZDu~n(PDjQ_dEa!(} zCI(kvA+g4Ht)wI{L<@I+a107+wEXjM$#|7BG63@L^FzX>uk=Xnb`Z9=+SnUB!4KoUP zcw9aPrRAzyc@-Rb=yy;Is49FmTvd6Kq@co@+69JNrw2%htKYbx=idVcPx8W<;i^Ox zBw37}&$}fR7jmW)hjA8GRz4NpsKXvXIRV#+tPAbyX?=dOedfso2ira zf@Nku*p#3#F##T4E1Rr6TXf5`6HUdPM2e#uraDaa$;^7d3{<402@9_oqPD{KZ?WIBKp0gYk+s&dn-)6x_W&_aa7 z=Raj--8NRyA|WAgvle^n)t%8gEr3v!vrN0PRQ%`UuV0)>-Tr(3EGn8bDL8n)S32wI z)37uFOsmThD@%(?y}dIsGCqC!l$G`V?c4P9^jbq!GnlGnAXRd5ot@m=+%YjRH6VGkn+6Wc*~||T5;TEMKW&C=76(4ClZf&Qlw_z{76Jqq Y0N9It0`$8JIRF3v07*qoM6N<$f<2y;w*UYD diff --git a/images/fe_icons/heading.png b/images/fe_icons/heading.png deleted file mode 100755 index 3d957238220ed7518821468205eb56d70e371bda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3601 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 X%hix-fH8oV00000NkvXXu0mjfgrCk? diff --git a/images/fe_icons/text-email.png b/images/fe_icons/text-email.png deleted file mode 100755 index 7697d66171ffab328eed73d9a289bfd4584b9a1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1532 zcmV}<5OdV`Ymyi@kgVOdvKwqhHh*6MIJ3`->mgN2Km z8V<#EB};6Uk+!#Ub9M6f{Oj%UdwYKKvP#cVJ8y4t7a=eC`~7aC$77bjEE^B{`T5xox`O)Gp#Hg$9^rHzUA_;Nb|N%8)Rf@X=w@t0bycgQF5Cy zbb*5)zFT5dZ)GL=FwcY!J+I5I`OUqok!DG*h;2J6Vgk zbgavXiHxc5@9>{GmX?|2<>j!kvN3ajy}rNks6qYy|B65i*x1?r{{O#vLw8<`M@USP+1WyOgp8`JIeLgtezAZg9PjY)=Ej<@VpDEz zZ>8Dnqv-4U{Qms$#e6(U>CC3VXb@A0ttc`~)YaIOP$Ft$ZkD^|=D>0f3<`|N+KkiF z-=2x~rHuEhlfiBwpu*_-=9qQ7yyd%JVvobKTo#p?jGff#wryTdmzT7)wjM4-OM0*K z(Po^Vr1Q8>XPUr_kD1S#a-gHBsj97ZcX#EzW%l{~mYJTPlxxb5e(UG#+KYLrE+KZP z&}5jtX_K~Kf~S~@jAUkUjjz~{vfKNxn6tRNm&f9tz~;JdGx_0x`>>byv6@_@q=bHc zmV0O?aBzf&kc5eqh>DTFz{GHFYx2us^3G$7Ye<}YR?M|+{P4ftwus-mnAV|8*QH%T zii-QTp!2awKsq*GDKc9yKJWGW;NsiYJrh{(Tx`p=&0M@L7mfvDOa3j_f`;O6F5 zP~Zgy1p%$i|84fgA7Pnn08u6HXowC(MMYcME0sd`3SDP`s< zk3-L~3B5vAWg_F^;*teXSSF|8dBIxg?C<$LVbbwaAgVS3RprZ+7M7Z%%77FV0~P62 z=*~Sm&nJv6*d`I8>VRW{s!N`Xq-0}iZazqnI8f2n2Ho8tMbbi0RSJ#?si~;Y)04rL@eOq$V<*PbQtePj~)1ay@C6vmT@VK}%%1qq>QgoBsOkG(_ zM`x!PClg;LR28#-LPAzno@#>XOTqQ*>83Z_&D5VnDsS5YRAko!SM?|X6coVl>OK*a zZp*C#RK#VGe9MXRnB78zS*svHFX8zeNl_BRm17?kM!;1moQHSQchc1c0QcRFbRhuh${Yj z@A?;MZ)d=z2&`(>)7N*k&nz(wOu<*0C~muc=K*i6fHS_*#F@v**qC3DK$)Y+V;tv9 iuw;sxMc1+rAiw~iu|U4te&S&g!?4;m@HawhPgJH~n{{`T5xox`O)Gp#Hg z$9^rHzUA_;Nb|N%8)Rf@X=zb%n=*8P_Q_spimwn55a;ajFL8cdex>VtW4dV|^}$y* zdx11|g7EhHu2mA}=ZaZ0vxOA+`@Si%V@9*#L?@&-s zFfcIu{r>&_|Nj2}-{0TQ&(Eq*4>5Cqia-qUs6qGo{q(+6#l^+HdP87fV6!wOe}93U zprw>W4X>}S@AdmgX_KYd?D^q=_p6goezAukD2M=#Lt^@@~=o*T3U^- z*!=Ou@~uVk%VAGXP+KrQLU)9cwB41r-@m}b=D>31#+rOQN{q?cjMLMWyXLdCw(`zn z!^h0?(Ps9gjKOXppu*_0TozA=iA#E~cBs&pii~HPz)o+N`>>bj%%-@yy_nU}prfgfvfE8gPid33T%@F*lxxb5 ze%gz9C^AexKR~K3A*1N)WSG8Sf~Rn9Yi5V6Tvk%LZ!-rC6o4cg5eoNicgo9Ksq*GDKhi1Nx^6k`?sJ~g|+*)pZ)dJ%FNAjr_7tY zb%9a7jc#RCwBA zh#&?qP*;_m-H8)wYRA4gIkous1PA}Lw%)QuSh%iE>(vCUkdTl|5LFw0hXH}RySt5z zO+kSp7!-v4p7_V)aQI@zui6k*GL|~%Ktx2O`Amhp?*W11j8IiZmSDTnK{y@E%vmew zWn3Zu*7pjtz#UXo<*X14R3t6vaLrhL>-$D$KZ)>z5LKJOs?s%c!8jr!8>on-Qe*wr z`ObdK-X@U{RYxr&a^vGO?ZLPbs7MT`=trr>evl#w0jMfjpjnBD_N-u>msKpre*Ny0 z(%Ds3>p+U8L*2yyvav=If9_sBO>hcfH*+V!z;;@QxT|$H#X+J6~`{Kg$T1=L_`2x zmBlJpi=-$z>ejB$3j^V*WcNmZ!%_^S$ktU~SsbirQ};#xz*+a;s@T{rul)Ca=9e8x z28tyxMXP5VNdp0xs%5eeut&+jH3+6?RnxmQMK}~eRpsz4Fz>~!2&zgm-(`^}ZbeX4{AG_i zgm5c@s;b_0u8i9=KN^Q3h^n|#hKAFgOwE6TLlHz3-@^|*%hi`g;Zg)vb@pZZdG&@? zJ`t Q3jhEB07*qoM6N<$g1YMa7XSbN diff --git a/images/fe_icons/text-password.png b/images/fe_icons/text-password.png deleted file mode 100755 index 36d69f2390ae331b8660718eaac22886fd039338..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1522 zcmV>h!!*a5fA}B?*{{jGGz`zQ4c4 zbtOw|mXWr%b8~f{pP%!xO3zX|A|M|ZAuj*`0B)nlW0t@&91HSlT%oMgo|T@s`})Oa%^jZgoH?4gC;v!jk2$9^rHzUBJ-{_?O$^R`YKWMpY+X;E^UGIW9V$zExSuPVtW4dV|^}$y*dx11|g7EhHu2mA}=epOkAqKR|YO zck<3-LW+u0betY8L`Z3qmABuNP$KiuW{k<&jMLL%kHeLjjF!9R#K_I-=j{8im&~>z~=I=Na)O_PnVao zToy}uuTXxm*QH%&n!x+FptH5MFE22BJWAS&d4MDwYg=)-zQYF%6l!B`jH;}lqp9fV z?D^q=oP1WwkABaaawsxPKR`gE=~*}n_pzG4z{G@pewKS^*xKDEaBzf&kc5eqh>DSLZfkCCZ}Q7wjB7~y zu$U1G2i~@b)}c)N@V|L^ds{F*Ksq*GDKhi1Nx^6k{PD$Ag|+?l)N-fHo4n)i_4}CB z(YkLlUx24ue4?qUtxj*4@~uVtx1WV2BxGiBfyc*^wB6>wayI~$_W%F_cu7P-RCwBA zh$RLvP*;_+^O-a1>ZiZDxqS-=h=}NOaQN{?e$8~3l3Y$>&0 z0aCOL>MjO5vE*cF>Ad7**W%=(($f0P9-Uf&rE0hBmrDq!et@cqvda+U0IDh$jLi_d zE6o(@F`4t=^OoCp_3YbJFUq7qRo#lsl@v=Z%+83lzM01n>e0h#sH`BWr&lY=K9M^O zs*1rYRxlUnM-EqOmYHH%1`nJJm0yP|bng>o|7Ud>uBsR0Y%x$+`s~lLFbWSAPDm5N<_KRW)nomUH1)Arg31Ufo~GN(nM19-khggHGE9?N)sj(dr3)NIRa&loQkAA6Ty-xFORNeAwYlu Y0QOMj&mt2q&Hw-a07*qoM6N<$f^3BI4*&oF diff --git a/images/fe_icons/text.png b/images/fe_icons/text.png deleted file mode 100755 index cb7951b3d94b751a8e4dbdc4f0763901c5f13164..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1485 zcmV;;1v2`HP)mn;H(y&d&At{l#@9`TPA#Y?hI>w{vrK^Ri0M zQacwRFK(m9W0t@y8xLZZz4C-?n}b||gNyaWTBT?;@uxwPQ&?k!s`})Oa%^jpmYsuy zgh*Y3COcV;va$~vDJ3H!zH%n%>Fn^JJH~n{=B7UW_S$Nl!=*hltt=hKel4B8<@)^o z@~}wrwoV&lWNB$>3IzdCa+@-Af%eH>@9*zvim&JF@-A?GU4EtOd}F$4AoamlHh6?I zc7pKs`>s_I=jiO&Uq)Gaq5Hn4{G{{H{{{{N~_5B&Z9 zF>`>5Kn(GyLEmRizj{M{e}VV<{r36&^uAOuFff!w4X>}SFmiwD>g>hE#j`XeouH** zl)Pe(!?Ro#PnVa>wQaU-Ub=5HW{0f5z{HQ%*6HEILU)9t=<8{dw*L9#*QH(j@W1k{ zMe@#LLW+t|P*6x|lU$^vkh0rgle>(`+O)N{_N9#XtCOYK?Ca<3!EPa-!szCC1}daryuN?cY_m6?onyu4?cz}jh3d&0tx zkB@eDcbJNdprffddWejwte=!?%8!2U_50e3d8#fU^U-Exn7&|wr(b}l{PD$VV{VPF z*pIQ=Kw*rWd{&po;-A3g-@BOk;eq$Dn)|SqgnoYIy=8zT9G1K0Cvb3thmeGcm57Rw zjE|XcZfkCCZ}Q7wjB7|#l%w9Zh}NM@=D>24P$GGGd;7Ma&zo}du}MHWHeV?+!DtXw zg|+?l)N-fHo4n&>W^tI+(chklT3T8M4HORy3R8)#9xg;%e4;2aOsT4^PH&h~be#LJ znESV%g(W14IWd99$Ci6&hRw~AwB41r-{resSdyZflL%HHskRl;Ys48(3RT=rLWj`)Al~1X(s0S%p4s}-* zvMP|G1m`WvT$NJiEEWoJ$~}Rq3PDl@RHT*Qyp#FR?ThCwC|P`yJ1i0pRdp7w%A~*@ zsHlfoTUJs)N$I};<8QVksH#c-psG^AiZrj-Xv^LUkX*k}fbo~{beO8DUZA3&q7slI z&jcf8X`mt|-RP?pj1!G#!Oaq{4G-svjkV?F-iD+oD)Rh+r?dRwszfJ1!xE&(#zk9J z5Ugm!{v&?=XBNO!F)*xJ`~7Eg^K%&;=|Y&Im6O|&K>((zS`-4>WprEuV2buFd6WnS z%b==+q2QKI;hYqxA`W#pc!ivzEwgw6%wURQ($cV|d!QmSLAW9uxdW(3aB)gD4nLw zAgb7}Ki)fA;Z!6pMPOC0@3(X*9Q&i`5reNZ5nF$$?gmRShb6w!#Bzm&h6cMBfig$z nrACk?!ICNHHC@X>fB*vkh1u54ih~k900000NkvXXu0mjfNiOuf diff --git a/javascript/FieldEditor.js b/javascript/FieldEditor.js index 3dbf571..e69de29 100755 --- a/javascript/FieldEditor.js +++ b/javascript/FieldEditor.js @@ -1,555 +0,0 @@ -FieldEditor = Class.create(); -FieldEditor.applyTo('div.FieldEditor'); -FieldEditor.prototype = { - initialize: function() { - FieldEditorField.applyToChildren(this, 'div.EditableFormField'); - FieldEditorHeadingField.applyToChildren(this, 'div.EditableFormHeading'); - FieldEditorRadioField.applyToChildren(this, 'div.EditableRadioField'); - FieldEditorCheckboxGroupField.applyToChildren(this, 'div.EditableCheckboxGroupField'); - FieldEditorDropdown.applyToChildren(this, 'div.EditableDropdown'); - FieldEditorEmailField.applyToChildren(this, 'div.EditableEmailField'); - FieldEditorTextField.applyToChildren(this, 'div.EditableTextField'); - - if( !Element.hasClassName( this, 'readonly' ) ) { - Sortable.create('Fields_fields', {tag: 'div', handle:'handle'}); - $('Form_EditForm').observeMethod('BeforeSave', this.beforeSave.bind(this)); - } - - }, - sortFields: function() { - var fieldEditor = $('Fields_fields'); - - if(fieldEditor) { - - var i, j, div, field, editables = fieldEditor.childNodes; - - for( i = 0; div = editables[i]; i++ ) { - if(div.getElementsByTagName) { - var fields = div.getElementsByTagName('input'); - /*fields[fields.length - 1].value = i;*/ - for( j = 0; field = fields.item(j); j++ ) { - if( field.name == div.id + '[Sort]' ) { - field.value = i; - } - } - } - } - } - }, - beforeSave: function() { - var fieldEditor = $('Fields_fields'); - - if(fieldEditor) { - this.sortFields(); - - var children = $('Fields_fields').childNodes; - - for( var i = 0; i < children.length; ++i ) { - var child = children[i]; - - if( child.beforeSave ) - child.beforeSave(); - } - } - }, - deleteOption: function( optionToRemove ) { - var fields = document.getElementById('Fields_fields'); - fields.removeChild(optionToRemove); - } -} - -FieldEditorField = Class.create(); - -FieldEditorField.prototype = { - initialize: function() { - var fieldInfoDiv = this.findDescendant( 'div', 'FieldInfo' ); - - this.titleField = this.findDescendant( 'input', 'text'); - - this.titleField.onchange = this.changeTitle.bind(this); - this.titleField.onblur = this.changeTitle.bind(this); - this.titleField.onfocus = this.focusTitle.bind(this); - - this.titleField.onchange(); - - var links = fieldInfoDiv.getElementsByTagName('a'); - this.toggler = this.findDescendant( 'a', 'toggler' ); - this.fieldInfo = this.getElementsByTagName('div')[0]; - - - this.toggler.onclick = this.toggle.bind(this); - this.extraOptions = this.getExtraOptions(); - this.visible = false; - this.deleteButton = this.findDescendant('a', 'delete'); - - //this.style.height = "auto"; - - if( this.deleteButton ) - this.deleteButton.onclick = this.confirmDelete.bind(this); - }, - toggle: function() { - // this.parentNode.autoSize(); - - if( this.visible ) - this.hide(); - else - this.show(); - - this.fieldInfo.style.display = 'block'; - - return false; - }, - show: function() { - /*this.style.height = ""; - this.style.overflow = "";*/ - - if( this.selectedOption ) - this.selectedOption.checked = true; - - this.visible = true; - // var extraOptions = this.getExtraOptions(); - // if( this.extraOptions ) - this.extraOptions.style.display = 'block'; - }, - hide: function() { - - this.visible = false; - // var extraOptions = this.getExtraOptions(); - //if( this.extraOptions ) - this.extraOptions.style.display = 'none'; - }, - getExtraOptions: function() { - var extraOptions = this.findDescendant('div', 'ExtraOptions'); - - if( extraOptions.parentNode != this ) - alert("Found extra options but not this parent (" + this.id + ")"); - - return extraOptions; - }, - confirmDelete: function() { - if( confirm( 'Are you sure you want to delete this field from the form?' ) ) - this.parentNode.parentNode.parentNode.deleteOption( this ); - - return false; - }, - findDescendant: function( tag, clsName, element ) { - - if( !element ) - element = this; - - var descendants = element.getElementsByTagName(tag); - - for( var i = 0; i < descendants.length; i++ ) { - var el = descendants[i]; - // alert(el.tagName + ' ' + el.className); - - if( tag.toUpperCase() == el.tagName && el.className.indexOf( clsName ) != -1 ) - return el; - } - - return null; - }, - focusTitle: function() { - if( this.titleField && this.titleField.value == this.titleField.title ) - this.titleField.value = ''; - }, - changeTitle: function() { - if( this.titleField && this.titleField.value == '' ) - this.titleField.value = this.titleField.title; - } -} - -FieldEditorHeadingField = Class.extend('FieldEditorField'); - -FieldEditorHeadingField.prototype = { - initialize: function() { - this.FieldEditorField.initialize(); - } -} - -FieldEditorEmailField = Class.extend('FieldEditorField'); - - -FieldEditorEmailField.prototype = { - initialize: function() { - this.extraOptions = this.getExtraOptions(); - this.defaultText = this.getDefaultText(); - - this.FieldEditorField.initialize(); - }, - getDefaultText: function() { - var defaultField = this.getDefaultField(); - if(defaultField) { - var j, nestedChild, nestedChildren = defaultField.childNodes; - for( j=0; nestedChild = nestedChildren[j]; j++) { - if (nestedChild.className == 'defaultText' ) - { - return nestedChild; - } - } - } - }, - getDefaultField: function() { - - var i, child, children = this.getElementsByTagName('div'); - for( i = 0; child = children[i]; i++){ - if(child.className == 'FieldDefault'){ - return child; - } - } - } -} - - -FieldEditorTextField = Class.extend('FieldEditorField'); -FieldEditorTextField.prototype = { - initialize: function() { - this.FieldEditorField.initialize(); - this.defaultText = this.getDefaultText(); - this.numRows = this.extraOptions.getElementsByTagName('input')[3]; - if(this.numRows) { - this.numRows.onchange = this.changedRows.bind(this); - this.oldNumRows = eval(this.numRows.value); - } - - }, - changedRows: function() { - var newNumRows = eval(this.numRows.value); - - // TODO Show that the field is actually longer than 5 rows - if( newNumRows > 5 ) - newNumRows == 5; - - if( this.oldNumRows == newNumRows ) - return; - - if( newNumRows < 1 ) - newNumRows = 1; - - // resize/convert the textarea - var newType = ''; - - if( newNumRows == 1 ) - newType = 'input'; - else - newType = 'textarea' - - var newDefaultText = document.createElement(newType); - newDefaultText.className = this.defaultText.className; - newDefaultText.value = this.defaultText.value; - newDefaultText.id = this.defaultText.id; - newDefaultText.name = this.defaultText.name; - - if( newDefaultText.rows ) - newDefaultText.rows = newNumRows; - - //Does not work any more - //this.replaceChild( newDefaultText, this.defaultText ); - - //instead, using the following code - var defaultField = this.getDefaultField(); - defaultField.replaceChild(newDefaultText, this.defaultText); - - //keep other codes. - this.defaultText = newDefaultText; - this.oldNumRows = newNumRows; - }, - getDefaultText: function() { - var defaultField = this.getDefaultField(); - - if(defaultField) { - var j, nestedChild, nestedChildren = defaultField.childNodes; - for( j=0; nestedChild = nestedChildren[j]; j++) { - - if (nestedChild.className == 'defaultText' ) - { - return nestedChild; - } - } - } - }, - getDefaultField: function() { - var i, child, children = this.getElementsByTagName('div'); - for( i = 0; child = children[i]; i++){ - if(child.className == 'FieldDefault'){ - return child.getElementsByTagName('div')[0]; - } - } - } -} - -/** - * This should extend FieldEditorField - */ -FieldEditorRadioField = Class.extend('FieldEditorField'); - -FieldEditorRadioField.prototype = { - initialize: function() { - this.FieldEditorField.initialize(); - - this.hiddenFields = this.findDescendant( 'div', 'hidden' ); - - var dropdownBox = this.findDescendant( 'div', 'EditableDropdownBox' ); - - this.optionList = dropdownBox.getElementsByTagName('ul')[0]; - var options = this.optionList.getElementsByTagName('li'); - - if( options && options.length > 0 ) { - this.addOptionField = options[options.length - 1]; - - if( typeof this.addOptionField != 'undefined' && this.addOptionField.className != "AddDropdownOption" ) - this.addOptionField = null; - - // bind each option's delete link - for( var i = 0; i < options.length - 1; i++ ) { - var option = options[i]; - - var links = option.getElementsByTagName('a'); - - links[0].onclick = this.removeOption.bindAsEventListener(this); - } - } - - // Bind method to add option at the bottom of the list - if( this.addOptionField ) { - this.addOptionLink = this.addOptionField.getElementsByTagName('a')[0]; - this.addOptionTitle = this.addOptionField.getElementsByTagName('input')[0]; - this.addOptionLink.onclick = this.addOption.bind(this); - } - - if( !Element.hasClassName( $('Fields'), 'readonly' ) ) { - Sortable.create(this.optionList.id,{handle:'handle',tag:'li',only:'EditableFormFieldOption'}); - } - this.FieldEditorField.initialize(); - - // find the Delete field - var hiddenFields = this.getElementsByTagName('input'); - - for( var i = 0; i < hiddenFields.length; i++ ) { - var field = hiddenFields[i]; - if( field.name.indexOf('[Deleted\]' ) != -1 ) - this.deletedOptions = field; - } - - this.selectedOption = null; - - $('Form_EditForm').observeMethod('BeforeSave', this.beforeSave.bind(this)); - }, - firstElement: function( el ) { - - var node = el.firstChild; - - while( !node.tagName ) - node = node.nextSibling; - - return node; - }, - createOption: function( title, id, selected ) { - var templateNode = this.firstElement( this.hiddenFields ); - var newOptionNode = templateNode.cloneNode( true ); - - var newNodeChildren = newOptionNode.childNodes; - - for( var i = 0; i < newNodeChildren.length; i++ ) { - - var child = newNodeChildren[i]; - - if( !child.tagName ) - continue; - - // input elements - if( child.tagName.toLowerCase() == 'input' ) { - - if( child.className == 'text' ) { - child.name = this.id + '[' + id + '][Title]'; - child.value = title; - } else if( child.type == 'checkbox' ) - child.name = this.id + '[' + id + '][Default]'; - else if( child.type == 'radio' ) { - child.value = id; - } else if( child.type == 'hidden' ) { - child.name = this.id + '[' + id + '][Sort]'; - child.value = -1; - } - } else if ( child.tagName.toLowerCase() == 'a' ) { - child.onclick = this.removeOption.bindAsEventListener(this); - } - } - - this.optionList.insertBefore( newOptionNode, this.addOptionField ); - }, - removeOption: function( event ) { - - var target = event.srcElement; - - if( !target ) - target = event.target; - - var entry = target.parentNode.parentNode; - var id = entry.id; - - if( !id.match( '/^[0-9]+$/' ) ) { - if( this.deletedOptions.value ) - this.deletedOptions.value += ','; - - this.deletedOptions.value += id; - } - - // remove the child from the options - this.optionList.removeChild( entry ); - - // remove the child from the dropdown - /*for( var i = 0; i < this.dropdown.length; i++ ) { - if( this.dropdown.options[i].text == title ) { - this.dropdown.remove(i); - return false; - } - }*/ - - if( !Element.hasClassName( $('Fields'), 'readonly' ) ) - Sortable.create(this.optionList.id,{handle:'handle',tag:'li',only:'EditableFormFieldOption'}); - - // return false so it doesn't follow the link - return false; - }, - addOption: function() { - if( this.addOptionTitle.value.length == 0 ) - return false; - - // The IDs come from the database and are the ID of the actual record - // client-side, we will need a unique identifier that can be differentiated - // from the actual database IDs, unless we just drop all records and - // recreate them - var newID = '_' + this.optionList.childNodes.length; - - this.createOption( this.addOptionTitle.value, newID, this.optionList.childNodes.length == 0 ); - - if( !Element.hasClassName( $('Fields'), 'readonly' ) ) - Sortable.create(this.optionList.id,{handle:'handle',tag:'li',only:'EditableFormFieldOption'}); - - this.addOptionTitle.value = ''; - - return false; - }, - beforeSave: function() { - this.sortOptions(); - }, - sortOptions: function() { - var inputTags = this.optionList.getElementsByTagName('input'); - - var i,item,sort=0; - for(i=0;item=inputTags[i];i++) { - if(item.name.match(/\[Sort\]$/) ) { - item.value = sort++; - } - } - }, - selectOption: function(newOption) { - - if( this.selectedOption ) - this.selectedOption.checked = false; - - newOption.checked = true; - this.selectedOption = newOption; - }, - selectOptionEvent: function(event) { - if(event.srcElement) - this.selectOption(event.srcElement); - else - this.selectOption(event.target); - }, - updateOption: function( prefix, tempID, newID, newSort ) { - var options = this.optionList.childNodes; - - for( var i = 0; i < options.length; i++ ) { - var option = options[i]; - - var fields = option.getElementsByTagName('input'); - - for( var j = 0; j < fields.length; j++ ) { - var field = fields[j]; - - var oldPrefix = prefix + '[' + tempID + ']'; - var newPrefix = prefix + '[' + newID + ']'; - - if( field.name.indexOf( oldPrefix ) == 0 ) { - - if( field.name.match( /\[Sort\]$/ ) ) - field.value = newSort; - - // rename the field - field.name = newPrefix + field.name.substring( oldPrefix.length ); - - } else if( field.name == prefix + '[Default]' ) { - field.value = newID; - } - } - } - } -} - -FieldEditorCheckboxGroupField = Class.extend('FieldEditorRadioField'); - -FieldEditorDropdown = Class.extend('FieldEditorRadioField'); - -Behaviour.register({ - - 'div.FieldEditor ul.Menu li a': { - urlForFieldMethod: function(methodName) { - return this.ownerForm().action + '/field/Fields/' + methodName + '?NewID=' + this.numNewFields; - }, - ownerForm: function() { - var f = this.parentNode; - while(f && f.tagName.toLowerCase() != 'form') f = f.parentNode; - return f; - }, - - onclick: function() { - // get the ID of the field editor here - - if( Element.hasClassName( $('Fields'), 'readonly' ) ) - return false; - - action = this.urlForFieldMethod("addfield") + "&Type=" + this.id + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '');; - - statusMessage('Adding new field' ); - - new Ajax.Request(action, { - method: 'get', - onFailure: reportError, - onSuccess: this.appendNewField.bind(this) - }); - - return false; - }, - - appendNewField: function(response) { - this.numNewFields++; - - var el = document.createElement('div'); - el.innerHTML = response.responseText; - - var i=0; - while(!el.childNodes[i].tagName) i++; - var newField = el.childNodes[i]; - $('Fields_fields').appendChild(newField); - - // Behaviour.debug(); - if(newField) { - Behaviour.apply(newField,true); - FieldEditor.applyTo('div.FieldEditor'); - } - - // do we want to make sorting explicit? - Sortable.create('Fields_fields', {tag: 'div', handle:'handle'}); - - statusMessage('Added new field','good'); - } - } -}); - -function reportError(request){ - // More complex error for developers - statusMessage(request.responseText,'bad'); - -} diff --git a/javascript/UserForm.js b/javascript/UserForm.js index 0569fcd..c0afbea 100644 --- a/javascript/UserForm.js +++ b/javascript/UserForm.js @@ -1,5 +1,21 @@ +/** + * Javascript required to power the user defined forms. + * + * Rewritten and refactored from the prototype version FieldEditor. + * + * @todo Upgrade to jQuery 1.3 so we can use live rather + * then livequery + */ (function($) { $(document).ready(function() { + + /*--------------------- SUBMISSIONS ------------------------ */ + + /** + * Delete a given Submission from the form, or all submissions + * we let the href of the delete link to do all the work for us + */ + $("#FormSubmissions .deleteSubmission").click(function() { var deletedSubmission = $(this); $.post($(this).attr('href'), function(data) { @@ -7,5 +23,126 @@ }); return false; }); - }) -})(jQuery); \ No newline at end of file + + /*-------------------- FIELD EDITOR ----------------------- */ + + /** + * Create a new instance of a field in the current form + * area. the type information should all be on this object + */ + + $("div.FieldEditor ul.Menu li a").livequery('click',function() { + + // if this form is readonly... + if($("#Fields").hasClass('readonly')) return false; + + // Give the user some feedback + statusMessage(ss.i18n._t('UserForms.ADDINGNEWFIELD', 'Adding New Field')); + + // variables + var action = $("#Form_EditForm").attr("action") + '/field/Fields/addfield'; + var length = $(".FieldInfo").length + 1; + var securityID = ($("#SecurityID")) ? '&SecurityID='+$("#SecurityID").attr("value") : ''; + var type = $(this).attr("ID"); + + //send ajax request to the page + $.ajax({ + type: "GET", + url: action, + data: 'NewID='+ length +"&Type="+ type + securityID, + + // create a new field + success: function(msg){ + $('#Fields_fields').append(msg); + statusMessage(ss.i18n._t('UserForms.ADDEDNEWFIELD', 'Added New Field')); + }, + + // error creating new field + error: function(request, text, error) { + statusMessage(ss.i18n._t('UserForms.ERRORCREATINGFIELD', 'Error Creating Field')); + } + }); + }); + + /** + * Show the more options popdown. Or hide it if we + * currently have it open + */ + $(".EditableFormField .moreOptions").livequery('click',function() { + var parentID = $(this).parents(".EditableFormField"); + if(parentID) { + var extraOptions = parentID.children(".extraOptions"); + if(extraOptions) { + if(extraOptions.hasClass('hidden')) { + extraOptions.removeClass('hidden').show(); + } + else { + extraOptions.addClass('hidden').hide(); + } + } + } + return false; + }); + + /** + * Delete a field from the user defined form + */ + $(".EditableFormField .delete").livequery('click', function() { + $(this).parents(".EditableFormField").remove(); + }); + + /** + * Add a suboption to a radio field or to a dropdown box + * for example + */ + $(".EditableFormField .addableOption").livequery('click', function() { + + // Give the user some feedback + statusMessage(ss.i18n._t('UserForms.ADDINGNEWFIELD', 'Adding New Option')); + + // variables + var options = $(this).parent("li"); + var action = $("#Form_EditForm").attr("action") + '/field/Fields/addoptionfield'; + var parent = $(this).attr("rel"); + var text = $(this).parents("li").children(".text").val(); + + // clear input + $(this).parents("li").children(".text").val(""); + + //send ajax request to the page + $.ajax({ + type: "GET", + url: action, + data: 'Parent='+ parent +"&Text="+ text, + + // create a new field + success: function(msg){ + options.before(msg); + statusMessage(ss.i18n._t('UserForms.ADDEDNEWFIELD', 'Added New Field')); + }, + + // error creating new field + error: function(request, text, error) { + statusMessage(ss.i18n._t('UserForms.ERRORCREATINGFIELD', 'Error Creating Field')); + } + }); + return false; + }); + + /** + * Delete a suboption such as an dropdown option or a + * checkbox field + */ + $(".EditableFormField .deleteOption").livequery('click', function() { + // pass the deleted status onto the element + $(this).parents("li").children("[type=text]").attr("value", "field-node-deleted"); + $(this).parents("li").hide(); + + // Give the user some feedback + statusMessage(ss.i18n._t('UserForms.REMOVINGOPTION', 'Removed Option')); + return false; + }); + + }); +}) +(jQuery); \ No newline at end of file diff --git a/templates/EditableCheckbox.ss b/templates/EditableCheckbox.ss deleted file mode 100755 index 5ce547f..0000000 --- a/templates/EditableCheckbox.ss +++ /dev/null @@ -1,26 +0,0 @@ -
-
- <% if isReadonly %> - <% _t('LOCKED', 'This field cannot be modified') %> - <% else %> - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% end_if %> - <% _t('CHECKBOX', 'Checkbox field') %> - $TitleField - <% _t('MORE', 'More options') %> - <% _t('DELETE', 'Delete this field') %> -
-
-
- -
- <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
- - - -
\ No newline at end of file diff --git a/templates/EditableCheckboxGroupField.ss b/templates/EditableCheckboxGroupField.ss deleted file mode 100755 index 3553ad3..0000000 --- a/templates/EditableCheckboxGroupField.ss +++ /dev/null @@ -1,51 +0,0 @@ -
-
- <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% end_if %> - <% _t('CHECKBOXGROUP', 'Checkbox group') %> - $TitleField - - <% _t('MORE', 'More options') %> - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> - <% if CanDelete %> - <% _t('DELETE', 'Delete this field') %> - <% else %> - <% _t('REQUIRED', 'This field is required for this form and cannot be deleted') %> - <% end_if %> - <% end_if %> -
- -
-
-
    - <% if isReadonly %> - <% control Options %> - $ReadonlyOption - <% end_control %> - <% else %> - <% control Options %> - $Option - <% end_control %> -
  • - - <% _t('ADD', 'Add new option') %> -
  • - <% end_if %> -
-
- <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
- - - - -
diff --git a/templates/EditableCheckboxOption.ss b/templates/EditableCheckboxOption.ss deleted file mode 100755 index 70865a9..0000000 --- a/templates/EditableCheckboxOption.ss +++ /dev/null @@ -1,10 +0,0 @@ -
  • - <% _t('DRAG', 'Drag to rearrange order of options') %> - - - <% if isReadonly %> - <% _t('DELETE', 'Remove this option') %> - <% else %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% end_if %> -
  • \ No newline at end of file diff --git a/templates/EditableDateField.ss b/templates/EditableDateField.ss deleted file mode 100755 index 6343bb5..0000000 --- a/templates/EditableDateField.ss +++ /dev/null @@ -1,20 +0,0 @@ -
    -
    - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% _t('DATE', 'Date Field') %> - $TitleField - <% _t('MORE', 'More options') %> - <% _t('DELETE', 'Delete this field') %> -
    -
    -
    - $DefaultField -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - -
    diff --git a/templates/EditableDropdown.ss b/templates/EditableDropdown.ss deleted file mode 100755 index c02bd6d..0000000 --- a/templates/EditableDropdown.ss +++ /dev/null @@ -1,50 +0,0 @@ -
    -
    - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% end_if %> - <% _t('DROPDOWN', 'Dropdown box') %> - $TitleField - <% _t('MORE', 'More options') %> - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> - <% if CanDelete %> - <% _t('DELETE', 'Delete this field') %> - <% else %> - <% _t('REQUIRED', 'This field is required for this form and cannot be deleted') %> - <% end_if %> - <% end_if %> -
    - -
    -
    -
      - <% if isReadonly %> - <% control Options %> - $ReadonlyOption - <% end_control %> - <% else %> - <% control Options %> - $Option - <% end_control %> -
    • - - <% _t('ADD', 'Add new option') %> -
    • - <% end_if %> -
    -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - - -
    diff --git a/templates/EditableDropdownOption.ss b/templates/EditableDropdownOption.ss deleted file mode 100755 index 2bdf47a..0000000 --- a/templates/EditableDropdownOption.ss +++ /dev/null @@ -1,10 +0,0 @@ -
  • - <% _t('DRAG', 'Drag to rearrange order of options') %> - - - <% if isReadonly %> - <% _t('DELETE', 'Remove this option') %> - <% else %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% end_if %> -
  • \ No newline at end of file diff --git a/templates/EditableEmailField.ss b/templates/EditableEmailField.ss deleted file mode 100755 index 7b7aadd..0000000 --- a/templates/EditableEmailField.ss +++ /dev/null @@ -1,25 +0,0 @@ -
    -
    - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% _t('EMAIL', 'Email address field') %> - $TitleField - <% _t('MORE', 'More options') %> - <% if CanDelete %> - <% _t('DELETE', 'Delete this field') %> - <% else %> - <% _t('REQUIRED', 'This field is required for this form and cannot be deleted') %> - <% end_if %> -
    -
    -
    - $DefaultField -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - - -
    \ No newline at end of file diff --git a/templates/EditableFileField.ss b/templates/EditableFileField.ss deleted file mode 100755 index f8f6b31..0000000 --- a/templates/EditableFileField.ss +++ /dev/null @@ -1,20 +0,0 @@ -
    -
    - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% _t('FILE', 'File upload field') %> - $TitleField - <% _t('MORE', 'More options') %> - <% _t('DELETE', 'Delete this field') %> -
    -
    -
    - $DefaultField -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - -
    diff --git a/templates/EditableFormField.ss b/templates/EditableFormField.ss index 3d2a8bc..06194a6 100755 --- a/templates/EditableFormField.ss +++ b/templates/EditableFormField.ss @@ -1,44 +1,61 @@
    <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> + <% _t('LOCKED', 'These fields cannot be modified') %> <% else %> - <% _t('DRAG', 'Drag to rearrange order of fields') %> + <% _t('DRAG', 'Drag to rearrange order of fields') %> <% end_if %> + $ClassName + $TitleField - <% _t('MORE', 'More options') %> + + <% if showExtraOptions %> + + <% _t('MORE', 'More options') %> + + <% end_if %> + <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> + <% _t('LOCKED', 'These fields cannot be modified') %> <% else %> - <% if CanDelete %> - <% _t('DELETE', 'Delete this field') %> - <% else %> - <% _t('REQUIRED', 'This field is required for this form and cannot be deleted') %> - <% end_if %> - <% end_if %> -
    - <% if Options %> - - <% end_if %> -
    -
    - $DefaultField + <% if CanDelete %> + <% _t('DELETE', 'Delete this field') %> + <% else %> + <% _t('REQUIRED', 'This field is required for this form and cannot be deleted') %> + <% end_if %> + <% end_if %> +
    + + <% if showExtraOptions %> + - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - + <% end_if %> + + + +
    \ No newline at end of file diff --git a/templates/EditableFormFieldOption.ss b/templates/EditableFormFieldOption.ss deleted file mode 100755 index 4ec8971..0000000 --- a/templates/EditableFormFieldOption.ss +++ /dev/null @@ -1,15 +0,0 @@ -
  • - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - $DefaultSelect - - - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> - <% _t('DRAG', 'Drag to rearrange order of fields') %> - $DefaultSelect - - - <% _t('DELETE', 'Remove this option') %> - <% end_if %> -
  • \ No newline at end of file diff --git a/templates/EditableFormHeading.ss b/templates/EditableFormHeading.ss deleted file mode 100755 index 9324c39..0000000 --- a/templates/EditableFormHeading.ss +++ /dev/null @@ -1,17 +0,0 @@ -
    -
    - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% _t('HEADING', 'Heading field') %> - $TitleField - <% _t('MORE', 'More options') %> - <% _t('DELETE', 'Delete this field') %> -
    -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - -
    diff --git a/templates/EditableLiteralField.ss b/templates/EditableLiteralField.ss deleted file mode 100644 index d10f909..0000000 --- a/templates/EditableLiteralField.ss +++ /dev/null @@ -1,20 +0,0 @@ -
    -
    - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% _t('LITERALFIELD', 'Literal Field') %> - $TitleField - <% _t('MORE', 'More options') %> - <% _t('DELETE', 'Delete this field') %> -
    -
    -
    - $DefaultField -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - -
    \ No newline at end of file diff --git a/templates/EditableOption.ss b/templates/EditableOption.ss new file mode 100644 index 0000000..1cb543d --- /dev/null +++ b/templates/EditableOption.ss @@ -0,0 +1,11 @@ +
  • + <% _t('DRAG', 'Drag to rearrange order of options') %> + $DefaultSelect + + + <% if isReadonly %> + <% _t('LOCKED', 'These fields cannot be modified') %> + <% else %> + <% _t('DELETE', 'Remove this option') %> + <% end_if %> +
  • \ No newline at end of file diff --git a/templates/EditableRadioField.ss b/templates/EditableRadioField.ss deleted file mode 100755 index 452905a..0000000 --- a/templates/EditableRadioField.ss +++ /dev/null @@ -1,51 +0,0 @@ -
    -
    - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% end_if %> - <% _t('SET', 'Radio button set') %> - $TitleField - - <% _t('MORE', 'More options') %> - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> - <% if CanDelete %> - <% _t('DELETE', 'Delete this field') %> - <% else %> - <% _t('REQUIRED', 'This field is required for this form and cannot be deleted') %> - <% end_if %> - <% end_if %> -
    - -
    -
    -
      - <% if isReadonly %> - <% control Options %> - $ReadonlyOption - <% end_control %> - <% else %> - <% control Options %> - $Option - <% end_control %> -
    • - - <% _t('ADD', 'Add new option') %> -
    • - <% end_if %> -
    -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - - -
    \ No newline at end of file diff --git a/templates/EditableRadioOption.ss b/templates/EditableRadioOption.ss deleted file mode 100755 index 70865a9..0000000 --- a/templates/EditableRadioOption.ss +++ /dev/null @@ -1,10 +0,0 @@ -
  • - <% _t('DRAG', 'Drag to rearrange order of options') %> - - - <% if isReadonly %> - <% _t('DELETE', 'Remove this option') %> - <% else %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% end_if %> -
  • \ No newline at end of file diff --git a/templates/EditableTextField.ss b/templates/EditableTextField.ss deleted file mode 100755 index b9f59bd..0000000 --- a/templates/EditableTextField.ss +++ /dev/null @@ -1,20 +0,0 @@ -
    -
    - <% _t('DRAG', 'Drag to rearrange order of fields') %> - <% _t('TEXTFIELD', 'Text Field') %> - $TitleField - <% _t('MORE', 'More options') %> - <% _t('DELETE', 'Delete this field') %> -
    -
    -
    - $DefaultField -
    - <% control ExtraOptions %> - $FieldHolder - <% end_control %> -
    - - - -
    \ No newline at end of file diff --git a/tests/UserDefinedFormTest.php b/tests/UserDefinedFormTest.php new file mode 100644 index 0000000..ae92f4a --- /dev/null +++ b/tests/UserDefinedFormTest.php @@ -0,0 +1,28 @@ +Name = "$field"; + $object->Title = "$field"; + $object->write(); + + $this->assertEquals($field, $object->Name); + } + } +} +?> \ No newline at end of file