summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/ui/Grid.java
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2015-01-27 19:47:51 +0200
committerHenrik Paul <henrik@vaadin.com>2015-02-03 12:03:56 +0000
commit9cac6602821383dc2e03607066c0ea7ec7d01af7 (patch)
tree24b7239135eff169429f9e4549742fc7a6a2066e /server/src/com/vaadin/ui/Grid.java
parent04d52c41f48c9e8811a9d03c7ae0204e73f1bde2 (diff)
downloadvaadin-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.java138
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,