Skip to content

Commit

Permalink
FIX: TreeDropdownField Folder expansion
Browse files Browse the repository at this point in the history
When viewing a Folder tree, an expansion icon was shown if the Folder had *any* children, but it should be restricted to children that are Folders.
  • Loading branch information
jonom committed May 27, 2015
1 parent 50d88ed commit a56d08b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 14 deletions.
1 change: 0 additions & 1 deletion filesystem/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@ public function getCMSFields() {

//get a tree listing with only folder, no files
$folderTree = new TreeDropdownField("ParentID", _t('AssetTableField.FOLDER','Folder'), 'Folder');
$folderTree->setChildrenMethod('ChildFolders');

$fields = new FieldList(
new TabSet('Root',
Expand Down
9 changes: 8 additions & 1 deletion filesystem/Folder.php
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,13 @@ public function getCMSFields() {
public function ChildFolders() {
return Folder::get()->filter('ParentID', $this->ID);
}

/**
* Get the number of children of this folder that are also folders.
*/
public function numChildFolders() {
return $this->ChildFolders()->count();
}

/**
* @return String
Expand All @@ -479,7 +486,7 @@ public function CMSTreeClasses() {
if(!$this->canEdit())
$classes .= " disabled";

$classes .= $this->markingClasses();
$classes .= $this->markingClasses('numChildFolders');

return $classes;
}
Expand Down
42 changes: 31 additions & 11 deletions forms/TreeDropdownField.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,13 @@ class TreeDropdownField extends FormField {
protected $sourceObject, $keyField, $labelField, $filterCallback,
$disableCallback, $searchCallback, $baseID = 0;
/**
* @var string default child method in Hierarcy->getChildrenAsUL
* @var string default child method in Hierarchy->getChildrenAsUL
*/
protected $childrenMethod = 'AllChildrenIncludingDeleted';
/**
* @var string default child counting method in Hierarchy->getChildrenAsUL
*/
protected $numChildrenMethod = 'numChildren';

/**
* Used by field search to leave only the relevant entries
Expand Down Expand Up @@ -96,6 +100,12 @@ public function __construct($name, $title = null, $sourceObject = 'Group', $keyF
$this->keyField = $keyField;
$this->labelField = $labelField;
$this->showSearch = $showSearch;

//Extra settings for Folders
if ($sourceObject == 'Folder') {
$this->childrenMethod = 'ChildFolders';
$this->numChildrenMethod = 'numChildFolders';
}

$this->addExtraClass('single');

Expand Down Expand Up @@ -171,16 +181,26 @@ public function setShowSearch($bool) {

/**
* @param $method The parameter to ChildrenMethod to use when calling Hierarchy->getChildrenAsUL in
* {@link Hierarchy}. The method specified determined the structure of the returned list. Use "ChildFolders"
* {@link Hierarchy}. The method specified determines the structure of the returned list. Use "ChildFolders"
* in place of the default to get a drop-down listing with only folders, i.e. not including the child elements in
* the currently selected folder.
* the currently selected folder. setNumChildrenMethod() should be used as well for proper functioning.
*
* See {@link Hierarchy} for a complete list of possible methods.
*/
public function setChildrenMethod($method) {
$this->childrenMethod = $method;
return $this;
}

/**
* @param $method The parameter to numChildrenMethod to use when calling Hierarchy->getChildrenAsUL in
* {@link Hierarchy}. Should be used in conjunction with setChildrenMethod().
*
*/
public function setNumChildrenMethod($method) {
$this->numChildrenMethod = $method;
return $this;
}

/**
* @return string
Expand Down Expand Up @@ -273,10 +293,11 @@ public function tree(SS_HTTPRequest $request) {
if ( $this->search != "" )
$this->populateIDs();

if ($this->filterCallback || $this->sourceObject == 'Folder' || $this->search != "" )
if ($this->filterCallback || $this->search != "" )
$obj->setMarkingFilterFunction(array($this, "filterMarking"));

$obj->markPartialTree();
$obj->markPartialTree($nodeCountThreshold = 30, $context = null,
$this->childrenMethod, $this->numChildrenMethod);

// allow to pass values to be selected within the ajax request
if( isset($_REQUEST['forceValue']) || $this->value ) {
Expand All @@ -298,7 +319,7 @@ public function tree(SS_HTTPRequest $request) {
Convert::raw2xml($child->$keyField),
Convert::raw2xml($child->$keyField),
Convert::raw2xml($child->class),
Convert::raw2xml($child->markingClasses()),
Convert::raw2xml($child->markingClasses($self->numChildrenMethod)),
($self->nodeIsDisabled($child)) ? 'disabled' : '',
(int)$child->ID,
$child->obj($labelField)->forTemplate()
Expand Down Expand Up @@ -330,7 +351,7 @@ public function tree(SS_HTTPRequest $request) {
null,
true,
$this->childrenMethod,
'numChildren',
$this->numChildrenMethod,
true, // root call
null,
$nodeCountCallback
Expand All @@ -343,7 +364,7 @@ public function tree(SS_HTTPRequest $request) {
null,
true,
$this->childrenMethod,
'numChildren',
$this->numChildrenMethod,
true, // root call
null,
$nodeCountCallback
Expand All @@ -353,15 +374,14 @@ public function tree(SS_HTTPRequest $request) {
}

/**
* Marking public function for the tree, which combines different filters sensibly. If a filter function has been
* set, that will be called. If the source is a folder, automatically filter folder. And if search text is set,
* Marking public function for the tree, which combines different filters sensibly.
* If a filter function has been set, that will be called. And if search text is set,
* filter on that too. Return true if all applicable conditions are true, false otherwise.
* @param $node
* @return unknown_type
*/
public function filterMarking($node) {
if ($this->filterCallback && !call_user_func($this->filterCallback, $node)) return false;
if ($this->sourceObject == "Folder" && $node->ClassName != 'Folder') return false;
if ($this->search != "") {
return isset($this->searchIds[$node->ID]) && $this->searchIds[$node->ID] ? true : false;
}
Expand Down
2 changes: 1 addition & 1 deletion model/Hierarchy.php
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ public function markingClasses($numChildrenMethod="numChildren") {
}

// Set jstree open state, or mark it as a leaf (closed) if there are no children
if(!$this->$numChildrenMethod()) {
if(!$this->owner->$numChildrenMethod()) {
$classes .= " jstree-leaf closed";
} elseif($this->isTreeOpened()) {
$classes .= " jstree-open";
Expand Down

0 comments on commit a56d08b

Please sign in to comment.