Commit b5185e88 authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Make block configuration forms wider when js is available; form content not widened yet

parent a8cc24bc
......@@ -395,6 +395,7 @@ class BlockInstance {
$smarty->assign('movecontrols', $movecontrols);
$smarty->assign('configurable', call_static_method(generate_class_name('blocktype', $this->get('blocktype')), 'has_instance_config'));
$smarty->assign('configure', $configure); // Used by the javascript to rewrite the block, wider.
$smarty->assign('content', $content);
$smarty->assign('javascript', defined('JSON'));
$smarty->assign('strnotitle', get_string('notitle', 'view'));
......@@ -444,6 +445,12 @@ class BlockInstance {
* javascript to run
*/
public function build_configure_form($new=false) {
static $renderedform;
if (!empty($renderedform)) {
return $renderedform;
}
safe_require('blocktype', $this->get('blocktype'));
$elements = call_static_method(generate_class_name('blocktype', $this->get('blocktype')), 'instance_config_form', $this);
......@@ -472,6 +479,17 @@ class BlockInstance {
? get_string('defaulttitledescription', 'blocktype.' . blocktype_name_to_namespaced($this->get('blocktype'))) : null,
'defaultvalue' => $title,
),
'blockconfig' => array(
'type' => 'hidden',
'value' => $this->get('id'),
),
// This form is never submitted by js, but if it was
// created by a json script, remember that in case the
// block is rendered again after a form error.
'js' => array(
'type' => 'hidden',
'value' => (bool) defined('JSON'),
),
),
$elements
);
......@@ -539,7 +557,8 @@ class BlockInstance {
}
}
return array('html' => $html, 'javascript' => $js);
$renderedform = array('html' => $html, 'javascript' => $js);
return $renderedform;
}
public function commit() {
......
......@@ -80,6 +80,47 @@ function ViewManager() {
// Now we're done, remove the loading message and display the page
removeElement('views-loading');
showElement(self.bottomPane);
// If there is a block already in configure mode, make it wider, and get the normal content
var configblockcontent = getFirstElementByTagAndClassName('div', 'configure');
if (configblockcontent) {
var blockinstance = getFirstParentByTagAndClassName(configblockcontent, 'div', 'blockinstance');
var blockinstanceId = blockinstance.id.substr(blockinstance.id.lastIndexOf('_') + 1);
var button = getFirstElementByTagAndClassName('input', 'configurebutton', blockinstance);
setNodeAttribute(button, 'disabled', 'disabled');
var configform = configblockcontent.innerHTML;
// Put a loading message in place while the content downloads
insertSiblingNodesBefore(configblockcontent, DIV({'id':'block-loading'}, IMG({'src': config.theme['images/loading.gif']}), ' ', get_string('loading')));
hideElement(configblockcontent);
sendjsonrequest('blockcontentediting.json.php', {'id':blockinstanceId}, 'POST', function(data) {
showElement(configblockcontent);
self.currentConfigureData = {
'contentdiv': configblockcontent,
'oldcontent': data.data,
'button' : button
};
removeElement($('block-loading'));
self.growBlock(blockinstance);
// Make the cancel button be supersmart
var cancelButton = $('cancel_cb_' + blockinstanceId + '_action_configureblockinstance_id_' + blockinstanceId);
connect(cancelButton, 'onclick', function(e) {
e.stop();
configblockcontent.innerHTML = data.data;
self.currentConfigureData = null;
removeNodeAttribute(button, 'disabled');
self.shrinkBlock(blockinstance);
});
}, function() {
removeElement($('block-loading'));
showElement(configblockcontent);
self.growBlock(blockinstance);
});
}
}
/**
......@@ -256,53 +297,110 @@ function ViewManager() {
this.rewriteConfigureButton = function(button) {
connect(button, 'onclick', function(e) {
e.stop();
setNodeAttribute(button, 'disabled', 'disabled');
self.getConfigureForm(getFirstParentByTagAndClassName(button, 'div', 'blockinstance'));
});
}
// If there is a configuration form open, close it. This is because
// each one shares the same form tag - the one for the entire form.
// We might be able to support having more than one form open at
// any one time, as long as we can detect precisely which form was
// submitted
if (self.currentConfigureData) {
self.currentConfigureData['contentdiv'].innerHTML = self.currentConfigureData['oldcontent'];
removeNodeAttribute(self.currentConfigureData['button'], 'disabled');
self.currentConfigureData = null;
}
var pd = {'id': $('viewid').value, 'change': 1};
pd[getNodeAttribute(e.src(), 'name')] = 1;
this.getConfigureForm = function(blockinstance) {
var button = getFirstElementByTagAndClassName('input', 'configurebutton', blockinstance);
setNodeAttribute(button, 'disabled', 'disabled');
// If there is a configuration form open, close it. This is because
// each one shares the same form tag - the one for the entire form.
// We might be able to support having more than one form open at
// any one time, as long as we can detect precisely which form was
// submitted
if (self.currentConfigureData) {
self.currentConfigureData['contentdiv'].innerHTML = self.currentConfigureData['oldcontent'];
removeNodeAttribute(self.currentConfigureData['button'], 'disabled');
self.shrinkBlock(getFirstParentByTagAndClassName(self.currentConfigureData['contentdiv'], 'div', 'blockinstance'));
self.currentConfigureData = null;
}
var blockinstance = getFirstParentByTagAndClassName(button, 'div', 'blockinstance');
var blockinstanceId = blockinstance.id.substr(blockinstance.id.lastIndexOf('_') + 1);
var contentDiv = getFirstElementByTagAndClassName('div', 'blockinstance-content', blockinstance);
var oldContent = contentDiv.innerHTML;
var blockinstanceId = blockinstance.id.substr(blockinstance.id.lastIndexOf('_') + 1);
var contentDiv = getFirstElementByTagAndClassName('div', 'blockinstance-content', blockinstance);
// Put a loading message in place while the form downloads
replaceChildNodes(contentDiv, IMG({'src': config.theme['images/loading.gif']}), ' ', get_string('loading'));
var pd = {'id': $('viewid').value, 'change': 1};
pd[getNodeAttribute(button, 'name')] = 1;
sendjsonrequest('blocks.json.php', pd, 'POST', function(data) {
self.currentConfigureData = {
'contentdiv': contentDiv,
'oldcontent': oldContent,
'button' : button
};
contentDiv.innerHTML = data.data['html'];
eval(data.data.javascript);
$('action-dummy').name = getNodeAttribute(e.src(), 'name');
var oldContent = contentDiv.innerHTML;
// Make the cancel button be supersmart
var cancelButton = $('cancel_cb_' + blockinstanceId + '_action_configureblockinstance_id_' + blockinstanceId);
connect(cancelButton, 'onclick', function(e) {
e.stop();
contentDiv.innerHTML = oldContent;
self.currentConfigureData = null;
removeNodeAttribute(button, 'disabled');
});
// Put a loading message in place while the form downloads
replaceChildNodes(contentDiv, IMG({'src': config.theme['images/loading.gif']}), ' ', get_string('loading'));
}, function() {
sendjsonrequest('blocks.json.php', pd, 'POST', function(data) {
self.currentConfigureData = {
'contentdiv': contentDiv,
'oldcontent': oldContent,
'button' : button
};
self.growBlock(blockinstance);
contentDiv.innerHTML = data.data['html'];
eval(data.data.javascript);
$('action-dummy').name = getNodeAttribute(button, 'name');
// Make the cancel button be supersmart
var cancelButton = $('cancel_cb_' + blockinstanceId + '_action_configureblockinstance_id_' + blockinstanceId);
connect(cancelButton, 'onclick', function(e) {
e.stop();
contentDiv.innerHTML = oldContent;
self.currentConfigureData = null;
removeNodeAttribute(button, 'disabled');
self.shrinkBlock(blockinstance);
});
}, function() {
removeNodeAttribute(button, 'disabled');
});
}
this.growBlock = function(blockinstance) {
var width = getElementDimensions(blockinstance).w;
var left = getElementPosition(blockinstance).x;
hideElement(blockinstance);
var newwidth = 500;
var blockheader = getFirstElementByTagAndClassName('div', 'blockinstance-header', blockinstance);
var blockcontrols = getFirstElementByTagAndClassName('div', 'blockinstance-controls', blockinstance);
hideElement(blockheader);
insertSiblingNodesAfter(blockheader, DIV({'id':'blockconfig-header'}, scrapeText(blockheader) + ': ' + get_string('Configure')));
setStyle(blockinstance, {
'border': '2px solid #a0a0a0',
'z-index': 1,
'width': newwidth + 'px'
});
// Move the block to the left to keep it above the old block
var newleft = (width - newwidth) / 2;
if (left + newleft < 0) {
newleft = 0;
} else if (left + newwidth > getViewportDimensions().w) {
newleft = width - newwidth;
}
setStyle(blockinstance, {'left': newleft + 'px'});
showElement(blockinstance);
keepElementInViewport(blockinstance);
}
this.shrinkBlock = function(blockinstance) {
hideElement(blockinstance);
setStyle(blockinstance, {
'left': 0,
'width': 'auto',
'border': 0,
'z-index': 0
});
var blockheader = getFirstElementByTagAndClassName('div', 'blockinstance-header', blockinstance);
var blockcontrols = getFirstElementByTagAndClassName('div', 'blockinstance-controls', blockinstance);
var configheader = $('blockconfig-header');
if (configheader) {
removeElement(configheader);
}
showElement(blockheader);
showElement(blockinstance);
}
/**
......@@ -860,6 +958,7 @@ function ViewManager() {
if (self.currentConfigureData) {
self.currentConfigureData['contentdiv'].innerHTML = self.currentConfigureData['oldcontent'];
removeNodeAttribute(self.currentConfigureData['button'], 'disabled');
self.shrinkBlock(getFirstParentByTagAndClassName(self.currentConfigureData['contentdiv'], 'div', 'blockinstance'));
self.currentConfigureData = null;
}
self.currentConfigureData = {
......@@ -877,6 +976,9 @@ function ViewManager() {
removeElement(self.blockPlaceholder);
eval(data.data.javascript);
if (configureButton) {
self.growBlock(blockinstance);
}
});
};
......
......@@ -200,6 +200,7 @@ $string['moveblockleft'] = 'Move this block left';
$string['moveblockdown'] = 'Move this block down';
$string['moveblockup'] = 'Move this block up';
$string['moveblockright'] = 'Move this block right';
$string['Configure'] = 'Configure';
$string['configureblock'] = 'Configure this block';
$string['removeblock'] = 'Remove this block';
$string['blocktitle'] = 'Block Title';
......
......@@ -603,7 +603,7 @@ class View {
default:
throw new InvalidArgumentException(get_string('noviewcontrolaction', 'error', $action));
}
$message = '';
$success = false;
try {
......@@ -790,9 +790,13 @@ class View {
}
$blockcontent = '';
foreach($data['blockinstances'] as $blockinstance) {
$result = $blockinstance->$renderfunction($blockinstance->get('id') == $this->blockinstance_currently_being_configured);
$configure = ($blockinstance->get('id') == $this->blockinstance_currently_being_configured);
$result = $blockinstance->$renderfunction($configure, false, $jsconfig);
if ($editing) {
$blockcontent .= $result['html'];
if ($configure) {
$blockcontent .= '<script type="text/javascript">' . $result['javascript'] . '</script>';
}
// NOTE: build_column is always called in the context of column
// operations, so the javascript returned, which is currently
// for configuring block instances only, is not necessary
......
......@@ -539,6 +539,7 @@ function jsstrings() {
'view' => array(
'confirmdeleteblockinstance',
'blocksinstructionajax',
'Configure',
),
),
'adminusersearch' => array(
......
......@@ -1941,6 +1941,10 @@ span.viewicon {
.blockinstance-content .maharatable th {
text-align: left !important;
}
#blockconfig-header {
font-weight: bold;
padding: 5px 5px 0;
}
#feedback th,
#objection th {
padding: 2px 10px;
......
......@@ -10,7 +10,7 @@
{if $configurable} <input type="image" src="{theme_path location=images/configure-block.png}" class="submit configurebutton" name="action_configureblockinstance_id_{$id}" alt="&bull;" title="{str tag='configureblock' section='view'}">{/if}
<input type="image" src="{theme_path location=images/remove-block.png}" class="submit deletebutton" name="action_removeblockinstance_id_{$id}" alt="X" title="{str tag='removeblock' section='view'}">
</div>
<div class="blockinstance-content">
<div class="blockinstance-content{if $configure} configure{/if}">
{$content}
</div>
</div>
......
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2008 Catalyst IT Ltd (http://www.catalyst.net.nz)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package mahara
* @subpackage core
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2008 Catalyst IT Ltd http://catalyst.net.nz
*
*/
define('INTERNAL', 1);
define('JSON', 1);
require(dirname(dirname(__FILE__)) . '/init.php');
require_once(get_config('docroot') . 'blocktype/lib.php');
$bi = new BlockInstance(param_integer('id'));
safe_require('blocktype', $bi->get('blocktype'));
$content = call_static_method(generate_class_name('blocktype', $bi->get('blocktype')), 'render_instance', $bi, true);
json_reply(false, array('message' => false, 'data' => $content));
?>
......@@ -80,6 +80,17 @@ if ($new && isset($_POST['cancel'])) {
redirect(get_config('wwwroot') . 'view/');
}
// If a block was configured & submitted, build the form now so it can
// be processed without having to render the other blocks.
if ($blockid = param_integer('blockconfig', 0)) {
// However, if removing a newly placed block, let it fall through to process_changes
if (!isset($_POST['cancel_action_configureblockinstance_id_' . $blockid]) || !param_integer('removeoncancel', 0)) {
require_once(get_config('docroot') . 'blocktype/lib.php');
$bi = new BlockInstance($blockid);
$bi->build_configure_form();
}
}
View::set_nav($group, $institution, ($view->get('type') == 'profile'));
if ($view->get('type') == 'profile') {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment