From fdc15c0cac3086c89d79b5cfe17f4d030c5fb916 Mon Sep 17 00:00:00 2001
From: tpylak <tpylak>
Date: Wed, 4 Feb 2009 09:04:26 +0000
Subject: [PATCH] LMS-737 filter as the user types the pattern, remove "apply
 filters" button

SVN: 9668
---
 .../ui/grid/AbstractBrowserGrid.java          | 65 ++++++++++++++-----
 .../ui/grid/PagingColumnFilter.java           | 19 ++++--
 .../application/util/IDelagatedAction.java    | 28 ++++++++
 3 files changed, 91 insertions(+), 21 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/IDelagatedAction.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
index f56e55db3fb..d88c6e86dce 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
@@ -50,7 +50,6 @@ import com.extjs.gxt.ui.client.widget.layout.FitLayout;
 import com.extjs.gxt.ui.client.widget.layout.RowData;
 import com.extjs.gxt.ui.client.widget.layout.RowLayout;
 import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem;
-import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
 import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem;
 import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
 import com.google.gwt.user.client.Element;
@@ -65,6 +64,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.VoidAsyncC
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.AbstractEntityModel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.BrowserGridPagingToolBar.IBrowserGridActionInvoker;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelagatedAction;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.URLMethodWithParameters;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WindowUtils;
@@ -116,14 +116,16 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
     /** @return on which fields user can set filters? */
     abstract protected List<IColumnDefinition<T>> getAvailableFilters();
 
-    protected final IViewContext<ICommonClientServiceAsync> viewContext;
+    // --------
 
-    // ------ private section. NOTE: it should remain unaccessible to subclasses! ---------------
+    protected final IViewContext<ICommonClientServiceAsync> viewContext;
 
-    private static final String LABEL_APPLY_FILTERS_HINT = "Refresh to apply filters";
+    // ------------ dictionary messages which should be moved to an external file
 
     private static final String LABEL_FILTERS = "Filters";
 
+    // ------ private section. NOTE: it should remain unaccessible to subclasses! ---------------
+
     private static final int PAGE_SIZE = 50;
 
     private final PagingLoader<PagingLoadConfig> pagingLoader;
@@ -139,6 +141,8 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
 
     private final List<PagingColumnFilter<T>> filterWidgets;
 
+    // --------- non-final fields
+
     // available columns configs and definitions
     private ColumnDefsAndConfigs<T> columns;
 
@@ -181,10 +185,10 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         this.pagingToolbar =
                 new BrowserGridPagingToolBar(asActionInvoker(), viewContext, PAGE_SIZE);
         pagingToolbar.bind(pagingLoader);
-        this.filterWidgets = createFilterWidgets(getAvailableFilters());
-
-        final LayoutContainer bottomToolbars = createBottomToolbars(filterWidgets, pagingToolbar);
+        this.filterWidgets = createFilterWidgets();
+        Component filterToolbar = createFilterToolbar(filterWidgets);
 
+        final LayoutContainer bottomToolbars = createBottomToolbars(filterToolbar, pagingToolbar);
         this.contentPanel = createEmptyContentPanel();
         contentPanel.add(grid);
         contentPanel.setBottomComponent(bottomToolbars);
@@ -192,16 +196,35 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
 
         setLayout(new FitLayout());
         add(contentPanel);
+    }
 
+    private List<PagingColumnFilter<T>> createFilterWidgets()
+    {
+        return createFilterWidgets(getAvailableFilters(), createApplyFiltersDelagator());
+    }
+
+    private IDelagatedAction createApplyFiltersDelagator()
+    {
+        return new IDelagatedAction()
+            {
+                public void execute()
+                {
+                    if (isHardRefreshNeeded() == false)
+                    {
+                        reloadData();
+                    }
+                }
+            };
     }
 
     private static <T> List<PagingColumnFilter<T>> createFilterWidgets(
-            List<IColumnDefinition<T>> availableFilters)
+            List<IColumnDefinition<T>> availableFilters, IDelagatedAction onFilterAction)
     {
         List<PagingColumnFilter<T>> filterWidgets = new ArrayList<PagingColumnFilter<T>>();
         for (IColumnDefinition<T> columnDefinition : availableFilters)
         {
-            PagingColumnFilter<T> filterWidget = new PagingColumnFilter<T>(columnDefinition);
+            PagingColumnFilter<T> filterWidget =
+                    new PagingColumnFilter<T>(columnDefinition, onFilterAction);
             filterWidgets.add(filterWidget);
         }
         return filterWidgets;
@@ -603,10 +626,16 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         {
             this.columns = createColumnsDefinition();
         }
+        GWTUtils.setAutoExpandOnLastVisibleColumn(grid);
 
+        reloadData();
+    }
+
+    // refreshes the data, does not clear the cache
+    private void reloadData()
+    {
         ColumnModel columnModel = new ColumnModel(columns.getColumnConfigs());
         grid.reconfigure(grid.getStore(), columnModel);
-        GWTUtils.setAutoExpandOnLastVisibleColumn(grid);
         pagingLoader.load(0, PAGE_SIZE);
     }
 
@@ -689,6 +718,11 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         }
     }
 
+    private boolean isHardRefreshNeeded()
+    {
+        return resultSetKey == null;
+    }
+
     /** Export always deals with data from the previous refresh operation */
     public final void export()
     {
@@ -727,11 +761,10 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         return contentPanel;
     }
 
-    private static <T> LayoutContainer createBottomToolbars(
-            List<PagingColumnFilter<T>> filterWidgets, Component pagingToolbar)
+    // creates filter and paging toolbars
+    private static <T> LayoutContainer createBottomToolbars(Component filterToolbar,
+            Component pagingToolbar)
     {
-        Component filterToolbar = createFilterToolbar(filterWidgets);
-
         LayoutContainer bottomToolbars = new LayoutContainer();
         bottomToolbars.setLayout(new RowLayout(com.extjs.gxt.ui.client.Style.Orientation.VERTICAL));
         bottomToolbars.add(filterToolbar);
@@ -746,14 +779,12 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         {
             return filterToolbar;
         }
-        filterToolbar.add(new LabelToolItem(LABEL_FILTERS + ": "));
 
+        filterToolbar.add(new LabelToolItem(LABEL_FILTERS + ": "));
         for (PagingColumnFilter<T> filterWidget : filterWidgets)
         {
             filterToolbar.add(new AdapterToolItem(filterWidget));
         }
-        filterToolbar.add(new FillToolItem());
-        filterToolbar.add(new LabelToolItem(LABEL_APPLY_FILTERS_HINT));
         return filterToolbar;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/PagingColumnFilter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/PagingColumnFilter.java
index 881004b69ea..8c4ca171322 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/PagingColumnFilter.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/PagingColumnFilter.java
@@ -20,6 +20,7 @@ import com.extjs.gxt.ui.client.data.ModelData;
 import com.extjs.gxt.ui.client.store.Store;
 import com.extjs.gxt.ui.client.widget.StoreFilterField;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelagatedAction;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridFilterInfo;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IColumnDefinition;
 
@@ -32,11 +33,14 @@ public class PagingColumnFilter<T/* entity */> extends StoreFilterField<ModelDat
 {
     private final IColumnDefinition<T> filteredField;
 
-    public PagingColumnFilter(IColumnDefinition<T> filteredField)
+    private final IDelagatedAction onFilterAction;
+
+    public PagingColumnFilter(IColumnDefinition<T> filteredField, IDelagatedAction onFilterAction)
     {
         this.filteredField = filteredField;
+        this.onFilterAction = onFilterAction;
         setWidth(100);
-        String label = filteredField.getHeader() + "...";
+        String label = filteredField.getHeader();
         setEmptyText(label);
     }
 
@@ -53,11 +57,18 @@ public class PagingColumnFilter<T/* entity */> extends StoreFilterField<ModelDat
         }
     }
 
-    /** We do not use this method, data are filtered on the server side */
+    @Override
+    protected void onFilter()
+    {
+        super.onFilter();
+        onFilterAction.execute();
+    }
+
+    /** NOTE: We do not use this method, data are filtered on the server side */
     @Override
     protected boolean doSelect(Store<ModelData> store, ModelData parent, ModelData record,
             String property, String filterText)
     {
-        return true;
+        return true; // never called
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/IDelagatedAction.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/IDelagatedAction.java
new file mode 100644
index 00000000000..dd85d5d021c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/IDelagatedAction.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.application.util;
+
+/**
+ * Use this interface to delegate any kind of action to a different part of code without adding an
+ * explicit dependency.
+ * 
+ * @author Tomasz Pylak
+ */
+public interface IDelagatedAction
+{
+    void execute();
+}
-- 
GitLab