2007-07-19 12:40:28 +02:00
|
|
|
<?php
|
2008-01-09 05:18:36 +01:00
|
|
|
/**
|
|
|
|
* Dropdown-like field that gives you a tree of items, using ajax.
|
|
|
|
* @package forms
|
|
|
|
* @subpackage fields-relational
|
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
class TreeDropdownField extends FormField {
|
|
|
|
protected $sourceObject, $keyField, $labelField, $filterFunc;
|
|
|
|
protected $treeBaseID = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new tree dropdown field.
|
|
|
|
* @param name The name of the field.
|
|
|
|
* @param title The label of the field.
|
2008-01-13 23:06:51 +01:00
|
|
|
* @param sourceObject The object-type to list in the tree. Must be a 'hierachy' object.
|
2007-07-19 12:40:28 +02:00
|
|
|
* @param keyField The column of that object-type to return as the field value. Defaults to ID
|
|
|
|
* @param labelField The column to show as the human-readable value in the tree. Defaults to Title
|
|
|
|
*/
|
|
|
|
function __construct($name, $title, $sourceObject = "Group", $keyField = "ID", $labelField = "Title") {
|
|
|
|
$this->sourceObject = $sourceObject;
|
|
|
|
$this->keyField = $keyField;
|
|
|
|
$this->labelField = $labelField;
|
2007-09-27 22:56:55 +02:00
|
|
|
|
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::css(SAPPHIRE_DIR . '/css/TreeDropdownField.css');
|
2007-09-27 22:56:55 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
parent::__construct($name, $title);
|
|
|
|
}
|
|
|
|
|
|
|
|
function setFilterFunction($filterFunc) {
|
|
|
|
$this->filterFunc = $filterFunc;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Set the root node of the tree. Defaults to 0, ie, the whole tree
|
|
|
|
*/
|
|
|
|
function setTreeBaseID($treeBaseID) {
|
|
|
|
$this->treeBaseID = $treeBaseID;
|
|
|
|
}
|
|
|
|
|
|
|
|
function Field() {
|
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(THIRDPARTY_DIR . "/tree/tree.js");
|
|
|
|
Requirements::css(THIRDPARTY_DIR . "/tree/tree.css");
|
|
|
|
Requirements::javascript(SAPPHIRE_DIR . "/javascript/TreeSelectorField.js");
|
2007-07-19 12:40:28 +02:00
|
|
|
|
|
|
|
if($this->value) {
|
|
|
|
$record = DataObject::get_by_id($this->sourceObject, $this->value);
|
|
|
|
$title = $record->Title;
|
|
|
|
} else {
|
2007-10-25 04:47:45 +02:00
|
|
|
$title = _t('DropdownField.CHOOSE', "(Choose)", PR_MEDIUM, 'Start-value of a dropdown');
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$id = $this->id();
|
|
|
|
|
|
|
|
return <<<HTML
|
|
|
|
<div id="TreeDropdownField_$id" class="TreeDropdownField single"><input id="$id" type="hidden" name="$this->name" value="$this->value" /><span class="items">$title</span><a href="#" title="open" class="editLink"> </a></div>
|
|
|
|
HTML;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the site tree
|
|
|
|
*/
|
|
|
|
function gettree() {
|
|
|
|
if($this->treeBaseID) $obj = DataObject::get_by_id($this->sourceObject, $this->treeBaseID);
|
|
|
|
else $obj = singleton($this->sourceObject);
|
|
|
|
|
|
|
|
|
|
|
|
if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc);
|
|
|
|
else if($this->sourceObject == 'Folder') $obj->setMarkingFilter('ClassName', 'Folder');
|
|
|
|
$obj->markPartialTree();
|
|
|
|
|
|
|
|
// If we've already got values selected, make sure that we've got them in our tree
|
|
|
|
if($_REQUEST['forceValues']) {
|
|
|
|
$forceValues = split(" *, *", trim($_REQUEST['forceValues']));
|
|
|
|
foreach($forceValues as $value) {
|
|
|
|
$obj->markToExpose($this->getByKey($value));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$eval = '"<li id=\"selector-' . $this->name . '-$child->' . $this->keyField . '\" class=\"$child->class" . $child->markingClasses() . "\"><a>" . $child->' . $this->labelField . ' . "</a>"';
|
|
|
|
echo $obj->getChildrenAsUL("class=\"tree\"", $eval, null, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a subtree via Ajax
|
|
|
|
*/
|
|
|
|
public function getsubtree() {
|
|
|
|
if($this->keyField == "ID") $obj = DataObject::get_by_id($this->sourceObject, $_REQUEST['SubtreeRootID']);
|
|
|
|
else $obj = DataObject::get_one($this->sourceObject, "$this->keyField = '$_REQUEST[SubtreeRootID]'");
|
|
|
|
|
|
|
|
if(!$obj) user_error("Can't find database record $this->sourceObject with $this->keyField = $_REQUEST[SubtreeRootID]", E_USER_ERROR);
|
|
|
|
if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc);
|
|
|
|
$obj->markPartialTree();
|
|
|
|
|
|
|
|
$eval = '"<li id=\"selector-' . $this->name . '-$child->' . $this->keyField . '\" class=\"$child->class" . $child->markingClasses() . "\"><a>" . $child->' . $this->labelField . ' . "</a>"';
|
|
|
|
$tree = $obj->getChildrenAsUL("", $eval, null, true);
|
|
|
|
echo substr(trim($tree), 4,-5);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getByKey($key) {
|
|
|
|
if(!is_numeric($key)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($this->keyField == 'ID') {
|
|
|
|
return DataObject::get_by_id($this->sourceObject, $key);
|
|
|
|
} else {
|
|
|
|
return DataObject::get_one($this->sourceObject, "$this->keyField = '$key'");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the stack of values to be traversed to find the given key in the database
|
|
|
|
*/
|
|
|
|
public function getstack() {
|
|
|
|
if($this->keyField == "ID") $page = DataObject::get_by_id($this->sourceObject, $_REQUEST['SubtreeRootID']);
|
|
|
|
else $page = $this->getByKey($_REQUEST['SubtreeRootID']);
|
|
|
|
|
|
|
|
while($page->ParentID) {
|
|
|
|
echo $ids[] = $page->ID;
|
|
|
|
$page = $page->Parent;
|
|
|
|
}
|
|
|
|
$ids[] = $page->ID;
|
|
|
|
echo implode(",", array_reverse($ids));
|
|
|
|
}
|
|
|
|
|
|
|
|
function performReadonlyTransformation() {
|
|
|
|
$fieldName = $this->labelField;
|
|
|
|
$source = array(
|
|
|
|
$this->value => $this->getByKey($this->value)->$fieldName
|
|
|
|
);
|
|
|
|
$field = new LookupField($this->name, $this->title, $source);
|
|
|
|
$field->setValue($this->value);
|
|
|
|
$field->setForm($this->form);
|
2008-08-12 04:58:48 +02:00
|
|
|
$field->setReadonly(true);
|
2007-07-19 12:40:28 +02:00
|
|
|
return $field;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-01-13 23:06:51 +01:00
|
|
|
?>
|