diff options
author | Artur Signell <artur@vaadin.com> | 2015-01-27 19:47:51 +0200 |
---|---|---|
committer | Henrik Paul <henrik@vaadin.com> | 2015-02-03 12:03:56 +0000 |
commit | 9cac6602821383dc2e03607066c0ea7ec7d01af7 (patch) | |
tree | 24b7239135eff169429f9e4549742fc7a6a2066e /server/src/com/vaadin/ui/Grid.java | |
parent | 04d52c41f48c9e8811a9d03c7ae0204e73f1bde2 (diff) | |
download | vaadin-framework-9cac6602821383dc2e03607066c0ea7ec7d01af7.tar.gz vaadin-framework-9cac6602821383dc2e03607066c0ea7ec7d01af7.zip |
Add methods for getting invalid fields from a FieldGroup (#13775)
* Method for retrieving all failing fields exceptions from a
CommitException
* Methods for handling commit errors in Grid (#16515)
* Show editor row validation errors only on the fields (#16509)
Change-Id: Iabef662579e4ccae3803a513205e46542c41cce2
Diffstat (limited to 'server/src/com/vaadin/ui/Grid.java')
-rw-r--r-- | server/src/com/vaadin/ui/Grid.java | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java index 3c0afbc484..0ba771b283 100644 --- a/server/src/com/vaadin/ui/Grid.java +++ b/server/src/com/vaadin/ui/Grid.java @@ -48,6 +48,7 @@ import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.RpcDataProviderExtension; import com.vaadin.data.RpcDataProviderExtension.DataProviderKeyMapper; +import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.data.fieldgroup.DefaultFieldGroupFieldFactory; import com.vaadin.data.fieldgroup.FieldGroup; import com.vaadin.data.fieldgroup.FieldGroup.BindException; @@ -90,6 +91,7 @@ import com.vaadin.shared.ui.grid.GridStaticSectionState.RowState; import com.vaadin.shared.ui.grid.HeightMode; import com.vaadin.shared.ui.grid.ScrollDestination; import com.vaadin.shared.util.SharedUtil; +import com.vaadin.ui.Notification.Type; import com.vaadin.ui.renderer.ObjectRenderer; import com.vaadin.ui.renderer.Renderer; import com.vaadin.util.ReflectTools; @@ -239,6 +241,102 @@ public class Grid extends AbstractComponent implements SelectionNotifier, } /** + * Error handler for the editor + */ + public interface EditorErrorHandler extends Serializable { + + /** + * Called when an exception occurs while the editor row is being saved + * + * @param event + * An event providing more information about the error + */ + void commitError(CommitErrorEvent event); + } + + /** + * An event which is fired when saving the editor fails + */ + public static class CommitErrorEvent extends Component.Event { + + private CommitException cause; + + public CommitErrorEvent(Grid grid, CommitException cause) { + super(grid); + this.cause = cause; + } + + /** + * Retrieves the cause of the failure + * + * @return the cause of the failure + */ + public CommitException getCause() { + return cause; + } + + @Override + public Grid getComponent() { + return (Grid) super.getComponent(); + } + + /** + * Checks if validation exceptions caused this error + * + * @return true if the problem was caused by a validation error + */ + public boolean isValidationFailure() { + return cause.getCause() instanceof InvalidValueException; + } + + } + + /** + * Default error handler for the editor + * + */ + public class DefaultEditorErrorHandler implements EditorErrorHandler { + + @Override + public void commitError(CommitErrorEvent event) { + Map<Field<?>, InvalidValueException> invalidFields = event + .getCause().getInvalidFields(); + + if (!invalidFields.isEmpty()) { + // Validation error, show first failure as + // "<Column header>: <message>" + FieldGroup fieldGroup = event.getCause().getFieldGroup(); + Object propertyId = getFirstPropertyId(fieldGroup, + invalidFields.keySet()); + Field<?> field = fieldGroup.getField(propertyId); + String caption = getColumn(propertyId).getHeaderCaption(); + // TODO This should be shown in the editor component once + // there is a place for that. Optionally, all errors should be + // shown + Notification.show(caption + ": " + + invalidFields.get(field).getLocalizedMessage(), + Type.ERROR_MESSAGE); + + } else { + com.vaadin.server.ErrorEvent.findErrorHandler(Grid.this).error( + new ConnectorErrorEvent(Grid.this, event.getCause())); + } + } + + private Object getFirstPropertyId(FieldGroup fieldGroup, + Set<Field<?>> keySet) { + for (Column c : getColumns()) { + Object propertyId = c.getPropertyId(); + Field<?> f = fieldGroup.getField(propertyId); + if (keySet.contains(f)) { + return propertyId; + } + } + return null; + } + } + + /** * Selection modes representing built-in {@link SelectionModel * SelectionModels} that come bundled with {@link Grid}. * <p> @@ -2622,6 +2720,8 @@ public class Grid extends AbstractComponent implements SelectionNotifier, */ private boolean defaultContainer = true; + private EditorErrorHandler editorErrorHandler = new DefaultEditorErrorHandler(); + private static final Method SELECTION_CHANGE_METHOD = ReflectTools .findMethod(SelectionListener.class, "select", SelectionEvent.class); @@ -2861,6 +2961,15 @@ public class Grid extends AbstractComponent implements SelectionNotifier, try { saveEditor(); success = true; + } catch (CommitException e) { + try { + getEditorErrorHandler().commitError( + new CommitErrorEvent(Grid.this, e)); + } catch (Exception ee) { + // A badly written error handler can throw an exception, + // which would lock up the Grid + handleError(ee); + } } catch (Exception e) { handleError(e); } @@ -4713,6 +4822,35 @@ public class Grid extends AbstractComponent implements SelectionNotifier, editorFieldGroup.setFieldFactory(fieldFactory); } + /** + * Sets the error handler for the editor. + * + * The error handler is called whenever there is an exception in the editor. + * + * @param editorErrorHandler + * The editor error handler to use + * @throws IllegalArgumentException + * if the error handler is null + */ + public void setEditorErrorHandler(EditorErrorHandler editorErrorHandler) + throws IllegalArgumentException { + if (editorErrorHandler == null) { + throw new IllegalArgumentException( + "The error handler cannot be null"); + } + this.editorErrorHandler = editorErrorHandler; + } + + /** + * Gets the error handler used for the editor + * + * @see #setErrorHandler(com.vaadin.server.ErrorHandler) + * @return the editor error handler, never null + */ + public EditorErrorHandler getEditorErrorHandler() { + return editorErrorHandler; + } + @Override public void addItemClickListener(ItemClickListener listener) { addListener(GridConstants.ITEM_CLICK_EVENT_ID, ItemClickEvent.class, |