@@ -3,4 +3,18 @@ | |||
height: 16px; | |||
display: block; | |||
background: transparent url(../icons/16/error.png) no-repeat top right; | |||
} | |||
.i-formlayout-captioncell { | |||
text-align:right; | |||
} | |||
.i-form-errormessage { | |||
background: transparent url(../icons/16/error.png) no-repeat top left; | |||
padding-left: 20px; | |||
margin-bottom: 5px; | |||
margin-top: 5px; | |||
min-height: 20px; | |||
} | |||
* html .i-form-errormessage { | |||
height: 20px | |||
} |
@@ -484,6 +484,20 @@ input.i-modified, | |||
display: block; | |||
background: transparent url(icons/16/error.png) no-repeat top right; | |||
} | |||
.i-formlayout-captioncell { | |||
text-align:right; | |||
} | |||
.i-form-errormessage { | |||
background: transparent url(icons/16/error.png) no-repeat top left; | |||
padding-left: 20px; | |||
margin-bottom: 5px; | |||
margin-top: 5px; | |||
min-height: 20px; | |||
} | |||
* html .i-form-errormessage { | |||
height: 20px | |||
} | |||
.i-Notification { | |||
font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif; |
@@ -22,18 +22,22 @@ public class ErrorMessage extends FlowPanel { | |||
public void updateFromUIDL(UIDL uidl) { | |||
clear(); | |||
for (final Iterator it = uidl.getChildIterator(); it.hasNext();) { | |||
final Object child = it.next(); | |||
if (child instanceof String) { | |||
final String errorMessage = (String) child; | |||
add(new HTML(errorMessage)); | |||
} else if (child instanceof UIDL.XML) { | |||
final UIDL.XML xml = (UIDL.XML) child; | |||
add(new HTML(xml.getXMLAsString())); | |||
} else { | |||
final ErrorMessage childError = new ErrorMessage(); | |||
add(childError); | |||
childError.updateFromUIDL((UIDL) child); | |||
if (uidl.getChildCount() == 0) { | |||
add(new HTML(" ")); | |||
} else { | |||
for (final Iterator it = uidl.getChildIterator(); it.hasNext();) { | |||
final Object child = it.next(); | |||
if (child instanceof String) { | |||
final String errorMessage = (String) child; | |||
add(new HTML(errorMessage)); | |||
} else if (child instanceof UIDL.XML) { | |||
final UIDL.XML xml = (UIDL.XML) child; | |||
add(new HTML(xml.getXMLAsString())); | |||
} else { | |||
final ErrorMessage childError = new ErrorMessage(); | |||
add(childError); | |||
childError.updateFromUIDL((UIDL) child); | |||
} | |||
} | |||
} | |||
} |
@@ -4,34 +4,130 @@ | |||
package com.itmill.toolkit.terminal.gwt.client.ui; | |||
import com.google.gwt.user.client.ui.SimplePanel; | |||
import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.Element; | |||
import com.google.gwt.user.client.ui.ComplexPanel; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; | |||
import com.itmill.toolkit.terminal.gwt.client.Container; | |||
import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener; | |||
import com.itmill.toolkit.terminal.gwt.client.ErrorMessage; | |||
import com.itmill.toolkit.terminal.gwt.client.Paintable; | |||
import com.itmill.toolkit.terminal.gwt.client.UIDL; | |||
import com.itmill.toolkit.terminal.gwt.client.Util; | |||
public class IForm extends SimplePanel implements Paintable { | |||
public class IForm extends ComplexPanel implements Paintable, | |||
ContainerResizedListener { | |||
public static final String CLASSNAME = "i-form"; | |||
private Container lo; | |||
private Element legend = DOM.createLegend(); | |||
private Element caption = DOM.createSpan(); | |||
private Element errorIndicatorElement = DOM.createDiv(); | |||
private Element desc = DOM.createDiv(); | |||
private Icon icon; | |||
private ErrorMessage errorMessage = new ErrorMessage(); | |||
private Element fieldContainer = DOM.createDiv(); | |||
private Element footerContainer = DOM.createDiv(); | |||
private Container footer; | |||
public IForm() { | |||
super(); | |||
setElement(DOM.createFieldSet()); | |||
setStyleName(CLASSNAME); | |||
DOM.appendChild(getElement(), legend); | |||
DOM.appendChild(legend, caption); | |||
DOM.setElementProperty(errorIndicatorElement, "className", | |||
"i-errorindicator"); | |||
DOM.setStyleAttribute(errorIndicatorElement, "display", "none"); | |||
DOM.setInnerText(errorIndicatorElement, " "); // needed for IE | |||
DOM.setElementProperty(desc, "className", "i-form-description"); | |||
DOM.appendChild(getElement(), desc); | |||
DOM.appendChild(getElement(), fieldContainer); | |||
errorMessage.setVisible(false); | |||
errorMessage.setStyleName(CLASSNAME + "-errormessage"); | |||
DOM.appendChild(getElement(), errorMessage.getElement()); | |||
DOM.appendChild(getElement(), footerContainer); | |||
} | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
if (client.updateComponent(this, uidl, true)) { | |||
if (client.updateComponent(this, uidl, false)) { | |||
return; | |||
} | |||
if (uidl.hasAttribute("caption")) { | |||
DOM.setInnerText(caption, uidl.getStringAttribute("caption")); | |||
} else { | |||
DOM.setInnerText(caption, ""); | |||
} | |||
if (uidl.hasAttribute("icon")) { | |||
if (icon == null) { | |||
icon = new Icon(client); | |||
DOM.insertChild(legend, icon.getElement(), 0); | |||
} | |||
icon.setUri(uidl.getStringAttribute("icon")); | |||
} else { | |||
if (icon != null) { | |||
DOM.removeChild(legend, icon.getElement()); | |||
} | |||
} | |||
if (uidl.hasAttribute("error")) { | |||
final UIDL errorUidl = uidl.getErrors(); | |||
errorMessage.updateFromUIDL(errorUidl); | |||
errorMessage.setVisible(true); | |||
} else { | |||
errorMessage.setVisible(false); | |||
} | |||
if (uidl.hasAttribute("description")) { | |||
DOM.setInnerHTML(desc, uidl.getStringAttribute("description")); | |||
} else { | |||
DOM.setInnerHTML(desc, ""); | |||
} | |||
iLayout(); | |||
final UIDL layoutUidl = uidl.getChildUIDL(0); | |||
if (lo == null) { | |||
lo = (Container) client.getPaintable(layoutUidl); | |||
setWidget((Widget) lo); | |||
add((Widget) lo, fieldContainer); | |||
} | |||
lo.updateFromUIDL(layoutUidl, client); | |||
if (uidl.getChildCount() > 1) { | |||
// render footer | |||
Container newFooter = (Container) client.getPaintable(uidl | |||
.getChildUIDL(1)); | |||
if (footer == null) { | |||
add((Widget) newFooter, footerContainer); | |||
footer = newFooter; | |||
} else if (newFooter != footer) { | |||
remove((Widget) footer); | |||
client.unregisterPaintable(footer); | |||
add((Widget) newFooter, footerContainer); | |||
} | |||
footer = newFooter; | |||
footer.updateFromUIDL(uidl.getChildUIDL(1), client); | |||
} else { | |||
if (footer != null) { | |||
remove((Widget) footer); | |||
client.unregisterPaintable(footer); | |||
} | |||
} | |||
} | |||
public void iLayout() { | |||
// fix contained components container size as they may have relative | |||
// widths | |||
int width = DOM.getElementPropertyInt(desc, "offsetWidth"); | |||
DOM.setStyleAttribute(fieldContainer, "width", width + "px"); | |||
DOM.setStyleAttribute(footerContainer, "width", width + "px"); | |||
Util.runDescendentsLayout(this); | |||
} | |||
} |
@@ -41,10 +41,10 @@ public class IFormLayout extends FlexTable implements Container { | |||
prepareCell(i, 1); | |||
final UIDL childUidl = (UIDL) it.next(); | |||
final Paintable p = client.getPaintable(childUidl); | |||
Caption c = (Caption) componentToCaption.get(p); | |||
if (c == null) { | |||
c = new Caption(p, client); | |||
componentToCaption.put(p, c); | |||
Caption caption = (Caption) componentToCaption.get(p); | |||
if (caption == null) { | |||
caption = new Caption(p, client); | |||
componentToCaption.put(p, caption); | |||
} | |||
ErrorFlag error = (ErrorFlag) componentToError.get(p); | |||
if (error == null) { | |||
@@ -52,17 +52,18 @@ public class IFormLayout extends FlexTable implements Container { | |||
componentToError.put(p, error); | |||
} | |||
final Paintable oldComponent = (Paintable) getWidget(i, 1); | |||
prepareCell(i, 2); | |||
if (oldComponent == null) { | |||
setWidget(i, 1, (Widget) p); | |||
setWidget(i, 2, (Widget) p); | |||
} else if (oldComponent != p) { | |||
client.unregisterPaintable(oldComponent); | |||
setWidget(i, 1, (Widget) p); | |||
setWidget(i, 2, (Widget) p); | |||
} | |||
setWidget(i, 0, c); | |||
getCellFormatter().setStyleName(i, 0, "i-formlayout-captioncell"); | |||
setWidget(i, 0, caption); | |||
prepareCell(i, 2); | |||
getCellFormatter().setStyleName(i, 2, "i-formlayout-errorcell"); | |||
setWidget(i, 2, error); | |||
getCellFormatter().setStyleName(i, 1, "i-formlayout-errorcell"); | |||
setWidget(i, 1, error); | |||
p.updateFromUIDL(childUidl, client); | |||
@@ -4,7 +4,10 @@ import com.itmill.toolkit.Application; | |||
import com.itmill.toolkit.data.Validator; | |||
import com.itmill.toolkit.data.util.BeanItem; | |||
import com.itmill.toolkit.data.util.MethodProperty; | |||
import com.itmill.toolkit.terminal.ThemeResource; | |||
import com.itmill.toolkit.ui.AbstractComponent; | |||
import com.itmill.toolkit.ui.Button; | |||
import com.itmill.toolkit.ui.ExpandLayout; | |||
import com.itmill.toolkit.ui.Form; | |||
import com.itmill.toolkit.ui.OrderedLayout; | |||
import com.itmill.toolkit.ui.Panel; | |||
@@ -20,11 +23,15 @@ public class Ticket736 extends Application { | |||
final Window mainWin = new Window("Test app for #736"); | |||
setMainWindow(mainWin); | |||
mainWin.setTheme("example"); | |||
// Create form for editing address | |||
final Form f = new Form(); | |||
f.setItemDataSource(new BeanItem(address, new String[] { "name", | |||
"street", "zip", "city", "state", "country" })); | |||
f.setCaption("Office address"); | |||
f.setIcon(new ThemeResource("../default/icons/16/document.png")); | |||
f.setDescription("Jep jpe, this is form description."); | |||
mainWin.addComponent(f); | |||
// Select to use buffered mode for editing to enable commit and discard | |||
@@ -32,14 +39,19 @@ public class Ticket736 extends Application { | |||
f.setReadThrough(false); | |||
Button commit = new Button("Commit", f, "commit"); | |||
Button discard = new Button("Discard", f, "discard"); | |||
OrderedLayout ol = new OrderedLayout( | |||
OrderedLayout.ORIENTATION_HORIZONTAL); | |||
ExpandLayout ol = new ExpandLayout(OrderedLayout.ORIENTATION_HORIZONTAL); | |||
ol.setHeight("3em"); | |||
ol.addComponent(commit); | |||
ol.setComponentAlignment(commit, ExpandLayout.ALIGNMENT_RIGHT, | |||
ExpandLayout.ALIGNMENT_TOP); | |||
ol.addComponent(discard); | |||
mainWin.addComponent(ol); | |||
f.setFooter(ol); | |||
// Add some validators for the form | |||
f.getField("zip").addValidator(new IsInteger()); | |||
f.getField("zip").setDescription("Jepjep"); | |||
((AbstractComponent) f.getField("zip")).setIcon(new ThemeResource( | |||
"../default/icons/16/folder.png")); | |||
f.getField("state").addValidator(new IsValidState()); | |||
f.getField("name").setRequired(true); | |||
f.getField("street").setRequired(true); |
@@ -112,6 +112,8 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item, | |||
} | |||
}; | |||
private Layout formFooter; | |||
/** | |||
* Contructs a new form with default layout. | |||
* | |||
@@ -163,6 +165,9 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item, | |||
public void paintContent(PaintTarget target) throws PaintException { | |||
super.paintContent(target); | |||
layout.paint(target); | |||
if (formFooter != null) { | |||
formFooter.paint(target); | |||
} | |||
} | |||
/* | |||
@@ -957,4 +962,32 @@ public class Form extends AbstractField implements Item.Editor, Buffered, Item, | |||
throw new UnsupportedOperationException(); | |||
} | |||
/** | |||
* Returns a layout that is rendered below normal form contents. This area | |||
* can be used for example to include buttons related to form contents. | |||
* | |||
* @return layout rendered below normal form contents. | |||
*/ | |||
public Layout getFooter() { | |||
if (formFooter == null) { | |||
formFooter = new OrderedLayout(OrderedLayout.ORIENTATION_HORIZONTAL); | |||
setParent(formFooter); | |||
} | |||
return formFooter; | |||
} | |||
/** | |||
* Sets the layout that is rendered below normal form contens. | |||
* | |||
* @param newFormFooter | |||
* the new Layout | |||
*/ | |||
public void setFooter(Layout newFormFooter) { | |||
if (formFooter != null) { | |||
formFooter.setParent(null); | |||
} | |||
formFooter = newFormFooter; | |||
formFooter.setParent(this); | |||
} | |||
} |