2007-07-19 12:40:28 +02:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* This formfield represents many-many joins using a tree selector shown in a dropdown styled element
|
|
|
|
* which can be added to any form usually in the CMS.
|
2008-01-09 05:18:36 +01:00
|
|
|
* @package forms
|
|
|
|
* @subpackage fields-relational
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
|
|
|
class TreeMultiselectField extends TreeDropdownField {
|
|
|
|
function __construct($name, $title, $sourceObject = "Group", $keyField = "ID", $labelField = "Title") {
|
|
|
|
parent::__construct($name, $title, $sourceObject, $keyField, $labelField);
|
|
|
|
$this->value = 'unchanged';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return this field's linked items
|
|
|
|
*/
|
|
|
|
function getItems() {
|
2010-04-13 04:09:32 +02:00
|
|
|
// If the value has been set, use that
|
|
|
|
if($this->value != 'unchanged' && is_array($this->sourceObject)) {
|
|
|
|
$items = array();
|
|
|
|
$values = is_array($this->value) ? $this->value : preg_split('/ *, */', trim($this->value));
|
|
|
|
foreach($values as $value) {
|
|
|
|
$item = new stdClass;
|
|
|
|
$item->ID = $value;
|
|
|
|
$item->Title = $this->sourceObject[$value];
|
|
|
|
$items[] = $item;
|
|
|
|
}
|
|
|
|
return $items;
|
|
|
|
|
|
|
|
// Otherwise, look data up from the linked relation
|
|
|
|
} else if($this->form) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$fieldName = $this->name;
|
|
|
|
$record = $this->form->getRecord();
|
|
|
|
if(is_object($record) && $record->hasMethod($fieldName))
|
|
|
|
return $record->$fieldName();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* We overwrite the field attribute to add our hidden fields, as this
|
|
|
|
* formfield can contain multiple values.
|
|
|
|
*/
|
|
|
|
function Field() {
|
|
|
|
$value = '';
|
|
|
|
$itemList = '';
|
2010-02-12 03:39:07 +01:00
|
|
|
|
|
|
|
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/prototype.js');
|
|
|
|
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/behaviour.js');
|
|
|
|
Requirements::css(SAPPHIRE_DIR . '/css/TreeDropdownField.css');
|
|
|
|
Requirements::javascript(SAPPHIRE_DIR . "/javascript/tree/tree.js");
|
|
|
|
Requirements::css(SAPPHIRE_DIR . "/javascript/tree/tree.css");
|
2009-03-10 23:08:52 +01:00
|
|
|
Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang');
|
2010-02-12 03:39:07 +01:00
|
|
|
// needed for errorMessage()
|
|
|
|
Requirements::javascript(SAPPHIRE_DIR . '/javascript/LeftAndMain.js');
|
ENHANCEMENT Introduced constants for system paths like /sapphire in preparation for a more flexible directory reorganisation. Instead of hardcoding your path, please use the following constants: BASE_PATH, BASE_URL, SAPPHIRE_DIR, SAPPHIRE_PATH, CMS_DIR, CMS_PATH, THIRDPARTY_DIR, THIRDPARTY_PATH, ASSETS_DIR, ASSETS_PATH, THEMES_DIR, THEMES_PATH
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@63154 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-09-27 18:02:38 +02:00
|
|
|
Requirements::javascript(SAPPHIRE_DIR . "/javascript/TreeSelectorField.js");
|
2010-02-22 05:37:33 +01:00
|
|
|
|
2010-02-12 05:01:41 +01:00
|
|
|
// Any field values have priority over the relation getters
|
|
|
|
if($this->value) {
|
|
|
|
$items = new DataObjectSet();
|
|
|
|
$ids = explode(',', $this->value);
|
|
|
|
foreach($ids as $id) {
|
2010-02-22 05:37:33 +01:00
|
|
|
if(!is_numeric($id)) continue;
|
|
|
|
|
2010-02-12 05:01:41 +01:00
|
|
|
$item = DataObject::get_by_id($this->sourceObject, $id);
|
|
|
|
if($item) $items->push($item);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$items = $this->getItems();
|
|
|
|
}
|
2010-02-22 05:37:33 +01:00
|
|
|
|
2010-02-12 05:01:41 +01:00
|
|
|
if($items && $items->Count()) {
|
2007-07-19 12:40:28 +02:00
|
|
|
foreach($items as $item) {
|
|
|
|
$titleArray[] =$item->Title;
|
|
|
|
$idArray[] = $item->ID;
|
|
|
|
}
|
|
|
|
if(isset($titleArray)) {
|
|
|
|
$itemList = implode(", ", $titleArray);
|
|
|
|
$value = implode(",", $idArray);
|
|
|
|
}
|
2010-02-12 05:01:41 +01:00
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
|
|
|
|
$id = $this->id();
|
|
|
|
|
|
|
|
return <<<HTML
|
2010-04-13 04:09:32 +02:00
|
|
|
<div class="TreeDropdownField multiple" href="{$this->Link()}"><input id="$id" type="hidden" name="$this->name" value="$value" /><span class="items">$itemList</span><a href="#" title="open" class="editLink"> </a></div>
|
2007-07-19 12:40:28 +02:00
|
|
|
HTML;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Save the results into the form
|
|
|
|
* Calls function $record->onChange($items) before saving to the assummed
|
|
|
|
* Component set.
|
|
|
|
*/
|
|
|
|
function saveInto(DataObject $record) {
|
|
|
|
// Detect whether this field has actually been updated
|
|
|
|
if($this->value !== 'unchanged') {
|
2008-11-03 14:47:40 +01:00
|
|
|
$items = array();
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
$fieldName = $this->name;
|
|
|
|
$saveDest = $record->$fieldName();
|
|
|
|
if(!$saveDest) user_error("TreeMultiselectField::saveInto() Field '$fieldName' not found on $record->class.$record->ID", E_USER_ERROR);
|
|
|
|
|
|
|
|
if($this->value) {
|
2009-06-18 11:34:17 +02:00
|
|
|
$items = preg_split("/ *, */", trim($this->value));
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Allows you to modify the items on your object before save
|
|
|
|
$funcName = "onChange$fieldName";
|
|
|
|
if($record->hasMethod($funcName)){
|
|
|
|
$result = $record->$funcName($items);
|
|
|
|
if(!$result){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2010-02-12 05:01:41 +01:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
$saveDest->setByIDList($items);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Changes this field to the readonly field.
|
|
|
|
*/
|
|
|
|
function performReadonlyTransformation() {
|
2010-04-12 03:35:17 +02:00
|
|
|
$field = new TreeMultiselectField_Readonly($this->name, $this->title, $this->sourceObject, $this->keyField, $this->labelField);
|
|
|
|
$field->addExtraClass($this->extraClass());
|
|
|
|
$field->setForm($this->form);
|
2010-04-13 04:13:12 +02:00
|
|
|
$field->setValue($this->value);
|
2010-04-12 03:35:17 +02:00
|
|
|
return $field;
|
2009-06-17 13:36:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class TreeMultiselectField_Readonly extends TreeMultiselectField {
|
|
|
|
|
|
|
|
protected $readonly = true;
|
|
|
|
|
|
|
|
function Field() {
|
2008-11-03 14:47:40 +01:00
|
|
|
$titleArray = array();
|
|
|
|
$titleList = array();
|
2007-07-19 12:40:28 +02:00
|
|
|
if($items = $this->getItems()) {
|
|
|
|
foreach($items as $item) $titleArray[] = $item->Title;
|
|
|
|
if($titleArray) $titleList = implode(", ", $titleArray);
|
|
|
|
}
|
2009-06-17 13:36:49 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
$field = new ReadonlyField($this->name, $this->title);
|
|
|
|
$field->setValue($titleList);
|
|
|
|
$field->setForm($this->form);
|
2009-06-17 13:36:49 +02:00
|
|
|
return $field->Field();
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2009-06-17 13:36:49 +02:00
|
|
|
}
|