001: /* Listitem.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Wed Jun 15 17:38:52 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zul;
020:
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.ArrayList;
024:
025: import org.zkoss.lang.Objects;
026: import org.zkoss.util.logging.Log;
027: import org.zkoss.xml.HTMLs;
028:
029: import org.zkoss.zk.ui.Component;
030: import org.zkoss.zk.ui.UiException;
031:
032: import org.zkoss.zul.impl.XulElement;
033:
034: /**
035: * A list item.
036: *
037: * <p>Default {@link #getSclass}: item.
038: *
039: * @author tomyeh
040: */
041: public class Listitem extends XulElement {
042: private static final Log log = Log.lookup(Listitem.class);
043:
044: private Object _value;
045: /** The index in the parent (only for implementation purpose). */
046: private int _index = -1; //no parent at begining
047: private boolean _selected, _disabled;
048: /** whether the content of this item is loaded; used if
049: * the listbox owning this item is using a list model.
050: */
051: private boolean _loaded;
052:
053: public Listitem() {
054: }
055:
056: public Listitem(String label) {
057: setLabel(label);
058: }
059:
060: public Listitem(String label, Object value) {
061: setLabel(label);
062: setValue(value);
063: }
064:
065: /** Returns the list box that it belongs to.
066: * <p>It is the same as {@link #getParent}.
067: */
068: public Listbox getListbox() {
069: return (Listbox) getParent();
070: }
071:
072: /** Returns whether the HTML's select tag is used.
073: */
074: private final boolean inSelectMold() {
075: final Listbox listbox = getListbox();
076: return listbox != null && listbox.inSelectMold();
077: }
078:
079: protected String getRealSclass() {
080: final String sclx = (String) getListbox().getAttribute(
081: Attributes.STRIPE_STATE);
082: return super .getRealSclass() + (sclx != null ? " " + sclx : "");
083: }
084:
085: /** Returns the maximal length of each item's label.
086: * It is a shortcut of getParent().getMaxlength();
087: * Thus, it works only if the listbox's mold is "select".
088: */
089: public int getMaxlength() {
090: final Listbox listbox = getListbox();
091: return listbox != null ? listbox.getMaxlength() : 0;
092: }
093:
094: /** Returns the value.
095: * <p>Default: null.
096: * <p>Note: the value is application dependent, you can place
097: * whatever value you want.
098: * <p>If you are using listitem with HTML Form (and with
099: * the name attribute), it is better to specify a String-typed
100: * value.
101: */
102: public Object getValue() {
103: return _value;
104: }
105:
106: /** Sets the value.
107: * @param value the value.
108: * <p>Note: the value is application dependent, you can place
109: * whatever value you want.
110: * <p>If you are using listitem with HTML Form (and with
111: * the name attribute), it is better to specify a String-typed
112: * value.
113: */
114: public void setValue(Object value) {
115: if (!Objects.equals(_value, value)) {
116: _value = value;
117:
118: final Listbox listbox = getListbox();
119: if (listbox != null)
120: if (listbox.inSelectMold())
121: smartUpdate("value", Objects.toString(_value));
122: else if (listbox.getName() != null)
123: smartUpdate("z.value", Objects.toString(_value));
124: }
125: }
126:
127: /** Returns whether it is disabled.
128: * <p>Default: false.
129: */
130: public final boolean isDisabled() {
131: return _disabled;
132: }
133:
134: /** Sets whether it is disabled.
135: */
136: public void setDisabled(boolean disabled) {
137: if (_disabled != disabled) {
138: _disabled = disabled;
139: if (inSelectMold())
140: smartUpdate("disabled", _disabled);
141: else
142: invalidate();
143: }
144: }
145:
146: /** Returns whether it is selected.
147: * <p>Default: false.
148: */
149: public boolean isSelected() {
150: return _selected;
151: }
152:
153: /** Sets whether it is selected.
154: */
155: public void setSelected(boolean selected) {
156: if (_selected != selected) {
157: final Listbox listbox = (Listbox) getParent();
158: if (listbox != null) {
159: //Note: we don't update it here but let its parent does the job
160: listbox.toggleItemSelection(this );
161: } else {
162: _selected = selected;
163: }
164: }
165: }
166:
167: /** Returns the label of the {@link Listcell} it contains, or null
168: * if no such cell.
169: */
170: public String getLabel() {
171: final Listcell cell = (Listcell) getFirstChild();
172: return cell != null ? cell.getLabel() : null;
173: }
174:
175: /** Sets the label of the {@link Listcell} it contains.
176: *
177: * <p>If it is not created, we automatically create it.
178: */
179: public void setLabel(String label) {
180: autoFirstCell().setLabel(label);
181: }
182:
183: private Listcell autoFirstCell() {
184: Listcell cell = (Listcell) getFirstChild();
185: if (cell == null) {
186: cell = new Listcell();
187: cell.applyProperties();
188: cell.setParent(this );
189: }
190: return cell;
191: }
192:
193: /** Returns the src of the {@link Listcell} it contains, or null
194: * if no such cell.
195: */
196: public String getSrc() {
197: final Listcell cell = (Listcell) getFirstChild();
198: return cell != null ? cell.getSrc() : null;
199: }
200:
201: /** Sets the src of the {@link Listcell} it contains.
202: *
203: * <p>If it is not created, we automatically create it.
204: *
205: * <p>The same as {@link #setImage}.
206: */
207: public void setSrc(String src) {
208: autoFirstCell().setSrc(src);
209: }
210:
211: /** Returns the image of the {@link Listcell} it contains.
212: *
213: * <p>The same as {@link #getImage}.
214: */
215: public String getImage() {
216: return getSrc();
217: }
218:
219: /** Sets the image of the {@link Listcell} it contains.
220: *
221: * <p>If it is not created, we automatically create it.
222: *
223: * <p>The same as {@link #setSrc}.
224: */
225: public void setImage(String image) {
226: setSrc(image);
227: }
228:
229: /** Returns the index of this item (aka., the order in the listbox).
230: */
231: public final int getIndex() {
232: return _index;
233: }
234:
235: /** Sets whether the content of this item is loaded; used if
236: * the listbox owning this item is using a list model.
237: */
238: /*package*/final void setLoaded(boolean loaded) {
239: if (loaded != _loaded) {
240: _loaded = loaded;
241:
242: final Listbox listbox = getListbox();
243: if (listbox != null && listbox.getModel() != null)
244: if (_loaded && !listbox.inPagingMold())
245: invalidate();
246: //reason: the client doesn't init (for better performance)
247: //i.e., z.skipsib is specified for unloaded items
248: else
249: smartUpdate("z.loaded", _loaded);
250: }
251: }
252:
253: /** Returns whether the content of this item is loaded.
254: * It is meaningful only if {@link #getListbox} is live data,
255: * i.e., {@link Listbox#getModel} is not null.
256: *
257: * @since 2.4.0
258: */
259: public boolean isLoaded() {
260: return _loaded;
261: }
262:
263: //-- Utilities for implementation only (called by Listbox) */
264: /*package*/final void setIndexDirectly(int index) {
265: _index = index;
266: }
267:
268: /*package*/final void setSelectedDirectly(boolean selected) {
269: _selected = selected;
270: }
271:
272: //-- super --//
273: /** Returns the style class.
274: * Note: 1) if not set (or setSclass(null), "item" is assumed;
275: * 2) if selected, it appends " seld" to super's getSclass().
276: */
277: public String getSclass() {
278: String scls = super .getSclass();
279: if (scls == null)
280: scls = "item";
281: if (isDisabled())
282: return scls.length() > 0 ? scls + " disd" : "disd";
283: else if (isSelected())
284: return scls.length() > 0 ? scls + " seld" : "seld";
285: return scls;
286: }
287:
288: //-- Component --//
289: public void setParent(Component parent) {
290: if (parent != null && !(parent instanceof Listbox))
291: throw new UiException(
292: "Listitem's parent must be Listbox, not " + parent);
293: super .setParent(parent);
294: }
295:
296: public boolean insertBefore(Component child, Component insertBefore) {
297: if (!(child instanceof Listcell))
298: throw new UiException("Unsupported child for listitem: "
299: + child);
300: return super .insertBefore(child, insertBefore);
301: }
302:
303: public void invalidate() {
304: if (inSelectMold()) {
305: //Both IE and Mozilla are buggy if we update options by outerHTML
306: getParent().invalidate();
307: return;
308: }
309: super .invalidate();
310: }
311:
312: public void onChildAdded(Component child) {
313: if (inSelectMold())
314: invalidate(); //if HTML-select, Listcell has no client part
315: super .onChildAdded(child);
316: }
317:
318: public void onChildRemoved(Component child) {
319: if (inSelectMold())
320: invalidate(); //if HTML-select, Listcell has no client part
321: super .onChildRemoved(child);
322: }
323:
324: public String getOuterAttrs() {
325: final StringBuffer sb = new StringBuffer(80).append(super
326: .getOuterAttrs());
327:
328: if (inSelectMold()) {
329: HTMLs
330: .appendAttribute(sb, "value", Objects
331: .toString(_value));
332: if (isDisabled())
333: HTMLs.appendAttribute(sb, "disabled", "disabled");
334: if (isSelected())
335: HTMLs.appendAttribute(sb, "selected", "selected");
336: } else {
337: final Listbox listbox = getListbox();
338: if (listbox != null) {
339: if (listbox.getName() != null)
340: HTMLs.appendAttribute(sb, "z.value", Objects
341: .toString(_value));
342: if (listbox.getModel() != null)
343: HTMLs.appendAttribute(sb, "z.loaded", _loaded);
344: }
345: HTMLs.appendAttribute(sb, "z.disd", isDisabled());
346: if (getAttribute(Attributes.SKIP_SIBLING) != null) {
347: HTMLs.appendAttribute(sb, "z.skipsib", "true");
348: removeAttribute(Attributes.SKIP_SIBLING);
349: }
350: if (isSelected())
351: HTMLs.appendAttribute(sb, "z.sel", "true");
352:
353: final String clkattrs = getAllOnClickAttrs(false);
354: if (clkattrs != null)
355: sb.append(clkattrs);
356: HTMLs.appendAttribute(sb, "z.rid", getListbox().getUuid());
357: }
358: return sb.toString();
359: }
360:
361: //Clone//
362: public Object clone() {
363: final Listitem clone = (Listitem) super .clone();
364: clone._index = -1;
365: //note: we have to reset, since listbox.insertBefore assumes
366: //that a parent-less listitem's index is -1
367: return clone;
368: }
369: }
|