-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds keyboard navigation extension and example page
- Loading branch information
Showing
2 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<!DOCTYPE html> | ||
<HTML> | ||
<HEAD> | ||
<TITLE> ZTREE DEMO - Keyboard navigation </TITLE> | ||
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> | ||
<link rel="stylesheet" href="../../../css/demo.css" type="text/css"> | ||
<link rel="stylesheet" href="../../../css/zTreeStyle/zTreeStyle.css" type="text/css"> | ||
<script type="text/javascript" src="../../../js/jquery-1.4.4.min.js"></script> | ||
<script type="text/javascript" src="../../js/keyboard_navigation.js"></script> | ||
<script type="text/javascript" src="../../../js/jquery.ztree.core.js"></script> | ||
<script type="text/javascript" src="../../../js/jquery.ztree.exedit.js"></script> | ||
<SCRIPT type="text/javascript"> | ||
|
||
var setting = { | ||
data: { | ||
simpleData: { | ||
enable: true | ||
} | ||
} | ||
}; | ||
|
||
var zNodes =[ | ||
{ id:1, pId:0, name:"Custom Icon 01", open:true, iconSkin:"pIcon01"}, | ||
{ id:11, pId:1, name:"leaf node 01", iconSkin:"icon01"}, | ||
{ id:12, pId:1, name:"leaf node 02", iconSkin:"icon02"}, | ||
{ id:13, pId:1, name:"parent node 03", iconSkin:"pIcon01"}, | ||
{ id:131, pId:13, name:"leaf node 01", iconSkin:"icon01"}, | ||
{ id:132, pId:13, name:"leaf node 02", iconSkin:"icon02"}, | ||
{ id:133, pId:13, name:"leaf node 03", iconSkin:"icon03"}, | ||
{ id:2, pId:0, name:"Custom Icon 02", open:true, iconSkin:"pIcon02"}, | ||
{ id:21, pId:2, name:"leaf node 01", iconSkin:"icon04"}, | ||
{ id:22, pId:2, name:"leaf node 02", iconSkin:"icon05"}, | ||
{ id:23, pId:2, name:"leaf node 03", iconSkin:"icon06"}, | ||
{ id:3, pId:0, name:"no Custom Icon", open:true }, | ||
{ id:31, pId:3, name:"leaf node 01"}, | ||
{ id:32, pId:3, name:"leaf node 02"}, | ||
{ id:33, pId:3, name:"leaf node 03"} | ||
]; | ||
|
||
var $ = jQuery; | ||
$(document).ready(function() | ||
{ | ||
var element = "#treeDemo"; | ||
var zTree = $.fn.zTree.init($(element), setting, zNodes); | ||
// Initialize keyboard navigation | ||
$.fn.zTreeKeyboardNavigation(zTree, element); | ||
}); | ||
|
||
</SCRIPT> | ||
<style type="text/css"> | ||
.ztree li > a | ||
{ | ||
border-left: 1px solid white; | ||
} | ||
|
||
.ztree li > a.curSelectedNode { | ||
border-radius: 3px; | ||
} | ||
|
||
.ztree li span.button.pIcon01_ico_open{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/1_open.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.pIcon01_ico_close{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/1_close.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.pIcon02_ico_open, .ztree li span.button.pIcon02_ico_close{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/2.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.icon01_ico_docu{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/3.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.icon02_ico_docu{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/4.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.icon03_ico_docu{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/5.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.icon04_ico_docu{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/6.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.icon05_ico_docu{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/7.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
.ztree li span.button.icon06_ico_docu{margin-right:2px; background: url(../../../css/zTreeStyle/img/diy/8.png) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} | ||
</style> | ||
</HEAD> | ||
|
||
<BODY> | ||
<h1>Keyboard navigation</h1> | ||
<h6>[ File Path: core/custom_keyboard_navigation.html ]</h6> | ||
<div class="content_wrap"> | ||
<div class="zTreeDemoBackground left"> | ||
<ul id="treeDemo" class="ztree"></ul> | ||
</div> | ||
<div class="right"> | ||
<ul class="info"> | ||
<li class="title"><h2>1. Explanation of setting</h2> | ||
<ul class="list"> | ||
<li>Keyboard navigation does not require special configuration setting.</li> | ||
<li>It does require that the keyboard_navigation.js file is loaded and the function initialized.</li> | ||
</ul> | ||
</li> | ||
<li class="title"><h2>2. Explanation of navigation</h2> | ||
<ul class="list"> | ||
<li>Home: home key (keycode 36) Goes to the first root element is visible</li> | ||
<li>End: end key (keycode 35) Goes to the last leaf node and will expand nodes and scroll the element into view</li> | ||
<li>Down: right cursor key (keycode 39) Goes to the next visible node in the tree following the hierarchy</li> | ||
<li>Next: down cursor key (keycode 40) Goes to the next visible node at the same level</li> | ||
<li>Up: up cursor key (keycode 37) Goes to the prior visible node at the same level</li> | ||
<li>Previous: left cursor key (keycode 38) Goes to the prior visible node following the hierarchy</li> | ||
<li>Toggle: space key (keycode 32) Toggles the expand/collapse state of a parent node</li> | ||
</ul> | ||
</li> | ||
<li class="title"><h2>3.Other explanation</h2> | ||
<ul class="list"> | ||
<li>No other explanation.</li> | ||
</ul> | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
</BODY> | ||
</HTML> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
/* | ||
* JQuery zTree keyboard navigation extension | ||
* zTree v3.5.42 or later | ||
* http://www.xbrlquery.com/ | ||
* | ||
* Copyright (c) 2019 Bill Seddon | ||
* | ||
* Licensed same as jquery - MIT License | ||
* http://www.opensource.org/licenses/mit-license.php | ||
* | ||
* Date: 2020-02-18 | ||
*/ | ||
|
||
( function ($) | ||
{ | ||
/** | ||
* Creates a function that adds keyboard navigation: | ||
* Home: home key (keycode 36) Goes to the first root element is visible | ||
* End: end key (keycode 35) Goes to the last leaf node and will expand nodes and scroll the element into view | ||
* Down: right cursor key (keycode 39) Goes to the next visible node in the tree following the hierarchy | ||
* Next: down cursor key (keycode 40) Goes to the next visible node at the same level | ||
* Up: up cursor key (keycode 37) Goes to the prior visible node at the same level | ||
* Previous: left cursor key (keycode 38) Goes to the prior visible node following the hierarchy | ||
* Toggle: space key (keycode 32) Toggles the expand/collapse state of a parent node | ||
*/ | ||
$.fn.zTreeKeyboardNavigation = function(zTree, element) | ||
{ | ||
var rootNodes = zTree.getNodes(); | ||
if ( ! rootNodes ) return; | ||
|
||
var focusSelectedNode = function() | ||
{ | ||
if( ( selectedNodes = zTree.getSelectedNodes() ) && selectedNodes ) | ||
{ | ||
$("#" + selectedNodes[0].tId ).focus(); | ||
} | ||
} | ||
|
||
$(element).bind( 'keydown', function( e ) | ||
{ | ||
var selectedNodes = zTree.getSelectedNodes(); | ||
var selectedNode = selectedNodes ? selectedNodes[0] : null; | ||
|
||
var processSpace = function() | ||
{ | ||
// If there are no nodes or the selected node is not a parent, get out | ||
if ( selectedNode && selectedNode.isParent ) | ||
{ | ||
// Toggle the node | ||
zTree.expandNode( selectedNode, null, null, null, false ); | ||
} | ||
} | ||
|
||
var processHome = function() | ||
{ | ||
zTree.selectNode( rootNodes[0], false, true ); | ||
} | ||
|
||
var processEnd = function() | ||
{ | ||
var nodes = zTree.transformToArray(rootNodes); | ||
// Select the last node | ||
zTree.selectNode( nodes[ nodes.length - 1 ] ); | ||
} | ||
|
||
var processUp = function() | ||
{ | ||
var priorNode; | ||
if ( selectedNode ) | ||
{ | ||
priorNode = selectedNode.getPreNode(); | ||
if ( ! priorNode ) return; | ||
} | ||
else | ||
{ | ||
processEnd(); | ||
} | ||
|
||
if ( ! priorNode ) return; | ||
|
||
zTree.selectNode( priorNode ); | ||
} | ||
|
||
var processDown = function() | ||
{ | ||
var nextNode; | ||
if ( selectedNode ) | ||
{ | ||
nextNode = selectedNode.getNextNode(); | ||
if ( ! nextNode ) return; | ||
} | ||
else | ||
{ | ||
processHome(); | ||
} | ||
|
||
if ( ! nextNode ) return; | ||
|
||
zTree.selectNode( nextNode ); | ||
} | ||
|
||
var processOut = function() | ||
{ | ||
if ( ! selectedNode ) return; | ||
|
||
var parentNode = selectedNode.getParentNode(); | ||
var priorNode = selectedNode.getPreNode(); | ||
if ( ! parentNode && ! priorNode ) return; // Must have been the root node | ||
|
||
if ( priorNode ) | ||
{ | ||
if ( priorNode.isParent ) | ||
{ | ||
// There is a prior node, now the the question is where is the last open node? | ||
while ( priorNode ) | ||
{ | ||
if ( ! priorNode.isParent || ! priorNode.open || ! priorNode.children ) break; | ||
|
||
priorNode = priorNode.children[ priorNode.children.length -1 ]; | ||
} | ||
|
||
zTree.selectNode( priorNode ); | ||
return; | ||
} | ||
else | ||
{ | ||
zTree.selectNode( priorNode ); | ||
return; | ||
} | ||
} | ||
|
||
// Find the parent node with a valid prior sibling | ||
if ( parentNode ) | ||
{ | ||
// This call should be silent otherwise (in my view a bug in) | ||
// selectNode causes the root node to blur | ||
zTree.selectNode( parentNode, false, true ); | ||
} | ||
} | ||
|
||
var processIn = function() | ||
{ | ||
if ( ! selectedNode ) return; | ||
|
||
if ( selectedNode.isParent && selectedNode.open && selectedNode.children ) | ||
{ | ||
zTree.selectNode( selectedNode.children[0] ); | ||
return; | ||
} | ||
|
||
var nextNode = selectedNode.getNextNode(); | ||
if ( nextNode ) | ||
{ | ||
zTree.selectNode( nextNode ); | ||
} | ||
else | ||
{ | ||
// Cannot be root if there is a selected node that is not a parent | ||
var node = selectedNode; | ||
// Find the parent node with a valid next sibling | ||
while( node = node.getParentNode() ) | ||
{ | ||
var nextNode = node.getNextNode(); | ||
if ( nextNode ) | ||
{ | ||
zTree.selectNode( nextNode ); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if ( [32,33,34,35,36,37,38,39,40].includes(e.keyCode) ) | ||
{ | ||
// console.log('before'); | ||
// console.log(document.activeElement); | ||
|
||
switch ( e.keyCode ) | ||
{ | ||
case 32: /* Toggle parent nodes */ | ||
processSpace(); | ||
return; | ||
|
||
case 36: /* Home - go to the root node */ | ||
processHome(); | ||
break; | ||
|
||
case 35: /* End - go to the last node */ | ||
processEnd(); | ||
break; | ||
|
||
case 33: /* PageUp */ | ||
// Do nothing | ||
break; | ||
|
||
case 34: /* PageDown */ | ||
// Do nothing | ||
break; | ||
|
||
case 37: /* Left */ | ||
processOut(); | ||
break; | ||
|
||
case 38: /* Up */ | ||
processUp(); | ||
break; | ||
|
||
case 39: /* Right */ | ||
processIn(); | ||
break; | ||
|
||
case 40: /* Down */ | ||
processDown(); | ||
break; | ||
|
||
default: | ||
return; | ||
} | ||
} | ||
|
||
// console.log('after'); | ||
// console.log(document.activeElement); | ||
focusSelectedNode(); | ||
} ); | ||
|
||
$(element).trigger({ type : 'keydown', which : 36, keyCode: 36 }); | ||
focusSelectedNode(); | ||
} | ||
|
||
} )(jQuery); |