diff --git a/code/WidgetAreaEditor.php b/code/WidgetAreaEditor.php
index 14f72eef..dd4a6d1a 100644
--- a/code/WidgetAreaEditor.php
+++ b/code/WidgetAreaEditor.php
@@ -42,14 +42,14 @@ class WidgetAreaEditor extends FormField {
function saveInto(DataObject $record) {
$name = $this->name;
$idName = $name . "ID";
-
+
$widgetarea = $record->getComponent($name);
$widgetarea->write();
$record->$idName = $widgetarea->ID;
-
+
$widgets = $widgetarea->Widgets();
-
+
// store the field IDs and delete the missing fields
// alternatively, we could delete all the fields and re add them
$missingWidgets = array();
@@ -60,48 +60,50 @@ class WidgetAreaEditor extends FormField {
}
}
- // write the new widgets to the database
if(isset($_REQUEST['Widget'])) {
- foreach(array_keys($_REQUEST['Widget']) as $newWidgetID) {
- $newWidgetData = $_REQUEST['Widget'][$newWidgetID];
-
- // Sometimes the id is "new-1" or similar, ensure this doesn't get into the query
- if(!is_numeric($newWidgetID)) {
- $newWidgetID = 0;
+ foreach(array_keys($_REQUEST['Widget']) as $widgetAreaName) {
+ if ($widgetAreaName !== $this->name) {
+ continue;
}
-
- // \"ParentID\" = '0' is for the new page
- $widget = DataObject::get_one(
- 'Widget',
- sprintf(
- '("ParentID" = %d OR "ParentID" = 0) AND "Widget"."ID" = %d',
- $record->$name()->ID,
- (int)$newWidgetID
- )
- );
-
- // check if we are updating an existing widget
- if($widget && isset($missingWidgets[$widget->ID])) {
- unset($missingWidgets[$widget->ID]);
- }
-
- // create a new object
- if(!$widget && !empty($newWidgetData['Type']) && class_exists($newWidgetData['Type'])) {
- $widget = new $newWidgetData['Type']();
- $widget->ID = 0;
- $widget->ParentID = $record->$name()->ID;
-
- if(!is_subclass_of($widget, 'Widget')) {
- $widget = null;
- }
- }
-
- if($widget) {
- if($widget->ParentID == 0) {
- $widget->ParentID = $record->$name()->ID;
+
+ foreach(array_keys($_REQUEST['Widget'][$widgetAreaName]) as $newWidgetID) {
+ $newWidgetData = $_REQUEST['Widget'][$widgetAreaName][$newWidgetID];
+
+ // Sometimes the id is "new-1" or similar, ensure this doesn't get into the query
+ if(!is_numeric($newWidgetID)) {
+ $newWidgetID = 0;
+ }
+
+ // \"ParentID\" = '0' is for the new page
+ $widget = DataObject::get_one(
+ 'Widget',
+ "(\"ParentID\" = '{$record->$name()->ID}' OR \"ParentID\" = '0') AND \"Widget\".\"ID\" = '$newWidgetID'"
+ );
+
+
+ // check if we are updating an existing widget
+ if($widget && isset($missingWidgets[$widget->ID])) {
+ unset($missingWidgets[$widget->ID]);
+ }
+
+ // create a new object
+ if(!$widget && !empty($newWidgetData['Type']) && class_exists($newWidgetData['Type'])) {
+ $widget = new $newWidgetData['Type']();
+ $widget->ID = 0;
+ $widget->ParentID = $record->$name()->ID;
+
+ if(!is_subclass_of($widget, 'Widget')) {
+ $widget = null;
+ }
+ }
+
+ if($widget) {
+ if($widget->ParentID == 0) {
+ $widget->ParentID = $record->$name()->ID;
+ }
+ // echo "Saving $widget->ID into $name/$widget->ParentID\n
";
+ $widget->populateFromPostData($newWidgetData);
}
-
- $widget->populateFromPostData($newWidgetData);
}
}
}
@@ -109,7 +111,9 @@ class WidgetAreaEditor extends FormField {
// remove the fields not saved
if($missingWidgets) {
foreach($missingWidgets as $removedWidget) {
- if(isset($removedWidget) && is_numeric($removedWidget->ID)) $removedWidget->delete();
+ if(isset($removedWidget) && is_numeric($removedWidget->ID)) {
+ $removedWidget->delete();
+ }
}
}
}
diff --git a/css/WidgetAreaEditor.css b/css/WidgetAreaEditor.css
index 9f2bf54a..9b60ede6 100644
--- a/css/WidgetAreaEditor.css
+++ b/css/WidgetAreaEditor.css
@@ -15,7 +15,7 @@ div.usedWidgets {
border: 1px #CCC dotted;
padding: 5px;
}
-#NoWidgets {
+.NoWidgets {
padding: 50px; /* Make this nice and big and easily 'droppable' */
}
diff --git a/javascript/WidgetAreaEditor.js b/javascript/WidgetAreaEditor.js
index 31fdfcf7..02e2deb1 100644
--- a/javascript/WidgetAreaEditor.js
+++ b/javascript/WidgetAreaEditor.js
@@ -1,53 +1,97 @@
WidgetAreaEditorClass = Class.create();
-WidgetAreaEditorClass.applyTo('div.WidgetAreaEditor');
WidgetAreaEditorClass.prototype = {
initialize: function() {
- UsedWidget.applyToChildren($('WidgetAreaEditor_usedWidgets'), 'div.Widget');
+ this.name = this.getAttribute('name');
+ this.rewriteWidgetAreaAttributes();
+ UsedWidget.applyToChildren($('usedWidgets-'+this.name), 'div.Widget');
// Make available widgets draggable
- var availableWidgets = $('WidgetAreaEditor_availableWidgets').childNodes;
+ var availableWidgets = $('availableWidgets-'+this.name).childNodes;
+
for(var i = 0; i < availableWidgets.length; i++) {
var widget = availableWidgets[i];
- if(widget.id)
- new Draggable(widget.id);
+ // Don't run on comments, whitespace, etc
+ if (widget.nodeType == 1) {
+ // Gotta change their ID's because otherwise we get clashes between two tabs
+ widget.id = widget.id + '-'+this.name;
+ if(widget.id) {
+ widget.onclick = function(event) {
+ parts = event.currentTarget.id.split('-');
+ var widgetArea = parts.pop();
+ var className = parts.pop();
+ $('WidgetAreaEditor-'+widgetArea).addWidget(className, widgetArea);
+ }
+ }
+ }
}
-
+
+
// Create dummy sortable to prevent javascript errors
- Sortable.create('WidgetAreaEditor_availableWidgets', {
+ Sortable.create('availableWidgets-'+this.name, {
tag: 'li',
handle: 'handle',
containment: []
});
// Used widgets are sortable
- Sortable.create('WidgetAreaEditor_usedWidgets', {
+ Sortable.create('usedWidgets-'+this.name, {
tag: 'div',
handle: 'handle',
- containment: ['WidgetAreaEditor_availableWidgets', 'WidgetAreaEditor_usedWidgets'],
+ containment: ['availableWidgets-'+this.name, 'usedWidgets-'+this.name],
onUpdate: this.updateWidgets
});
// Figure out maxid, this is used when creating new widgets
this.maxid = 0;
- var usedWidgets = $('WidgetAreaEditor_usedWidgets').childNodes;
+ var usedWidgets = $('usedWidgets-'+this.name).childNodes;
for(var i = 0; i < usedWidgets.length; i++) {
var widget = usedWidgets[i];
if(widget.id) {
- widgetid = widget.id.match(/Widget\[([0-9]+)\]/i);
- if(widgetid && parseInt(widgetid[1]) > this.maxid)
- this.maxid = parseInt(widgetid[1]);
+ widgetid = widget.id.match(/\Widget\[(.+?)\]\[([0-9]+)\]/i);
+ if(widgetid && parseInt(widgetid[2]) > this.maxid) {
+ this.maxid = parseInt(widgetid[2]);
+ }
}
}
-
+
// Ensure correct sort values are written when page is saved
$('Form_EditForm').observeMethod('BeforeSave', this.beforeSave.bind(this));
},
+ rewriteWidgetAreaAttributes: function() {
+ this.name = this.getAttribute('name');
+
+ var monkeyWith = function(widgets, name) {
+ for(var i = 0; i < widgets.length; i++) {
+ widget = widgets[i];
+ if (!widget.getAttribute('rewritten') && (widget.id || widget.name)) {
+ if (widget.id && widget.id.indexOf('Widget[') === 0) {
+ var newValue = widget.id.replace(/Widget\[/, 'Widget['+name+'][');
+ //console.log('Renaming '+widget.tagName+' ID '+widget.id+' to '+newValue);
+ widget.id = newValue;
+ }
+ if (widget.name && widget.name.indexOf('Widget[') === 0) {
+ var newValue = widget.name.replace(/Widget\[/, 'Widget['+name+'][');
+ //console.log('Renaming '+widget.tagName+' Name '+widget.name+' to '+newValue);
+ widget.name = newValue;
+ }
+ widget.setAttribute('rewritten', 'yes');
+ }
+ else {
+ //console.log('Skipping '+(widget.id ? widget.id : (widget.name ? widget.name : 'unknown '+widget.tagName)));
+ }
+ }
+ }
+
+ monkeyWith($$('#WidgetAreaEditor-'+this.name+' .Widget'), this.name);
+ monkeyWith($$('#WidgetAreaEditor-'+this.name+' .Widget *'), this.name);
+ },
+
beforeSave: function() {
// Ensure correct sort values are written when page is saved
- var usedWidgets = $('WidgetAreaEditor_usedWidgets');
+ var usedWidgets = $('usedWidgets-'+this.name);
if(usedWidgets) {
this.sortWidgets();
@@ -64,15 +108,37 @@ WidgetAreaEditorClass.prototype = {
}
},
+ addWidget: function(className, holder) {
+ this.name = holder;
+ new Ajax.Request('Widget_Controller/EditableSegment/' + className, {
+ onSuccess : $('usedWidgets-'+holder).parentNode.parentNode.insertWidgetEditor.bind(this)
+ });
+ },
+
updateWidgets: function() {
+
+ // Gotta get the name of the current dohickey based off the ID
+ this.name = this.element.id.split('-').pop();
+
+ // alert(this.name);
+
+ // Gotta get the name of the current dohickey based off the ID
+ this.name = this.element.id.split('-').pop();
+
+
// This is called when an available widgets is dragged over to used widgets.
// It inserts the editor form into the new used widget
- var usedWidgets = $('WidgetAreaEditor_usedWidgets').childNodes;
+
+ var usedWidgets = $('usedWidgets-'+this.name).childNodes;
for(var i = 0; i < usedWidgets.length; i++) {
var widget = usedWidgets[i];
- if(widget.id && (widget.id.indexOf("Widget[") != 0) && (widget.id != 'NoWidgets')) {
- new Ajax.Request('Widget_Controller/EditableSegment/' + widget.id, {
- onSuccess : $('WidgetAreaEditor_usedWidgets').parentNode.parentNode.insertWidgetEditor.bind(this)
+ if(widget.id && (widget.id.indexOf("Widget[") != 0) && (widget.id != 'NoWidgets-'+this.name)) {
+ // Need to remove the -$Name part.
+ var wIdArray = widget.id.split('-');
+ wIdArray.pop();
+
+ new Ajax.Request('Widget_Controller/EditableSegment/' + wIdArray.join('-'), {
+ onSuccess : $('usedWidgets-'+this.name).parentNode.parentNode.insertWidgetEditor.bind(this)
});
}
}
@@ -80,47 +146,31 @@ WidgetAreaEditorClass.prototype = {
insertWidgetEditor: function(response) {
// Remove placeholder text
- if($('NoWidgets')) {
- $('WidgetAreaEditor_usedWidgets').removeChild($('NoWidgets'));
+ if($('NoWidgets-'+this.name)) {
+ $('usedWidgets-'+this.name).removeChild($('NoWidgets-'+this.name));
}
+
+ var usedWidgets = $('usedWidgets-'+this.name).childNodes;
+
+ // Give the widget a unique id
+ widget = document.createElement('div');
+ widget.innerHTML = response.responseText.replace(/Widget\[0\]/gi, "Widget[new-" + (++$('usedWidgets-'+this.name).parentNode.parentNode.maxid) + "]");
- // Find the new widget
- var usedWidgets = $('WidgetAreaEditor_usedWidgets').childNodes;
- for(var i = 0; i < usedWidgets.length; i++) {
- var widget = usedWidgets[i];
- if(widget.id && (widget.id.indexOf("Widget[") != 0)) {
- // Clone the widget so we can put it back in the available widgets column
- clone = widget.cloneNode(true);
-
- // Give the widget a unique id
- widget.innerHTML = response.responseText.replace(/Widget\[0\]/gi, "Widget[new-" + (++$('WidgetAreaEditor_usedWidgets').parentNode.parentNode.maxid) + "]");
-
- // Replace the available widget with the used widget with editor form
- widget.parentNode.insertBefore($(widget).getElementsByClassName('Widget')[0], widget);
- widget.parentNode.removeChild(widget);
-
- // Put the clone into the available widgets column
- $('WidgetAreaEditor_availableWidgets').appendChild(clone);
-
- // Reapply behaviour
- new Draggable(clone.id);
-
- Sortable.create('WidgetAreaEditor_usedWidgets', {
- tag: 'div',
- handle: 'handle',
- containment: ['WidgetAreaEditor_availableWidgets', 'WidgetAreaEditor_usedWidgets'],
- onUpdate: $('WidgetAreaEditor_usedWidgets').parentNode.parentNode.updateWidgets
- });
-
- UsedWidget.applyToChildren($('WidgetAreaEditor_usedWidgets'), 'div.Widget');
- return;
- }
- }
+ $('usedWidgets-'+this.name).appendChild(widget.childNodes[0]);
+ $('usedWidgets-'+this.name).parentNode.parentNode.rewriteWidgetAreaAttributes();
+ UsedWidget.applyToChildren($('usedWidgets-'+this.name), 'div.Widget');
+
+ Sortable.create('usedWidgets-SideBar', {
+ tag: 'div',
+ handle: 'handle',
+ containment: ['availableWidgets-'+this.name, 'usedWidgets-'+this.name],
+ onUpdate: $('usedWidgets-'+this.name).parentNode.parentNode.updateWidgets
+ });
},
sortWidgets: function() {
// Order the sort by the order the widgets are in the list
- var usedWidgets = $('WidgetAreaEditor_usedWidgets');
+ var usedWidgets = $('usedWidgets-'+this.name);
if(usedWidgets) {
widgets = usedWidgets.childNodes;
@@ -144,7 +194,8 @@ WidgetAreaEditorClass.prototype = {
deleteWidget: function(widgetToRemove) {
// Remove a widget from the used widgets column
- $('WidgetAreaEditor_usedWidgets').removeChild(widgetToRemove);
+ $('usedWidgets-'+this.name).removeChild(widgetToRemove);
+ // TODO ... re-create NoWidgets div?
}
}
@@ -180,3 +231,10 @@ UsedWidget.prototype = {
}
}
+// Loop over all WidgetAreas and fire 'em up
+var wAs = $$('.WidgetAreaEditor');
+for(var i = 0; i < wAs.length; i++) {
+ WidgetAreaEditorClass.applyTo('div#'+wAs[i].id);
+
+}
+
diff --git a/templates/WidgetAreaEditor.ss b/templates/WidgetAreaEditor.ss
index 7defcdc5..187e33e4 100644
--- a/templates/WidgetAreaEditor.ss
+++ b/templates/WidgetAreaEditor.ss
@@ -1,15 +1,15 @@
-
-
<% _t('NOAVAIL', 'There are currently no widgets available.') %>
<% _t('TOADD', 'To add widgets, drag them from the left area to here.') %>
-