View Poll Results: If you have better suggestions, please do so.

Voters
2. You may not vote on this poll
  • Useful

    2 100.00%
  • Not useful.

    0 0%
Multiple Choice Poll.
  1. #1
    Sencha User
    Join Date
    Nov 2010
    Posts
    2
    Vote Rating
    0
    himanshunp is on a distinguished road

      0  

    Default GXT 3 Dynamic Grid with Dynamic Column Model and Custom ValueProvider [WORKING 100%]

    GXT 3 Dynamic Grid with Dynamic Column Model and Custom ValueProvider [WORKING 100%]


    If anyone has encountered a scenario to create a Grid which can display data from any particular DB table (Grid view similar to TOAD or SQL Developer), here is the working example. This would also show you the power of ValueProvider without using Spring MVC to serialize objects in RPC calls.
    Requirement:
    Create a grid with pagination without hard coding column names and render dynamically when user selects table or view name from user input (like drop down or text field).
    Solution:
    Step #1: RPC Services
    You need to have RPC service with two calls. First to fetch columns or metadata of table and second to fetch data.


    RPCService


    Code:
    public List<String> fetchTableOrViewMetaData(String tableOrViewName);
    public PagingLoadResult<Map<String,String>> fetchTableOrViewData(PagingLoadConfig config,String tableOrViewName);
    RPCServiceAsync APIs


    Code:
    void fetchTableOrViewMetaData(String tableOrViewName, AsyncCallback<List<String>> callback);
    void fetchTableOrViewData(PagingLoadConfig config, String tableOrViewName, AsyncCallback<PagingLoadResult<Map<String,String>>> callback);
    Step#2: Create a ValueProvider which can fetch data from Map<String,String>
    Code:
    import java.util.Map;
    import com.sencha.gxt.core.client.ValueProvider;
    
    
    public class GenericMapValueProvider implements ValueProvider<Map<String, String>, String>{
        private String key;
        public GenericMapValueProvider(String key){
            this.key = key;
        }
        
        @Override
        public String getValue(Map<String, String> object) {
            return object.get(key);
        }
    
    
        @Override
        public void setValue(Map<String, String> object, String value) {
            object.put(key, value);
        }
    
    
        @Override
        public String getPath() {
            return key;
        }
    }
    Step#3: Generic Dynamic Grid Widget 100% Generic
    Code:
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.Scheduler;
    import com.google.gwt.core.client.Scheduler.ScheduledCommand;
    import com.google.gwt.user.client.ui.IsWidget;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.google.gwt.user.client.ui.Widget;
    import com.sencha.gxt.core.client.GXT;
    import com.sencha.gxt.data.client.loader.RpcProxy;
    import com.sencha.gxt.data.shared.ListStore;
    import com.sencha.gxt.data.shared.ModelKeyProvider;
    import com.sencha.gxt.data.shared.loader.LoadResultListStoreBinding;
    import com.sencha.gxt.data.shared.loader.PagingLoadConfig;
    import com.sencha.gxt.data.shared.loader.PagingLoadResult;
    import com.sencha.gxt.data.shared.loader.PagingLoader;
    import com.sencha.gxt.state.client.CookieProvider;
    import com.sencha.gxt.state.client.GridStateHandler;
    import com.sencha.gxt.state.client.StateManager;
    import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
    import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
    import com.sencha.gxt.widget.core.client.grid.ColumnModel;
    import com.sencha.gxt.widget.core.client.grid.Grid;
    import com.sencha.gxt.widget.core.client.toolbar.PagingToolBar;
    
    
    /**
     * @author Himanshu Parmar
     *
     * @param <M> Data Model
     * @param <CM> Column Model
     * @param <P> Proxy
     */
    public class DynamicGrid<M , CM extends ColumnModel<M>, P extends RpcProxy<PagingLoadConfig, PagingLoadResult<M>>> implements IsWidget, EntryPoint {
        private CM columnModel;
        private P proxy;
        private Grid<M> grid;
        private PagingLoader<PagingLoadConfig, PagingLoadResult<M>> loader;
        public DynamicGrid(final CM columnModel, final P proxy) {
            this.columnModel = columnModel;
            this.proxy = proxy;
        }
        
        @Override
        public Widget asWidget() {
            if (StateManager.get().getProvider() == null) {
                StateManager.get().setProvider(new CookieProvider("/", null, null, GXT.isSecure()));
            }
            ListStore<M> store = new ListStore<M>(new ModelKeyProvider<M>() {
                @Override
                public String getKey(M item) {
                    if(item instanceof <YourCustomerClass>){
                        return ((YourCustomerClass)item).getId();
                    }
                    return null;
                }
            });
            this.loader = new PagingLoader<PagingLoadConfig, PagingLoadResult<M>>(proxy);
            this.loader.setRemoteSort(true);
            this.loader.addLoadHandler(new LoadResultListStoreBinding<PagingLoadConfig, M, PagingLoadResult<M>>(store));
            
            final PagingToolBar toolBar = new PagingToolBar(50);
            toolBar.getElement().getStyle().setProperty("borderBottom", "none");
            toolBar.bind(loader);
            this.grid = new Grid<M>(store, columnModel) {
                @Override
                protected void onAfterFirstAttach() {
                    super.onAfterFirstAttach();
                    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
                        @Override
                        public void execute() {
                            loader.load();
                        }
                    });
                }
            };
            this.grid.getView().setStripeRows(true);
            this.grid.getView().setColumnLines(true);
            this.grid.setBorders(false);
            this.grid.setColumnReordering(true);
            this.grid.setStateful(true);
            this.grid.setLoadMask(true);
            this.grid.setStateId("gridExample");
            
            GridStateHandler<M> state = new GridStateHandler<M>(this.grid);
            state.loadState();
            VerticalLayoutContainer con = new VerticalLayoutContainer();
            con.setBorders(true);
            con.add(this.grid, new VerticalLayoutData(1, 1));
            con.add(toolBar, new VerticalLayoutData(1, -1));
            return con;
        }
    
    
        public void refreshGrid(){
            this.loader.load();
        }
        
        public Grid<M> getGrid(){
            return this.grid;
        }
        @Override
        public void onModuleLoad() {
            StateManager.get().setProvider(new CookieProvider("/", null, null, GXT.isSecure()));
            RootPanel.get().add(asWidget());
        }
    }
    Step#3: Create The UI View


    Code:
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.user.client.rpc.AsyncCallback;
    import com.google.gwt.user.client.ui.HasWidgets;
    import com.google.gwt.user.client.ui.IsWidget;
    import com.google.gwt.user.client.ui.Widget;
    import com.sencha.gxt.data.client.loader.RpcProxy;
    import com.sencha.gxt.data.shared.loader.PagingLoadConfig;
    import com.sencha.gxt.data.shared.loader.PagingLoadResult;
    import com.sencha.gxt.desktop.client.widget.Desktop;
    import com.sencha.gxt.widget.core.client.FramedPanel;
    import com.sencha.gxt.widget.core.client.box.AlertMessageBox;
    import com.sencha.gxt.widget.core.client.button.TextButton;
    import com.sencha.gxt.widget.core.client.container.SimpleContainer;
    import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
    import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
    import com.sencha.gxt.widget.core.client.event.RowDoubleClickEvent;
    import com.sencha.gxt.widget.core.client.event.RowDoubleClickEvent.RowDoubleClickHandler;
    import com.sencha.gxt.widget.core.client.event.SelectEvent;
    import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
    import com.sencha.gxt.widget.core.client.form.FieldLabel;
    import com.sencha.gxt.widget.core.client.form.TextField;
    import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
    import com.sencha.gxt.widget.core.client.grid.ColumnModel;
    import com.sencha.gxt.widget.core.client.grid.Grid;
    
    
    /**
     * @author Himanshu Parmar
     * 
     */
    public class DynamicGridView implements IsWidget {
        private final RPCServiceAsync service = GWT.create(RPCService.class);
        private DynamicGrid<Map<String,String>, ColumnModel<Map<String,String>>, RpcProxy<PagingLoadConfig, PagingLoadResult<Map<String,String>>>> dynamicGridPanel;
        @Override
        public Widget asWidget() {
            final String TABLE_NAME = "YOUR_DB_TABLE_NAME"; //THIS COULD COME FROM USER INPUT ON UI
            final SimpleContainer soc = new SimpleContainer();
            soc.mask("Loading..");
            //First get columns
            AsyncCallback<List<String>> callback = new AsyncCallback<List<String>>() {
                @Override
                public void onSuccess(List<String> result) {
                    RpcProxy<PagingLoadConfig, PagingLoadResult<Map<String,String>>> proxy = new RpcProxy<PagingLoadConfig, PagingLoadResult<Map<String,String>>>() {
                        @Override
                        public void load(PagingLoadConfig loadConfig, AsyncCallback<PagingLoadResult<Map<String,String>>> callback) {
                            service.fetchTableOrViewData(loadConfig, TABLE_NAME, callback);
                        }
                    };
    
    
                    /*Dynamic columns*/
                    List<ColumnConfig<Map<String,String>,?>> l = new ArrayList<ColumnConfig<Map<String,String>,?>>();
                    for(String column:result){
                        ColumnConfig<Map<String,String>,String> cc = new ColumnConfig<Map<String,String>, String>(new GenericMapValueProvider(column),150,column);
                        l.add(cc);
                    }
                    ColumnModel<Map<String,String>> cm = new ColumnModel<Map<String,String>>(l);
                    
                    dynamicGridPanel = new DynamicGrid<Map<String,String>, ColumnModel<Map<String,String>>, RpcProxy<PagingLoadConfig, PagingLoadResult<Map<String,String>>>>(cm, proxy);
                    SimpleContainer soc1 = new SimpleContainer();
                    soc1.add(dynamicGridPanel.asWidget());
                    VerticalLayoutContainer con = new VerticalLayoutContainer();
                    con.setBorders(true);
                    con.add(soc1, new VerticalLayoutData(1, 1));
                    soc.add(con);
                    soc.unmask();
                    soc.forceLayout();
                }
                
                @Override
                public void onFailure(Throwable caught) {
                    soc.unmask();
                    new AlertMessageBox("Error", "Error while loading grid."+caught.getMessage()).show();;
                }
            }; 
            service.fetchTableOrViewMetaData(TABLE_NAME, callback); 
            return soc;
        }
    
    
    }
    Enjoy!!!

  2. #2
    Sencha Premium Member
    Join Date
    Dec 2012
    Location
    California
    Posts
    1
    Vote Rating
    0
    amolpowar is on a distinguished road

      0  

    Default


    Himanshu,

    Thank you very much for the sample

    Regards
    Amol Powar

  3. #3
    Sencha - GXT Dev Team
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    404
    Vote Rating
    15
    branflake2267 will become famous soon enough

      0  

    Default


    Thanks for sharing.

    Brandon

  4. #4
    Sencha User
    Join Date
    Nov 2013
    Posts
    4
    Vote Rating
    0
    Ldappro is on a distinguished road

      0  

    Default A Couple of Questions Dynamic Grid

    A Couple of Questions Dynamic Grid


    I'm not sure I understand what you mean by "YourCustomerClass"


    ListStore<M> store = new ListStore<M>(new ModelKeyProvider<M>() { @Override public String getKey(M item) { if(item instanceof <YourCustomerClass>){ return ((YourCustomerClass)item).getId(); } return null; } }); this.lo
    Maybe something like this?

    Code:
    package com.att.research.gwt.siriusportal.shared;
    
    
    import java.io.Serializable;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class TableRow implements Serializable {
        
      private Map<String,String> typeMap = new HashMap<String,String>();
      private Map<String,Object> valuMap = new HashMap<String,Object>();
    
    
      private Integer id;
      private static int COUNTER = 0;
    
    
      public TableRow() {
        this.id = Integer.valueOf(COUNTER++);
      }
    
    
      public TableRow(HashMap<String,String> tMap, HashMap<String,Object> vMap) {
        this();
        this.typeMap = tMap;
        this.valuMap = vMap;
      }
    
    
      public Object getVal(String key) {
          Object val = null;
          if (valuMap.containsKey(key)) {
              val = valuMap.get(key);
          }
          return val;
      }
    
    
      public void setVal(String key, Object value) {
    
    
          if (typeMap.containsKey(key)) {
              valuMap.put(key, value);
          }
      }
      
      public String getType(String key) {
          String type = null;
          if (typeMap.containsKey(key)) {
              type = typeMap.get(key);
          }
          return type;
      }
      
      public void setType(String key, String sClass) {
          
          if (typeMap.containsKey(key)) {
              typeMap.put(key, sClass);
          }
      }
      
      public int getId() {
          return this.id;
      }
    
    
    }
    Also do you have an example that implements the Model-View-Presenter framework?