BUGFIX: Allow creation of TreeDropdownFields on forms with querystring URLs.

API CHANGE: Allow passing of an explicit map of dropdown items to a TreeDropdownField.
BUGFIX: Make use of the $this->value setting of TreeMultiselectFields. (from r95910) (from r98101)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@102594 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2010-04-13 02:09:32 +00:00
parent 9a56e31bfb
commit 4a2d71ae2a
3 changed files with 45 additions and 8 deletions

View File

@ -30,7 +30,10 @@ class TreeDropdownField extends FormField {
*
* @param string $name the field name
* @param string $title the field label
* @param string $souceClass the class to display in the tree, must have the "Hierachy" extension.
* @param sourceObject The object-type to list in the tree. Must be a 'hierachy' object. Alternatively,
* you can set this to an array of key/value pairs, like a dropdown source. In this case, the field
* will act like show a flat list of tree items, without any hierachy. This is most useful in
* conjunction with TreeMultiselectField, for presenting a set of checkboxes in a compact view.
* @param string $keyField to field on the source class to save as the field value (default ID).
* @param string $labelField the field name to show as the human-readable value on the tree (default Title).
* @param string $showSearch enable the ability to search the tree by entering the text in the input field.
@ -109,7 +112,8 @@ class TreeDropdownField extends FormField {
'div',
array (
'id' => "TreeDropdownField_{$this->id()}",
'class' => 'TreeDropdownField single' . ($this->extraClass() ? " {$this->extraClass()}" : '')
'class' => 'TreeDropdownField single' . ($this->extraClass() ? " {$this->extraClass()}" : ''),
'href' => $this->Link(),
),
$this->createTag (
'input',
@ -153,6 +157,17 @@ class TreeDropdownField extends FormField {
* @return string
*/
public function tree(SS_HTTPRequest $request) {
// Array sourceObject is an explicit list of values - construct a "flat tree"
if(is_array($this->sourceObject)) {
$output = "<ul class=\"tree\">\n";
foreach($this->sourceObject as $k => $v) {
$output .= '<li id="selector-' . $this->name . '-' . $k . '"><a>' . $v . '</a>';
}
$output .= "</ul>";
return $output;
}
// Regular source specification
$isSubTree = false;
$this->search = Convert::Raw2SQL($request->getVar('search'));

View File

@ -15,7 +15,20 @@ class TreeMultiselectField extends TreeDropdownField {
* Return this field's linked items
*/
function getItems() {
if($this->form) {
// 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) {
$fieldName = $this->name;
$record = $this->form->getRecord();
if(is_object($record) && $record->hasMethod($fieldName))
@ -68,7 +81,7 @@ class TreeMultiselectField extends TreeDropdownField {
$id = $this->id();
return <<<HTML
<div class="TreeDropdownField multiple"><input id="$id" type="hidden" name="$this->name" value="$value" /><span class="items">$itemList</span><a href="#" title="open" class="editLink">&nbsp;</a></div>
<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">&nbsp;</a></div>
HTML;
}

View File

@ -57,8 +57,17 @@ TreeDropdownField.prototype = {
}).bind(this));
},
helperURLBase: function() {
return this.ownerForm().action + '/field/' + this.getName() + '/';
// Build a URL from the field's base URL and the given sub URL
buildURL: function(subURL) {
var baseURL = jQuery(this).attr('href');
var subHasQuerystring = subURL.match(/\?/);
if(baseURL.match(/^(.*)\?(.*)$/)) {
if(subHasQuerystring) return RegExp.$1 + '/' + subURL + '&' + RegExp.$2
else return RegExp.$1 + '/' + subURL + '?' + RegExp.$2
} else {
return baseURL + '/' + subURL;
}
},
ownerForm: function() {
var f =this.parentNode;
@ -171,7 +180,7 @@ TreeDropdownField.prototype = {
},
ajaxGetTree: function(after) {
var ajaxURL = this.helperURLBase() + 'tree?';
var ajaxURL = this.buildURL('tree?forceValues=' + this.inputTag.value);
ajaxURL += $('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '';
if($('Form_EditForm_Locale')) ajaxURL += "&locale=" + $('Form_EditForm_Locale').value;
if ( this.inputTag.value ) ajaxURL += '&forceValue=' + this.inputTag.value;
@ -225,7 +234,7 @@ TreeDropdownField.prototype = {
var ul = this.treeNodeHolder();
ul.innerHTML = ss.i18n._t('LOADING', 'Loading...');
var ajaxURL = this.options.dropdownField.helperURLBase() + 'tree/' + this.getIdx();
var ajaxURL = this.options.dropdownField.buildURL('tree/' + this.getIdx());
ajaxURL += $('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '';
if($('Form_EditForm_Locale')) ajaxURL += "&locale=" + $('Form_EditForm_Locale').value;
// ajaxExpansion is called in context of TreeNode, not Tree, so search() doesn't exist.