001: package org.wings.plaf.css;
002:
003: import org.wings.plaf.css.script.LayoutFillScript;
004: import org.wings.io.Device;
005: import org.wings.*;
006:
007: import java.io.IOException;
008:
009: /**
010: * <code>CmsFormCG<code>.
011: * <p/>
012: * User: rrd
013: * Date: 14.08.2007
014: * Time: 16:42:21
015: *
016: * @author rrd
017: * @version $Id
018: */
019: public class CmsFormCG extends FormCG implements
020: org.wings.plaf.CmsFormCG {
021:
022: @Override
023: public void writeInternal(final Device device,
024: final SComponent component) throws IOException {
025: final SForm form = (SForm) component;
026: SLayoutManager layout = form.getLayout();
027:
028: // Prevent nesting of forms
029: boolean formTagRequired = !form.getResidesInForm();
030:
031: if (formTagRequired) {
032: device.print("<form method=\"");
033: if (form.isPostMethod()) {
034: device.print("post");
035: } else {
036: device.print("get");
037: }
038: device.print("\"");
039: writeAllAttributes(device, form);
040: Utils.optAttribute(device, "name", form.getName());
041: Utils.optAttribute(device, "enctype", form
042: .getEncodingType());
043: Utils.optAttribute(device, "action", form.getRequestURL());
044: Utils.writeEvents(device, form, null);
045:
046: // Is there a default button?
047: String defaultButtonName = "undefined";
048: if (form.getDefaultButton() != null) {
049: defaultButtonName = Utils
050: .event(form.getDefaultButton());
051: }
052:
053: // The "onsubmit"-handler of the form gets triggered
054: // ONLY if the user submits it by pressing <enter> in
055: // any of its fields. In all other cases - i.e. if a
056: // button is clicked - the affected component fires its
057: // "onclick"-event which calls "sendEvent(...)" which in
058: // turn submits the form VIA JAVASCRIPT (either by means
059: // of Ajax or the traditional way). Whenever forms are
060: // submitted via JS (e.g. form.submit()) the "onsubmit"-
061: // handler is NOT triggered. So once again, the code below
062: // will only be executed when <enter> has been pressed.
063: //
064: // Therefore we can use this mechanism in order to handle
065: // the default button of the form. (see SessionServlet)
066: device.print(" onsubmit=\"wingS.request.sendEvent(");
067: device.print("event,");
068: device.print("true,");
069: device.print(!component.isReloadForced());
070: device.print(",'default_button','");
071: device.print(defaultButtonName);
072: device.print("'); return false;\">");
073:
074: writeCapture(device, form);
075: }
076:
077: // This code is needed to trigger form events
078: device.print("<input type=\"hidden\" name=\"");
079: Utils.write(device, Utils.event(form));
080: device.print("\" value=\"");
081: Utils.write(device, form.getName());
082: device.print(SConstants.UID_DIVIDER);
083: device.print("\" />");
084:
085: SDimension preferredSize = form.getPreferredSize();
086: String height = preferredSize != null ? preferredSize
087: .getHeight() : null;
088: boolean clientLayout = isMSIE(form)
089: && height != null
090: && !"auto".equals(height)
091: && (layout instanceof SBorderLayout || layout instanceof SGridBagLayout);
092:
093: String tableName = form.getName() + "_table";
094: device.print("<table id=\"");
095: device.print(tableName);
096: device.print("\"");
097:
098: if (clientLayout) {
099: Utils.optAttribute(device, "layoutHeight", height);
100: form.getSession().getScriptManager().addScriptListener(
101: new LayoutFillScript(tableName));
102: }
103: device.print(">");
104:
105: // Render the container itself
106: Utils.renderContainer(device, form);
107:
108: device.print("</table>");
109:
110: if (formTagRequired) {
111: writeCapture(device, form);
112: device.print("</form>");
113: }
114: }
115:
116: /*
117: * we render two icons into the page that captures pressing simple 'return'
118: * in the page. Why ? Depending on the Browser, the Browser sends the
119: * first or the last submit-button it finds in the page as 'default'-Submit
120: * when we simply press 'return' somewhere. *
121: * However, we don't want to have this arbitrary behaviour in wingS.
122: * So we add these two (invisible image-) submit-Buttons, either of it
123: * gets triggered on simple 'return'.
124: *
125: * Formerly this mechanism was also used for the default button handling of
126: * the form. This is now done further above by the "onsubmit"-handler. However,
127: * we still need theses two images in order to always get the latter invoked.
128: *
129: * Watchout: the style of these images once had been changed to display:none;
130: * to prevent taking some pixel renderspace. However, display:none; made
131: * the Internet Explorer not accept this as an input getting the default-focus,
132: * so it fell back to the old behaviour. So changed that style to no-padding,
133: * no-margin, no-whatever (HZ).
134: */
135: private void writeCapture(Device device, SForm form)
136: throws IOException {
137: // Whenever a form is submitted via JS (like done in this case - see above)
138: // a input field of type image (like the one below) won't be sent. This is
139: // because for some reason it doesn't belong to the "form.elements"-collection
140: // which is eventually used to assemble the post-parameters. That's why we
141: // don't even name it - would be useless anyway...
142: device.print("<input type=\"image\" border=\"0\" ");
143: Utils.optAttribute(device, "src", getBlindIcon().getURL());
144: // device.print(" width=\"0\" height=\"0\" tabindex=\"-1\"" +
145: // " style=\"border:none;padding:0px;margin:0px;position:absolute\"/>");
146: device.print("/>");
147: }
148:
149: public static void writeAllAttributes(Device device,
150: SComponent component) throws IOException {
151: Utils.optAttribute(device, "id", component.getName());
152:
153: if (component instanceof LowLevelEventListener) {
154: Utils.optAttribute(device, "eid", component
155: .getLowLevelEventId());
156: }
157:
158: // Tooltip handling
159: writeTooltipMouseOver(device, component);
160:
161: // Component popup menu
162: writeContextMenu(device, component);
163: }
164: }
|