1 | define([ |
---|
2 | "dojo/_base/declare", // declare |
---|
3 | "dojo/dom-class", // domClass.add domClass.remove |
---|
4 | "dojo/dom-style", // domStyle.get |
---|
5 | "dojo/keys", // keys.DOWN_ARROW keys.PAGE_DOWN keys.PAGE_UP keys.UP_ARROW |
---|
6 | "../_WidgetBase", |
---|
7 | "../_TemplatedMixin", |
---|
8 | "./_ComboBoxMenuMixin", |
---|
9 | "./_ListMouseMixin" |
---|
10 | ], function(declare, domClass, domStyle, keys, |
---|
11 | _WidgetBase, _TemplatedMixin, _ComboBoxMenuMixin, _ListMouseMixin){ |
---|
12 | |
---|
13 | |
---|
14 | // module: |
---|
15 | // dijit/form/_ComboBoxMenu |
---|
16 | |
---|
17 | return declare("dijit.form._ComboBoxMenu",[_WidgetBase, _TemplatedMixin, _ListMouseMixin, _ComboBoxMenuMixin], { |
---|
18 | // summary: |
---|
19 | // Focus-less menu for internal use in `dijit/form/ComboBox` |
---|
20 | // Abstract methods that must be defined externally: |
---|
21 | // |
---|
22 | // - onChange: item was explicitly chosen (mousedown somewhere on the menu and mouseup somewhere on the menu) |
---|
23 | // - onPage: next(1) or previous(-1) button pressed |
---|
24 | // tags: |
---|
25 | // private |
---|
26 | |
---|
27 | // TODO for 2.0 or earlier: stop putting stuff inside this.containerNode. Switch to using this.domNode |
---|
28 | // or a different attach point. See _TemplatedMixin::searchContainerNode. |
---|
29 | templateString: "<div class='dijitReset dijitMenu' data-dojo-attach-point='containerNode' style='overflow: auto; overflow-x: hidden;' role='listbox'>" |
---|
30 | +"<div class='dijitMenuItem dijitMenuPreviousButton' data-dojo-attach-point='previousButton' role='option'></div>" |
---|
31 | +"<div class='dijitMenuItem dijitMenuNextButton' data-dojo-attach-point='nextButton' role='option'></div>" |
---|
32 | +"</div>", |
---|
33 | |
---|
34 | baseClass: "dijitComboBoxMenu", |
---|
35 | |
---|
36 | postCreate: function(){ |
---|
37 | this.inherited(arguments); |
---|
38 | if(!this.isLeftToRight()){ |
---|
39 | domClass.add(this.previousButton, "dijitMenuItemRtl"); |
---|
40 | domClass.add(this.nextButton, "dijitMenuItemRtl"); |
---|
41 | } |
---|
42 | this.containerNode.setAttribute("role","listbox"); |
---|
43 | }, |
---|
44 | |
---|
45 | _createMenuItem: function(){ |
---|
46 | // note: not using domConstruct.create() because need to specify document |
---|
47 | var item = this.ownerDocument.createElement("div"); |
---|
48 | item.className = "dijitReset dijitMenuItem" +(this.isLeftToRight() ? "" : " dijitMenuItemRtl"); |
---|
49 | item.setAttribute("role", "option"); |
---|
50 | return item; |
---|
51 | }, |
---|
52 | |
---|
53 | onHover: function(/*DomNode*/ node){ |
---|
54 | // summary: |
---|
55 | // Add hover CSS |
---|
56 | domClass.add(node, "dijitMenuItemHover"); |
---|
57 | }, |
---|
58 | |
---|
59 | onUnhover: function(/*DomNode*/ node){ |
---|
60 | // summary: |
---|
61 | // Remove hover CSS |
---|
62 | domClass.remove(node, "dijitMenuItemHover"); |
---|
63 | }, |
---|
64 | |
---|
65 | onSelect: function(/*DomNode*/ node){ |
---|
66 | // summary: |
---|
67 | // Add selected CSS |
---|
68 | domClass.add(node, "dijitMenuItemSelected"); |
---|
69 | }, |
---|
70 | |
---|
71 | onDeselect: function(/*DomNode*/ node){ |
---|
72 | // summary: |
---|
73 | // Remove selected CSS |
---|
74 | domClass.remove(node, "dijitMenuItemSelected"); |
---|
75 | }, |
---|
76 | |
---|
77 | _page: function(/*Boolean*/ up){ |
---|
78 | // summary: |
---|
79 | // Handles page-up and page-down keypresses |
---|
80 | |
---|
81 | var scrollamount = 0; |
---|
82 | var oldscroll = this.domNode.scrollTop; |
---|
83 | var height = domStyle.get(this.domNode, "height"); |
---|
84 | // if no item is highlighted, highlight the first option |
---|
85 | if(!this.getHighlightedOption()){ |
---|
86 | this.selectNextNode(); |
---|
87 | } |
---|
88 | while(scrollamount<height){ |
---|
89 | var highlighted_option = this.getHighlightedOption(); |
---|
90 | if(up){ |
---|
91 | // stop at option 1 |
---|
92 | if(!highlighted_option.previousSibling || |
---|
93 | highlighted_option.previousSibling.style.display == "none"){ |
---|
94 | break; |
---|
95 | } |
---|
96 | this.selectPreviousNode(); |
---|
97 | }else{ |
---|
98 | // stop at last option |
---|
99 | if(!highlighted_option.nextSibling || |
---|
100 | highlighted_option.nextSibling.style.display == "none"){ |
---|
101 | break; |
---|
102 | } |
---|
103 | this.selectNextNode(); |
---|
104 | } |
---|
105 | // going backwards |
---|
106 | var newscroll = this.domNode.scrollTop; |
---|
107 | scrollamount += (newscroll-oldscroll)*(up ? -1:1); |
---|
108 | oldscroll = newscroll; |
---|
109 | } |
---|
110 | }, |
---|
111 | |
---|
112 | handleKey: function(evt){ |
---|
113 | // summary: |
---|
114 | // Handle keystroke event forwarded from ComboBox, returning false if it's |
---|
115 | // a keystroke I recognize and process, true otherwise. |
---|
116 | switch(evt.keyCode){ |
---|
117 | case keys.DOWN_ARROW: |
---|
118 | this.selectNextNode(); |
---|
119 | return false; |
---|
120 | case keys.PAGE_DOWN: |
---|
121 | this._page(false); |
---|
122 | return false; |
---|
123 | case keys.UP_ARROW: |
---|
124 | this.selectPreviousNode(); |
---|
125 | return false; |
---|
126 | case keys.PAGE_UP: |
---|
127 | this._page(true); |
---|
128 | return false; |
---|
129 | default: |
---|
130 | return true; |
---|
131 | } |
---|
132 | } |
---|
133 | }); |
---|
134 | }); |
---|