Box children can now auto-repeat if child ID has $

This commit is contained in:
Nathan Gray 2013-07-04 19:38:36 +00:00
parent 86dfe42104
commit 4d2c969b8f
2 changed files with 161 additions and 14 deletions

View File

@ -892,11 +892,87 @@ class etemplate_widget_box extends etemplate_widget
public function run($method_name, $params=array(''), $respect_disabled=false)
{
$cname =& $params[0];
$expand =& $params[1];
$old_cname = $params[0];
$old_expand = $params[1];
if ($this->id) $cname = self::form_name($cname, $this->id, $params[1]);
parent::run($method_name, $params, $respect_disabled);
if ($expand['cname'] !== $cname && $cname)
{
$expand['cont'] =& self::get_array(self::$request->content, $cname);
$expand['cname'] = $cname;
}
if ($respect_disabled && ($disabled = $this->attrs['disabled'] || $disabled = self::check_disabled($disabled, $expand)))
{
if ($disabled)
{
error_log(__METHOD__."('$method_name', ".array2string($params).', '.array2string($respect_disabled).") $this disabled='{$this->attrs['disabled']}'='$disabled': NOT running");
return;
}
}
if (method_exists($this, $method_name))
{
call_user_func_array(array($this, $method_name), $params);
}
// Expand children
for($n = 0; ; ++$n)
{
// maintain $expand array name-expansion
$expand['row'] = $n;
if (isset($this->children[$n]))
{
$child = $this->children[$n];
}
// check if we need to autorepeat last row ($child)
elseif (isset($child) && $this->need_autorepeat($child, $cname, $expand))
{
// not breaking repeats last row/column ($child)
}
else
{
break;
}
//error_log('Running ' . $method_name . ' on child ' . $n . '(' . $child . ') ['.$expand['row'] . ','.$expand['c'] . ']');
$disabled = $child->run($method_name, $params, $respect_disabled, $columns_disabled) === false;
}
$params[0] = $old_cname;
$params[1] = $old_expand;
return true;
}
/**
* Check if a box child needs autorepeating, because still content left
*
* We only check passed widget and direct children.
*
* @param string $cname
* @param array $expand
*/
private function need_autorepeat(etemplate_widget &$widget, $cname, array $expand)
{
foreach(array($widget) + $widget->children as $check_widget)
{
$pat = $check_widget->id;
while(($pat = strstr($pat, '$')))
{
$pat = substr($pat,$pat[1] == '{' ? 2 : 1);
$Ok = $pat[0] == 'r' && !(substr($pat,0,2) == 'r_' || substr($pat,0,4) == 'row_');
if ($Ok && ($value = self::get_array(self::$request->content,
$fname=self::form_name($cname, $check_widget->id, $expand))) !== false && isset($value))
{
error_log(__METHOD__."($widget,$cname) $this autorepeating row $expand[row] because of $check_widget->id = '$fname' is ".array2string($value));
return true;
}
}
}
return false;
}
}
// register class for layout widgets, which can have an own namespace

View File

@ -45,24 +45,95 @@ var et2_box = et2_baseWidget.extend([et2_IDetachedDOM],
this.setDOMNode(this.div[0]);
},
/**
* Code for implementing et2_IDetachedDOM
* Overriden so we can check for autorepeating children. We only check for
* $ in the immediate children & grandchildren of this node.
*/
loadFromXML: function(_node) {
if(this._type != "box")
{
return this._super.apply(this, arguments);
}
// Load the child nodes.
var childIndex = 0;
var repeatNode = null;
for (var i=0; i < _node.childNodes.length; i++)
{
var node = _node.childNodes[i];
var widgetType = node.nodeName.toLowerCase();
if (widgetType == "#comment")
{
continue;
}
if (widgetType == "#text")
{
if (node.data.replace(/^\s+|\s+$/g, ''))
{
this.loadContent(node.data);
}
continue;
}
// Create the new element, if no expansion needed
var id = et2_readAttrWithDefault(node, "id", "");
if(id.indexOf('$') < 0)
{
this.createElementFromNode(node);
childIndex++;
}
else
{
repeatNode = node;
}
}
// Only the last child repeats(?)
if(repeatNode != null)
{
var currentPerspective = this.getArrayMgr("content").perspectiveData;
// Extra content
for(childIndex; typeof this.getArrayMgr("content").data[childIndex] != "undefined" && this.getArrayMgr("content").data[childIndex]; childIndex++) {
// Adjust for the row
var mgrs = this.getArrayMgrs();
for(var name in mgrs)
{
if(this.getArrayMgr(name).getEntry(childIndex))
{
this.getArrayMgr(name).perspectiveData.row = childIndex;
}
}
this.createElementFromNode(repeatNode);
}
// Reset
for(var name in this.getArrayMgrs())
{
this.getArrayMgr(name).perspectiveData = currentPerspective;
}
}
},
/**
* Code for implementing et2_IDetachedDOM
* This doesn't need to be implemented.
* Individual widgets are detected and handled by the grid, but the interface is needed for this to happen
*/
getDetachedAttributes: function(_attrs)
{
},
*/
getDetachedAttributes: function(_attrs)
{
},
getDetachedNodes: function()
{
getDetachedNodes: function()
{
return [this.getDOMNode()];
},
},
setDetachedAttributes: function(_nodes, _values)
{
}
setDetachedAttributes: function(_nodes, _values)
{
}
});
et2_register_widget(et2_box, ["vbox", "box"]);