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