Commit ed8785f1 authored by Jono Mingard's avatar Jono Mingard
Browse files

Allow blocks to be added in the page editor using the keyboard (Bug #1262933)



Adds a dialog for adding and moving blocks, activated when the user pressed Space/Enter
with a blocktype focused, or activates the new "Move block" button. The user can select
which cell (row/column) to put the block in and where in the cell to place the new
block.
The "Move block" button is hidden unless it gains keyboard focus meaning the interface isn't
any more cluttered for mouse users.

Change-Id: I9a3ced66c0947756f1f80b0dacff82de201c2142
Signed-off-by: default avatarJono Mingard <jonom@catalyst.net.nz>
parent 53cf4606
......@@ -734,6 +734,7 @@ class BlockInstance {
$smarty->assign('content', $content);
$smarty->assign('javascript', defined('JSON'));
$smarty->assign('strnotitle', get_string('notitle', 'view'));
$smarty->assign('strmovetitletext', $title == '' ? get_string('movethisblock', 'view') : get_string('moveblock', 'view', "'$title'"));
$smarty->assign('strconfigtitletext', $title == '' ? get_string('configurethisblock', 'view') : get_string('configureblock', 'view', "'$title'"));
$smarty->assign('strremovetitletext', $title == '' ? get_string('removethisblock', 'view') : get_string('removeblock', 'view', "'$title'"));
......
This diff is collapsed.
......@@ -230,6 +230,13 @@ $string['blockconfigurationrenderingerror'] = 'Configuration failed because the
$string['blocksintructionnoajax'] = 'Select a block and choose where to add it to your page. You can position a block using the arrow buttons in its titlebar.';
$string['blocksinstructionajax'] = 'This area shows a preview of what your page will look like.<br>Drag blocks below this line to add them to your page layout. You can drag blocks around your page layout to position them.';
$string['addblock'] = 'Add block: %s';
$string['blockcell'] = 'Cell';
$string['cellposition'] = 'Row %s Column %s';
$string['blockorder'] = 'Position';
$string['blockordertop'] = 'Top of column';
$string['blockorderafter'] = 'After "%s"';
$string['addnewblockhere'] = 'Add new block here';
$string['add'] = 'Add';
$string['addcolumn'] = 'Add column';
......@@ -243,9 +250,12 @@ $string['moveblockup'] = "Move %s block up";
$string['movethisblockup'] = "Move this block up";
$string['moveblockright'] = "Move %s block right";
$string['movethisblockright'] = "Move this block right";
$string['moveblock'] = 'Move %s block';
$string['movethisblock'] = 'Move this block';
$string['Configure'] = 'Configure';
$string['configureblock'] = 'Configure %s block';
$string['configurethisblock'] = 'Configure this block';
$string['closeconfiguration'] = 'Close configuration';
$string['removeblock'] = 'Remove %s block';
$string['removethisblock'] = 'Remove this block';
$string['blocktitle'] = 'Block title';
......
......@@ -56,10 +56,15 @@ ul.colnav li.selected span {
border: 1px solid #B3B3B3;
}
#block-category-general:hover,
#block-category-general:focus,
#block-category-internal:hover,
#block-category-internal:focus,
#block-category-fileimagevideo:hover,
#block-category-fileimagevideo:focus,
#block-category-external:hover,
#block-category-blog:hover {
#block-category-external:focus,
#block-category-blog:hover,
#block-category-blog:focus {
background-color: #FFFFFF;
}
/* container around blocktypes under each category */
......
......@@ -74,9 +74,20 @@
{if $block.javascript}<script type="text/javascript">{$block.javascript|safe}</script>{/if}
{/if}
</div>
<div id="addblock" class="blockinstance cb configure hidden" role="dialog" aria-labelledby="addblock-heading" tabindex="-1">
<div class="blockinstance-controls">
<input type="image" src="{theme_url filename=images/btn_close.png}" class="deletebutton" name="action_removeblockinstance_id_{$id}" alt="{str tag=Close}">
</div>
<div class="blockinstance-header">
<h2 id="addblock-heading" class="title"></h2>
</div>
<div class="blockinstance-content">
{$addform|safe}
</div>
</div>
<div id="configureblock" class="blockinstance cb configure hidden" role="dialog">
<div class="blockinstance-controls">
<input type="image" src="{theme_url filename=images/btn_close.png}" class="deletebutton" name="close_configuration" alt="{str tag=Close}">
<input type="image" src="{theme_url filename=images/btn_close.png}" class="deletebutton" name="close_configuration" alt="{str tag=closeconfiguration section=view}">
</div>
<div class="blockinstance-header">
</div>
......
......@@ -3,11 +3,12 @@
{foreach from=$movecontrols item=item}
<input type="image" src="{theme_url filename='images/btn_move`$item.dir`.png'}" class="movebutton" name="action_moveblockinstance_id_{$id}_row_{$row}_column_{$item.column}_order_{$item.order}" alt="{$item.arrow}" title="{$item.title}">
{/foreach}
<input type="image" src="{theme_url filename=images/btn_move.png}" class="keyboardmovebutton nojs-hidden-inline" name="action_moveblockinstance_id_{$id}" alt="{$strmovetitletext}">
{if $retractable && !$configure}
<img src="{theme_url filename=images/retractable.png}" alt="{str tag='retractable' section='view'}" title="{str tag='retractable' section='view'}" class="retractablebtn">
{/if}
{if $configurable && !$configure} <input type="image" src="{theme_url filename=images/btn_configure.png}" class="configurebutton" name="action_configureblockinstance_id_{$id}" alt="{str tag=Configure section=view}" title="{$strconfigtitletext}">{/if}
{if $configure}<input type="image" src="{theme_url filename=images/btn_close.png}" class="deletebutton" name="action_removeblockinstance_id_{$id}" alt="{str tag=Close}" title="{$strremovetitletext}">{else}<input type="image" src="{theme_url filename=images/btn_deleteremove.png}" class="deletebutton" name="action_removeblockinstance_id_{$id}" alt="{str tag=delete}" title="{$strremovetitletext}">{/if}
{if $configurable && !$configure} <input type="image" src="{theme_url filename=images/btn_configure.png}" class="configurebutton" name="action_configureblockinstance_id_{$id}" alt="{$strconfigtitletext}">{/if}
{if $configure}<input type="image" src="{theme_url filename=images/btn_close.png}" class="deletebutton" name="action_removeblockinstance_id_{$id}" alt="{str tag=Close}">{else}<input type="image" src="{theme_url filename=images/btn_deleteremove.png}" class="deletebutton" name="action_removeblockinstance_id_{$id}" alt="{$strremovetitletext}">{/if}
</div>
<div class="blockinstance-header">
<h2 class="title">{if $configure}{$configtitle}: {str tag=Configure section=view}{else}{$title|default:"[$strnotitle]"}{/if}</h2>
......
......@@ -3,8 +3,11 @@
{foreach from=$blocktypes item=blocktype}
{* TODO at this point we have now $blocktype.singleonly *}
<div class="blocktype">
<input type="radio" class="blocktype-radio" name="blocktype" value="{$blocktype.name}">
<img src="{$blocktype.thumbnail_path}" title="{$blocktype.description}" alt="{$blocktype.description}" width="24" height="24"><span class="blocktypetitle">{$blocktype.title}</span>
<a class="blocktypelink" href="#">
<input type="radio" id="blocktype-list-radio-{$blocktype.name}" class="blocktype-radio" name="blocktype" value="{$blocktype.name}">
<img src="{$blocktype.thumbnail_path}" title="{$blocktype.description}" alt="{$blocktype.description}" width="24" height="24">
<label for="blocktype-list-radio-{$blocktype.name}" class="blocktypetitle">{$blocktype.title}</label>
</a>
</div>
{/foreach}
</div>
......
......@@ -4,12 +4,18 @@
<div id="blocktype-common" class="blocktype-list">
{* If you are wanting to have some options always showing place the code here. *}
<div class="blocktype">
<input type="radio" class="blocktype-radio" name="blocktype" value="textbox">
<img width="24" height="24" title="{str tag=description section=blocktype.internal/textbox}" alt="{str tag=description section=blocktype.internal/textbox}" src="{$WWWROOT}thumb.php?type=blocktype&bt=textbox&ap=internal"><span class="blocktypetitle">{str tag='textbox' section='view'}</span>
<a class="blocktypelink" href="#">
<input type="radio" class="blocktype-radio" id="blocktype-radio-textbox" name="blocktype" value="textbox">
<img width="24" height="24" title="{str tag=description section=blocktype.internal/textbox}" alt="{str tag=description section=blocktype.internal/textbox}" src="{$WWWROOT}thumb.php?type=blocktype&bt=textbox&ap=internal">
<label for="blocktype-radio-textbox" class="blocktypetitle">{str tag='textbox' section='view'}</label>
</a>
</div>
<div class="blocktype lastrow">
<input type="radio" class="blocktype-radio" name="blocktype" value="image">
<img width="24" height="24" title="{str tag=description section=blocktype.file/image}" alt="{str tag=description section=blocktype.file/image}" src="{$WWWROOT}thumb.php?type=blocktype&bt=image&ap=file"><span class="blocktypetitle">{str tag='image' section='view'}</span>
<a class="blocktypelink" href="#">
<input type="radio" id="blocktype-radio-image" class="blocktype-radio" name="blocktype" value="image">
<img width="24" height="24" title="{str tag=description section=blocktype.file/image}" alt="{str tag=description section=blocktype.file/image}" src="{$WWWROOT}thumb.php?type=blocktype&bt=image&ap=file">
<label for="blocktype-radio-image" class="blocktypetitle">{str tag='image' section='view'}</label>
</a>
</div>
</div>
<div id="accordion">
......
......@@ -264,9 +264,17 @@ ul.colnav li.selected span {
.no-js .blocktype img, .withradio .blocktype img {
margin: 0;
}
.blocktype .blocktypelink {
display: block;
color: #474220;
cursor: inherit;
}
.blocktype .blocktypelink:hover, .blocktype .blocktypelink:focus {
text-decoration: none;
}
.blocktypetitle {
margin-left: 4px;
vertical-align: middle;
font-weight: normal;
}
#editcontent-sidebar.collapsed .blocktype .blocktypetitle {
display: none;
......@@ -377,6 +385,25 @@ ul.colnav li.selected span {
.no-js #external {
margin-top: -2px;
}
/* adding blocks */
.cellchooser {
width: 150px;
display: table;
}
.cellchooser label {
display: table-cell;
width: 1%;
border-right: 1px solid white;
border-bottom: 1px solid white;
height: 20px;
background: #555;
}
.cellchooser label.active {
background: #333;
}
.cellchooser label.focused {
outline: 1px dotted;
}
/* theme selector */
#select-theme {
clear: both;
......@@ -538,6 +565,18 @@ input.newblockhere {
cursor: pointer;
margin: 0 0 0 5px;
}
.blockinstance-controls input.keyboardmovebutton {
opacity: 0;
width: 1px;
height: 1px;
clip: rect(0px, 0px, 0px, 0px);
}
.blockinstance-controls input.keyboardmovebutton:focus {
opacity: 1;
width: auto;
height: auto;
clip: none;
}
/* retractable blocks */
img.retractablebtn {
margin: 0 0 0 5px;
......
......@@ -146,7 +146,44 @@ $inlinejs = "addLoadEvent( function() {\n" . join("\n", $blocktype_js['initjs'])
require_once('pieforms/pieform/elements/select.php');
$inlinejs .= pieform_element_select_get_inlinejs();
$smarty = smarty($javascript, $stylesheets, false, $extraconfig);
// The form for adding blocks via the keyboard
$addform = pieform(array(
'name' => 'addblock',
'method' => 'post',
'jsform' => true,
'renderer' => 'table',
'autofocus' => false,
'elements' => array(
'cellchooser' => array(
'type' => 'radio',
'title' => get_string('blockcell', 'view'),
'rowsize' => 2,
'separator' => '<br />',
'options' => array('R1C1', 'R1C2', 'R2C1'),
),
'position' => array(
'type' => 'select',
'title' => get_string('blockorder', 'view'),
'options' => array('Top', 'After 1', 'After 2'),
),
'submit' => array(
'type' => 'submitcancel',
'value' => array(get_string('save'), get_string('cancel')),
),
),
));
$smarty = smarty($javascript, $stylesheets, array(
'view' => array(
'addblock',
'cellposition',
'blockordertop',
'blockorderafter',
'moveblock',
),
), $extraconfig);
$smarty->assign('addform', $addform);
// The list of categories for the tabbed interface
$smarty->assign('category_list', $view->build_category_list($category, $new));
......
Supports Markdown
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