1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
21
22 import org.apache.myfaces.tobago.component.RendererTypes;
23 import org.apache.myfaces.tobago.component.UITreeLabel;
24 import org.apache.myfaces.tobago.component.UITreeNode;
25 import org.apache.myfaces.tobago.internal.component.AbstractUITree;
26 import org.apache.myfaces.tobago.layout.Measure;
27 import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
28 import org.apache.myfaces.tobago.renderkit.css.Classes;
29 import org.apache.myfaces.tobago.renderkit.css.Position;
30 import org.apache.myfaces.tobago.renderkit.css.Style;
31 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
32 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
33 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
34 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
35 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
36 import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
37 import org.apache.myfaces.tobago.util.ComponentUtils;
38 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
39
40 import javax.faces.component.UIComponent;
41 import javax.faces.context.FacesContext;
42 import java.io.IOException;
43 import java.util.ArrayList;
44 import java.util.List;
45
46 public class TreeListboxRenderer extends LayoutComponentRendererBase {
47
48 public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
49 super.prepareRender(facesContext, component);
50 setRendererTypeForCommandsAndNodes(component);
51 }
52
53 protected void setRendererTypeForCommandsAndNodes(UIComponent component) {
54 for (UIComponent child : component.getChildren()) {
55 if (child instanceof UITreeNode) {
56 child.setRendererType(RendererTypes.TREE_LISTBOX_NODE);
57 }
58 setRendererTypeForCommandsAndNodes(child);
59 }
60 }
61
62 @Override
63 public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
64
65 }
66
67 @Override
68 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
69
70 final AbstractUITree tree = (AbstractUITree) component;
71 final String clientId = tree.getClientId(facesContext);
72 final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
73 final Style style = new Style(facesContext, tree);
74 final Style scrollDivStyle = new Style();
75
76 writer.startElement(HtmlElements.DIV, tree);
77 scrollDivStyle.setWidth(Measure.valueOf(6 * 160));
78 scrollDivStyle.setHeight(style.getHeight()
79 .subtract(15));
80 scrollDivStyle.setPosition(Position.ABSOLUTE);
81 writer.writeStyleAttribute(scrollDivStyle);
82
83 writer.startElement(HtmlElements.DIV, tree);
84 writer.writeClassAttribute(Classes.create(tree));
85 HtmlRendererUtils.writeDataAttributes(facesContext, writer, tree);
86 writer.writeStyleAttribute(style);
87
88 writer.startElement(HtmlElements.INPUT, tree);
89 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
90 writer.writeNameAttribute(clientId);
91 writer.writeIdAttribute(clientId);
92 writer.writeAttribute(HtmlAttributes.VALUE, ";", false);
93 writer.endElement(HtmlElements.INPUT);
94
95 writer.startElement(HtmlElements.INPUT, tree);
96 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
97 writer.writeNameAttribute(clientId + ComponentUtils.SUB_SEPARATOR + AbstractUITree.SUFFIX_MARKED);
98 writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + AbstractUITree.SUFFIX_MARKED);
99 writer.writeAttribute(HtmlAttributes.VALUE, "", false);
100 writer.endElement(HtmlElements.INPUT);
101
102 if (tree.getSelectableAsEnum().isSupportedByTreeListbox()) {
103 writer.startElement(HtmlElements.INPUT, tree);
104 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
105 writer.writeNameAttribute(clientId + AbstractUITree.SELECT_STATE);
106 writer.writeIdAttribute(clientId + AbstractUITree.SELECT_STATE);
107 writer.writeAttribute(HtmlAttributes.VALUE, ";", false);
108 writer.endElement(HtmlElements.INPUT);
109 }
110
111 List<Integer> thisLevel = new ArrayList<Integer>();
112 thisLevel.add(0);
113 List<Integer> nextLevel = new ArrayList<Integer>();
114 for (int level = 0; level < 7; level++) {
115
116 writer.startElement(HtmlElements.DIV, null);
117 writer.writeClassAttribute(Classes.create(tree, "level"));
118 Style levelStyle = new Style();
119 levelStyle.setLeft(Measure.valueOf(level * 160));
120 writer.writeStyleAttribute(levelStyle);
121
122
123 if (level > 0) {
124 writer.startElement(HtmlElements.SELECT, null);
125 writer.writeAttribute(HtmlAttributes.DISABLED, true);
126 writer.writeAttribute(HtmlAttributes.SIZE, 9);
127 writer.writeClassAttribute(Classes.create(tree, "select"));
128 writer.endElement(HtmlElements.SELECT);
129 }
130
131 for(Integer rowIndex : thisLevel) {
132 encodeSelectBox(facesContext, tree, writer, rowIndex, nextLevel);
133 }
134
135 thisLevel.clear();
136 List<Integer> swap = thisLevel;
137 thisLevel = nextLevel;
138 nextLevel = swap;
139
140 writer.endElement(HtmlElements.DIV);
141 }
142
143 writer.endElement(HtmlElements.DIV);
144 writer.endElement(HtmlElements.DIV);
145
146 tree.setRowIndex(-1);
147 }
148
149 private void encodeSelectBox(
150 FacesContext facesContext, AbstractUITree tree, TobagoResponseWriter writer,
151 int parentRowIndex, List<Integer> foldersRowIndices)
152 throws IOException {
153
154 tree.setRowIndex(parentRowIndex);
155
156 final UITreeNode node = ComponentUtils.findDescendant(tree, UITreeNode.class);
157 final String parentId = node.getClientId(facesContext);
158
159 writer.startElement(HtmlElements.SELECT, tree);
160 writer.writeClassAttribute(Classes.create(tree, "select"));
161 if (parentId != null) {
162 writer.writeAttribute(DataAttributes.TREEPARENT, parentId, false);
163 }
164
165 writer.writeAttribute(HtmlAttributes.SIZE, 9);
166
167
168 final UITreeLabel label = ComponentUtils.findDescendant(tree, UITreeLabel.class);
169 final Object labelValue = label.getValue();
170 if (labelValue != null) {
171 writer.startElement(HtmlElements.OPTGROUP, tree);
172 writer.writeAttribute(HtmlAttributes.LABEL, labelValue.toString(), true);
173 writer.endElement(HtmlElements.OPTGROUP);
174 }
175
176 final List<Integer> rowIndices = tree.getRowIndicesOfChildren();
177
178 for (Integer rowIndex : rowIndices) {
179 tree.setRowIndex(rowIndex);
180 if (!tree.isRowAvailable()) {
181 break;
182 }
183
184 for (UIComponent child : tree.getChildren()) {
185 RenderUtils.prepareRendererAll(facesContext, child);
186 RenderUtils.encode(facesContext, child);
187 }
188
189 if (tree.isFolder()) {
190 foldersRowIndices.add(rowIndex);
191 }
192 }
193
194 writer.endElement(HtmlElements.SELECT);
195 }
196 }