2016-06-10 4 views
0

모든 노드가 확인란 인 dijit.Tree 객체를 만들었습니다. 부모 노드를 선택/선택 취소하면 자식 노드가 선택/선택 해제됩니다. 자식 중 하나가 선택 취소되면 부모는 선택 취소됩니다. 모든 자녀를 선택하면 부모가 선택됩니다. 완벽하게 잘 작동합니다.
그러나 키보드 액세스가 필요합니다. 트리 노드로 이동하여 스페이스 바 또는 Enter를 누르면 아무 일도 일어나지 않습니다.체크 박스가있는 Dojo dijit 트리에 키보드로 액세스 할 수 없습니다.

tabindex 및 aria-role을 (프로그래밍 방식으로) 확인란에 추가하려고 시도했지만 작동하지 않았습니다. 에 관해서는 http://jsfiddle.net/pdabade/pyz9Lcpv/65/

require([ 
"dojo/_base/window", "dojo/store/Memory", 
"dijit/tree/ObjectStoreModel", 
"dijit/Tree", "dijit/form/CheckBox", "dojo/dom", 
"dojo/domReady!" 
], function(win, Memory, ObjectStoreModel, Tree, checkBox, dom) { 

// Create test store, adding the getChildren() method required by  ObjectStoreModel 
var myStore = new Memory({ 
data: [{ 
    id: 'allDocuments', 
    name: 'All Documents' 
}, { 
    id: 'inboxDocuments', 
    name: 'Inbox Documents', 
    parent: 'allDocuments' 
}, { 
    id: 'outboxDocuments', 
    name: 'Outbox Documents', 
    parent: 'allDocuments' 
}, { 
    id: 'draftDocuments', 
    name: 'Draft Documents', 
    parent: 'allDocuments' 
}, { 
    id: 'finalDocuments', 
    name: 'Final Documents', 
    parent: 'allDocuments' 
}], 
getChildren: function(object) { 
    return this.query({ 
    parent: object.id 
    }); 
} 
}); 
// Create the model 
var myModel = new ObjectStoreModel({ 
store: myStore, 
query: { 
    id: 'allDocuments' 
} 
}); 

// Create the Tree. 
var tree = new Tree({ 
model: myModel, 

autoExpand: true, 
getIconClass: function(item, opened) { 
    // console.log('tree getIconClass', item, opened); 
    // console.log('tree item type', item.id); 
}, 

onClick: function(item, node, event) { 
    //node._iconClass= "dijitFolderClosed"; 
    //node.iconNode.className = "dijitFolderClosed"; 
    var _this = this; 
    console.log(item.id); 
    var id = node.domNode.id, 
    isNodeSelected = node.checkBox.get('checked'); 

    dojo.query('#' + id + ' .dijitCheckBox').forEach(function(node) { 
    dijit.getEnclosingWidget(node).set('checked', isNodeSelected); 
    }); 

    if (item.id != 'allComments') { 
    if (!isNodeSelected) { 
     var parent = node.tree.rootNode; // parent node id 
     //console.log(node); 
     parent.checkBox.set('checked', false); 
    } else { 
     var parent = node.tree.rootNode; 
     var selected = true; 
     var i = 0; 
     dojo.query('#' + parent.id + '.dijitCheckBox').forEach(function(node) { 
     if (i > 0) { 
      var isSet = dijit.getEnclosingWidget(node).get('checked'); 
      console.log(isSet); 
      if (isSet == false) { 
      selected = false; 
      } 
     } 
     i++; 
     }); 
     if (selected) { 
     parent.checkBox.set('checked', true); 
     } 
    } 

    } 
    //console.log(node.id); 
}, 
_createTreeNode: function(args) { 
    var tnode = new dijit._TreeNode(args); 
    tnode.labelNode.innerHTML = args.label; 
    console.log(args); 
    var cb = new dijit.form.CheckBox({ 
    "aria-checked": "false", 
    "aria-describedby": args.label 
    }); 
    cb.placeAt(tnode.labelNode, "first"); 
    tnode.checkBox = cb; 


    return tnode; 
} 

}); 
tree.placeAt(contentHere); 
tree.startup(); 
tree.checkedItems(); 
//tree.expandAll(); 


}); 

} 

모든 아이디어는 어떻게 키보드 액세스 할 수 있도록 - 여기

는 바이올린입니까?

감사합니다!

답변

0

dijit/Tree 소스를 살펴보면 _onNodePress() 함수를 키보드 이벤트의 이벤트 핸들러로 설정한다는 것을 알 수 있습니다. 그것을 재정의 (또는 그 뒤에 애스펙트를 추가)하고 수동으로 원하는 키를 처리 할 수 ​​있습니다. 공간과 Enter 키를 구체적으로 확인하는 데 사용할 수있는 트리 노드와 이벤트 객체를 인수로 취합니다.

내가 예와 jsfiddle을 포크 : https://jsfiddle.net/pgianna/jjore5sm/1/

_onNodePress: function(/*TreeNode*/ nodeWidget, /*Event*/ e){ 
    // This is the original implementation of _onNodePress: 
    this.focusNode(nodeWidget); 

    // This requires "dojo/keys" 
    if (e.keyCode == keys.ENTER || e.keyCode == keys.SPACE) 
    { 
     var cb = nodeWidget.checkBox; 
     cb.set('checked', !cb.get('checked')); 
    } 
} 
+0

정확하게 필요한 것! 정말 고맙습니다. – pdabade

+0

dijit/Tree 소스에 대한 링크를 제공 할 수 있습니까? – pdabade

+0

https://github.com/dojo/dijit/blob/master/Tree.js http://download.dojotoolkit.org/에서 전체 소스를 다운로드 할 수도 있습니다. – pgianna

0

role, aria-checked 또는 tabindex을 확인란에 추가하지 마십시오. 그것들은 이미 통제 장치에 내장되어 있으므로 도로를 무너 뜨릴 위험이 있습니다. 당신은 또한 role="presentation"을 없애 버릴 수 있습니다. 이는 사실상 프리젠 테이션 인 <div><span>입니다. 마지막으로, 각 텍스트 블록에 <label>이 필요하며이 텍스트 블록에 액세스하려면이 확인란을 선택하십시오. aria-describedby이 잘못되어 어쨌든 덜 좋은 옵션입니다.

나는 오류를 얻고있다 : Uncaught TypeError: tree.checkedItems is not a function (라인 159)

또한 큰 집중 관리 문제가 있습니다. CSS에 다음을 입력하면 각 단일 컨트롤에 대해 Tab 키가 두 번 눌러야합니다 (집중된 확인란으로 시작하는 경우). :focus {outline:2px solid #f00;}

클릭 수를 훔치는 요소가있는 것 같습니다 올바른 요소가 선택되지 않습니다. 클래스 dijit dijitReset dijitInline dijitCheckBox<span>tabindex-1에서 0으로 전환하고 탭 순서대로 또는 밖으로 이동하여 포커스를 도용합니다. 그것은 요인 일 수 있습니다.

스크립트 오류를 ​​해결하고 포커스 관리를 살펴 보는 것이 좋습니다.

+0

이 http://jsfiddle.net/pdabade/pyz9Lcpv/65/에 오류가 수정되었습니다. 나는 당신이 '각 단일 컨트롤에 대해 Tab 키를 두 번 누르면'그것에 대해 말한 것을 이해했습니다. 그러나 초점 관리의이 문제를 어떻게 해결할 수 있습니까? – pdabade

0

dijit을 사용하면 백그라운드에서 진행되는 모든 종류의 작업이 사용자의 제어에서 벗어날 수 있습니다. aardrian이 말했듯이, 많은 역할 = 프리젠 테이션이 있고 < 입력 유형 = 'checkbox>의 모든 아리아 태그는 불필요합니다. dijit은 아마 (잘못) 모든 것을 설정합니다. < 입력 유형 = '확인란'은 이미 선택 항목을 처리하며 그 역할은 본질적으로 선택란입니다. 이러한 아리아 속성은 div/span 태그에서 맞춤 체크 박스를 만들 때 사용됩니다.

코드에 네이티브 체크 박스가 있지만 불투명도가 0으로 설정되어있어 보이지 않습니다. dijit은 아마 체크 박스 이벤트를 위해 그것을 사용하고있을 것이다.

기본 체크 박스에는 data-dojo-attach-event = "ondijitclick : _onClick"도 있습니다. 그게 무슨 뜻인지 모르겠지만 이벤트 이름에서 "클릭"할 때마다 키보드로 작동하지 않을 수도 있습니다.

나는이 예제를 https://dojotoolkit.org/reference-guide/1.10/dijit/form/CheckBox.html에서 시도했으며 키보드로 작동한다. 히트 공간이 체크 박스를 체크하고 선택을 해제합니다.체크 박스에 초점을 맞출 수 있는지 여부는 다른 문제입니다.

확인란을 선택하면 상위 분기에 aria-checked = "mixed"를 사용하면 좋을 것입니다. 하위 체크 박스가있을 때마다 일부는 선택되고 일부는 선택되지 않은 경우, 부모 체크 박스에 "혼합"을 사용하여 여러 선택 항목을 나타낼 수 있습니다. dijit이 지원하는지 확실하지 않습니다.

+0

정상적인 dijit/form/CheckBox를 구현했으며 키보드로 잘 작동합니다. 문제는 dijit/트리 내에서 checkbox를 사용할 때입니다. – pdabade