Hybrid View

    Looks like we can't reproduce the issue or there's a problem in the test case provided.
  1. #1
    Sencha Premium Member
    Join Date
    Jun 2012
    Posts
    21
    Vote Rating
    0
    joseph.j.valerio@gmail.com is on a distinguished road

      0  

    Default LiveGrid Loading on hidden tab...

    LiveGrid Loading on hidden tab...


    Hi Guys,

    I have two questions.

    1. When I load a liveDataGrid on a hidden tab, the ui does not update, I have to specifically call grid.show() in a selectionEvent handler to get it to render correctly. Is this a bug, or is this the way it should/has to be done?

    2. When the live grid loads, it does not fill the space available. If I resize the tab, the grid then correctly resizes to fill the tab. I cannot figure out how to get it to ALWAYS fill the tab onload.

    This one is WRONG...
    grid-1.png

    This one is RIGHT...
    grid-2.png

    Here is a patch to the 3.0.4 GXT branch that will update the uiBinder tab example with my issues. I added a filter to getPosts() in the ExampleService to allow you to change the result set. You can see the update failure in question 1 by commenting out the grid.show() in the View's UiHandler. You must hit update to load the data, and "brad" is a good filter value... I am running Firefox 18.0.2 if question 2 gets to that...

    As always, thanks for your efforts,

    - Joe

    Code:
    Index: src/main/java/com/sencha/gxt/explorer/client/tabs/SampleLiveGrid.java
    ===================================================================
    --- src/main/java/com/sencha/gxt/explorer/client/tabs/SampleLiveGrid.java    (revision 0)
    +++ src/main/java/com/sencha/gxt/explorer/client/tabs/SampleLiveGrid.java    (revision 0)
    @@ -0,0 +1,102 @@
    +package com.sencha.gxt.explorer.client.tabs;
    +
    +import java.util.ArrayList;
    +import java.util.Date;
    +import java.util.List;
    +
    +import com.google.gwt.cell.client.DateCell;
    +import com.google.gwt.core.client.GWT;
    +import com.google.gwt.i18n.client.DateTimeFormat;
    +import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
    +import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
    +import com.sencha.gxt.core.client.dom.XDOM;
    +import com.sencha.gxt.data.shared.ListStore;
    +import com.sencha.gxt.data.shared.ModelKeyProvider;
    +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.examples.resources.client.model.Post;
    +import com.sencha.gxt.examples.resources.client.model.PostProperties;
    +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;
    +import com.sencha.gxt.widget.core.client.grid.GridView;
    +import com.sencha.gxt.widget.core.client.grid.LiveGridView;
    +
    +public class SampleLiveGrid extends Grid<Post> {
    +    
    +    PostProxy proxy = new PostProxy();
    +    
    +    public SampleLiveGrid(){
    +        
    +        super();
    +
    +        store = new ListStore<Post>(
    +                new ModelKeyProvider<Post>() {
    +                    @Override
    +                    public String getKey(Post item) {
    +                        return "" + item.getId();
    +                    }
    +                });
    +
    +        setLoader(makeLoader(store));
    +
    +        cm = makeColumnConfigs();
    +
    +        setView(makeGridView());
    +
    +        setLoadMask(true);
    +
    +        SafeHtmlBuilder builder = new SafeHtmlBuilder();
    +        view.getAppearance().render(builder);
    +
    +        setElement(XDOM.create(builder.toSafeHtml()));
    +        getElement().makePositionable();
    +
    +        sinkCellEvents();
    +
    +    }
    +    
    +    public PagingLoader<PagingLoadConfig, PagingLoadResult<Post>> makeLoader(ListStore<Post> store) {
    +
    +        final PagingLoader<PagingLoadConfig, PagingLoadResult<Post>> gridLoader = new PagingLoader<PagingLoadConfig, PagingLoadResult<Post>>(proxy);
    +        gridLoader.setRemoteSort(true);
    +        return gridLoader;
    +
    +    }
    +    
    +    public ColumnModel<Post> makeColumnConfigs() {
    +
    +        PostProperties props = GWT.create(PostProperties.class);
    +
    +        ColumnConfig<Post, String> forumColumn = new ColumnConfig<Post, String>(
    +                props.forum(), 150, "Forum");
    +        ColumnConfig<Post, String> usernameColumn = new ColumnConfig<Post, String>(
    +                props.username(), 150, "Username");
    +        ColumnConfig<Post, String> subjectColumn = new ColumnConfig<Post, String>(
    +                props.subject(), 150, "Subject");
    +        ColumnConfig<Post, Date> dateColumn = new ColumnConfig<Post, Date>(
    +                props.date(), 150, "Date");
    +        dateColumn.setCell(new DateCell(DateTimeFormat
    +                .getFormat(PredefinedFormat.DATE_SHORT)));
    +
    +        List<ColumnConfig<Post, ?>> l = new ArrayList<ColumnConfig<Post, ?>>();
    +        l.add(forumColumn);
    +        l.add(usernameColumn);
    +        l.add(subjectColumn);
    +        l.add(dateColumn);
    +
    +        return new ColumnModel<Post>(l);
    +    }
    +    
    +    public GridView<Post> makeGridView(){
    +        final LiveGridView<Post> liveGridView = new LiveGridView<Post>();
    +        liveGridView.setForceFit(true);
    +        return liveGridView;
    +    }
    +    
    +    public void setFilter(String filter){
    +        proxy.setFilter(filter);
    +    }
    +
    +}
    Index: src/main/java/com/sencha/gxt/explorer/client/tabs/BasicTabUiBinderExample.java
    ===================================================================
    --- src/main/java/com/sencha/gxt/explorer/client/tabs/BasicTabUiBinderExample.java    (revision 2683)
    +++ src/main/java/com/sencha/gxt/explorer/client/tabs/BasicTabUiBinderExample.java    (working copy)
    @@ -4,6 +4,7 @@
     import com.google.gwt.core.client.GWT;
     import com.google.gwt.event.logical.shared.SelectionEvent;
     import com.google.gwt.uibinder.client.UiBinder;
    +import com.google.gwt.uibinder.client.UiFactory;
     import com.google.gwt.uibinder.client.UiField;
     import com.google.gwt.uibinder.client.UiHandler;
     import com.google.gwt.user.client.ui.IsWidget;
    @@ -11,34 +12,72 @@
     import com.google.gwt.user.client.ui.Widget;
     import com.sencha.gxt.examples.resources.client.TestData;
     import com.sencha.gxt.explorer.client.model.Example.Detail;
    +import com.sencha.gxt.widget.core.client.PlainTabPanel;
    +import com.sencha.gxt.widget.core.client.Resizable;
     import com.sencha.gxt.widget.core.client.TabItemConfig;
     import com.sencha.gxt.widget.core.client.TabPanel;
    +import com.sencha.gxt.widget.core.client.button.TextButton;
    +import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
    +import com.sencha.gxt.widget.core.client.event.SelectEvent;
    +import com.sencha.gxt.widget.core.client.form.TextField;
    +import com.sencha.gxt.widget.core.client.grid.LiveToolItem;
     import com.sencha.gxt.widget.core.client.info.Info;
     
     @Detail(name = "Basic Tabs (UiBinder)", icon = "basictabs", category = "Tabs", files = "BasicTabUiBinderExample.ui.xml")
     public class BasicTabUiBinderExample implements IsWidget, EntryPoint {
     
    -  interface MyUiBinder extends UiBinder<Widget, BasicTabUiBinderExample> {
    -  }
    +    interface MyUiBinder extends UiBinder<Widget, BasicTabUiBinderExample> {
    +    }
    +
    +    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
     
    -  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
    +    @UiField(provided = true)
    +    String txt = TestData.DUMMY_TEXT_SHORT;
    +    @UiField
    +    TextButton update;
    +    @UiField
    +    TextField filter;
    +    @UiField
    +    SampleLiveGrid grid;
    +    @UiField 
    +    PlainTabPanel tabPanel;
    +    @UiField
    +    VerticalLayoutContainer gridTab;
     
    -  @UiField(provided = true)
    -  String txt = TestData.DUMMY_TEXT_SHORT;
    +    public Widget asWidget() {
    +        Widget w = uiBinder.createAndBindUi(this);
    +        new Resizable(tabPanel);
    +        return w;
    +    }
     
    -  public Widget asWidget() {
    -    return uiBinder.createAndBindUi(this);
    -  }
    +    public void onModuleLoad() {
    +        RootPanel.get().add(asWidget());
    +    }
     
    -  public void onModuleLoad() {
    -    RootPanel.get().add(asWidget());
    -  }
    +    @UiHandler(value = { "folder", "tabPanel" })
    +    void onSelection(SelectionEvent<Widget> event) {
    +        TabPanel panel = (TabPanel) event.getSource();
    +        Widget w = event.getSelectedItem();
    +        TabItemConfig config = panel.getConfig(w);
    +        Info.display("Message", "'" + config.getText() + "' Selected");
    +    }
     
    -  @UiHandler(value = {"folder", "panel"})
    -  void onSelection(SelectionEvent<Widget> event) {
    -    TabPanel panel = (TabPanel) event.getSource();
    -    Widget w = event.getSelectedItem();
    -    TabItemConfig config = panel.getConfig(w);
    -    Info.display("Message", "'" + config.getText() + "' Selected");
    -  }
    +    @UiHandler(value = { "tabPanel" })
    +    void onTabSelection(SelectionEvent<Widget> event) {
    +        if(event.getSelectedItem() == gridTab){
    +            grid.show();
    +        }
    +    }
    +    
    +    @UiFactory
    +    public LiveToolItem makeLiveToolItem(SampleLiveGrid grid) {
    +        return new LiveToolItem(grid);
    +    }
    +    
    +    @UiHandler("update")
    +    public void handleUpdate(SelectEvent event){
    +        grid.setFilter(filter.getText());
    +        grid.getLoader().load();
    +    }
    +
     }
    Index: src/main/java/com/sencha/gxt/explorer/client/tabs/BasicTabUiBinderExample.ui.xml
    ===================================================================
    --- src/main/java/com/sencha/gxt/explorer/client/tabs/BasicTabUiBinderExample.ui.xml    (revision 2683)
    +++ src/main/java/com/sencha/gxt/explorer/client/tabs/BasicTabUiBinderExample.ui.xml    (working copy)
    @@ -1,6 +1,13 @@
     <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
    -<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g="urn:import:com.google.gwt.user.client.ui"
    -  xmlns:tabs="urn:import:com.sencha.gxt.widget.core.client" xmlns:container="urn:import:com.sencha.gxt.widget.core.client.container">
    +<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' 
    +    xmlns:g="urn:import:com.google.gwt.user.client.ui"
    +    xmlns:tabs="urn:import:com.sencha.gxt.widget.core.client" 
    +    xmlns:frm="urn:import:com.sencha.gxt.widget.core.client.form" 
    +    xmlns:btn="urn:import:com.sencha.gxt.widget.core.client.button" 
    +    xmlns:container="urn:import:com.sencha.gxt.widget.core.client.container"
    +    xmlns:gxtt="urn:import:com.sencha.gxt.widget.core.client.toolbar"
    +    xmlns:gxtg="urn:import:com.sencha.gxt.widget.core.client.grid"
    +    xmlns:grid="urn:import:com.sencha.gxt.explorer.client.tabs">
     
       <ui:with type="java.lang.String" field="txt" />
       <ui:with type="com.sencha.gxt.examples.resources.client.images.ExampleImages" field="images" />
    @@ -20,6 +27,12 @@
       <ui:with type="com.sencha.gxt.widget.core.client.TabItemConfig" field="disabledTabConfig">
         <ui:attributes text="Disabled" enabled="false" />
       </ui:with>
    +    <ui:with field="gridVlo" type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData">
    +        <ui:attributes height="1"/>
    +    </ui:with>
    +    <ui:with field="gridFooterVlo" type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData">
    +        <ui:attributes height="30"/>
    +    </ui:with>
     
       <ui:style>
         .sep {
    @@ -41,11 +54,24 @@
           </tabs:child>
         </tabs:TabPanel>
     
    -    <tabs:PlainTabPanel ui:field="panel" pixelSize="450, 250" addStyleNames="margin-10">
    +    <frm:TextField ui:field="filter"/>
    +    <btn:TextButton ui:field="update" text="Update"/>
    +
    +    <tabs:PlainTabPanel ui:field="tabPanel" pixelSize="450, 250" addStyleNames="margin-10">
    +    
           <tabs:child config="{normalTabConfig}">
    -        <g:Label text="Just a plain old tab" addStyleNames="pad-text" />
    +        <container:VerticalLayoutContainer ui:field="gridTab">
    +            <container:child layoutData="{gridVlo}">
    +                <grid:SampleLiveGrid ui:field="grid" />
    +            </container:child>
    +            <container:child layoutData="{gridFooterVlo}">
    +                <gxtt:ToolBar>
    +                    <gxtg:LiveToolItem grid="{grid}"/>
    +                </gxtt:ToolBar>
    +            </container:child>
    +        </container:VerticalLayoutContainer>
           </tabs:child>
    -
    +      
           <tabs:child config="{iconTabConfig}">
             <g:Label text="Just a plain old tab with an icon" addStyleNames="pad-text" />
           </tabs:child>
    @@ -54,6 +80,7 @@
             <g:Label text="This tab should be disabled" addStyleNames="pad-text" />
           </tabs:child>
         </tabs:PlainTabPanel>
    +
       </container:FlowLayoutContainer>
     
     </ui:UiBinder>
    Index: src/main/java/com/sencha/gxt/explorer/client/tabs/PostProxy.java
    ===================================================================
    --- src/main/java/com/sencha/gxt/explorer/client/tabs/PostProxy.java    (revision 0)
    +++ src/main/java/com/sencha/gxt/explorer/client/tabs/PostProxy.java    (revision 0)
    @@ -0,0 +1,32 @@
    +package com.sencha.gxt.explorer.client.tabs;
    +
    +import com.google.gwt.core.client.GWT;
    +import com.google.gwt.user.client.rpc.AsyncCallback;
    +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.examples.resources.client.ExampleService;
    +import com.sencha.gxt.examples.resources.client.ExampleServiceAsync;
    +import com.sencha.gxt.examples.resources.client.model.Post;
    +
    +public class PostProxy extends RpcProxy<PagingLoadConfig, PagingLoadResult<Post>>{
    +
    +    final ExampleServiceAsync service = GWT.create(ExampleService.class);
    +
    +    String filter;
    +    
    +    @Override
    +    public void load(PagingLoadConfig loadConfig,
    +            AsyncCallback<PagingLoadResult<Post>> callback) {
    +        service.getPosts(loadConfig, filter, callback);
    +    }
    +
    +    public String getFilter() {
    +        return filter;
    +    }
    +
    +    public void setFilter(String filter) {
    +        this.filter = filter;
    +    }
    +
    +}
    Index: src/main/java/com/sencha/gxt/examples/resources/server/ExampleServiceImpl.java
    ===================================================================
    --- src/main/java/com/sencha/gxt/examples/resources/server/ExampleServiceImpl.java    (revision 2683)
    +++ src/main/java/com/sencha/gxt/examples/resources/server/ExampleServiceImpl.java    (working copy)
    @@ -79,16 +79,33 @@
     
       @Override
       public PagingLoadResult<Post> getPosts(PagingLoadConfig config) {
    +      return getPosts(config, null);      
    +  }
    +
    +  @Override
    +  public PagingLoadResult<Post> getPosts(PagingLoadConfig config, String filter) {
         if (posts == null) {
           loadPosts();
         }
    -
    +    
    +    List<Post> subPosts = new ArrayList<Post>();
    +    if(filter == null
    +    || filter.isEmpty()){
    +        subPosts = posts;
    +    } else {
    +        for(Post p : posts){
    +            if(p.getUsername().matches(filter)){
    +                subPosts.add(p);
    +            }
    +        }
    +    }
    +    
         if (config.getSortInfo().size() > 0) {
           SortInfo sort = config.getSortInfo().get(0);
           if (sort.getSortField() != null) {
             final String sortField = sort.getSortField();
             if (sortField != null) {
    -          Collections.sort(posts, sort.getSortDir().comparator(new Comparator<Post>() {
    +          Collections.sort(subPosts, sort.getSortDir().comparator(new Comparator<Post>() {
                 public int compare(Post p1, Post p2) {
                   if (sortField.equals("forum")) {
                     return p1.getForum().compareTo(p2.getForum());
    @@ -108,14 +125,14 @@
     
         ArrayList<Post> sublist = new ArrayList<Post>();
         int start = config.getOffset();
    -    int limit = posts.size();
    +    int limit = subPosts.size();
         if (config.getLimit() > 0) {
           limit = Math.min(start + config.getLimit(), limit);
         }
         for (int i = config.getOffset(); i < limit; i++) {
    -      sublist.add(posts.get(i));
    +      sublist.add(subPosts.get(i));
         }
    -    return new PagingLoadResultBean<Post>(sublist, posts.size(), config.getOffset());
    +    return new PagingLoadResultBean<Post>(sublist, subPosts.size(), config.getOffset());
       }
     
       @Override
    Index: src/main/java/com/sencha/gxt/examples/resources/client/ExampleService.java
    ===================================================================
    --- src/main/java/com/sencha/gxt/examples/resources/client/ExampleService.java    (revision 2683)
    +++ src/main/java/com/sencha/gxt/examples/resources/client/ExampleService.java    (working copy)
    @@ -17,7 +17,8 @@
     public interface ExampleService extends RemoteService {
     
       PagingLoadResult<Post> getPosts(PagingLoadConfig config);
    -
    +  PagingLoadResult<Post> getPosts(PagingLoadConfig config, String filter);
    +  
       /**
        * Returns the music root folder with all child references.
        * 
    Index: src/main/java/com/sencha/gxt/examples/resources/client/ExampleServiceAsync.java
    ===================================================================
    --- src/main/java/com/sencha/gxt/examples/resources/client/ExampleServiceAsync.java    (revision 2683)
    +++ src/main/java/com/sencha/gxt/examples/resources/client/ExampleServiceAsync.java    (working copy)
    @@ -15,7 +15,8 @@
     public interface ExampleServiceAsync {
     
       void getPosts(PagingLoadConfig config, AsyncCallback<PagingLoadResult<Post>> callback);
    -
    +  void getPosts(PagingLoadConfig config, String filter, AsyncCallback<PagingLoadResult<Post>> callback);
    +  
       void getMusicRootFolder(AsyncCallback<FolderDto> callback);
       
       void getMusicFolderChildren(FolderDto folder, AsyncCallback<List<BaseDto>> callback);

  2. #2
    Sencha Premium Member
    Join Date
    Jun 2012
    Posts
    21
    Vote Rating
    0
    joseph.j.valerio@gmail.com is on a distinguished road

      0  

    Default


    Guys,

    I posed two questions here, are they both bugs?

  3. #3
    Software Architect
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    Not sure where my reply went to:

    1) The problem is that when something is hidden with display none, it has no sizes and so the rowcount is not working correclty. A workaround would be to change the HideMode to HideMode.OFFSETS on the component that you add to the TabPanel.

    2) This might be solved with the workaround from 1) too


    I moved this into the bugs forum to add workarounds internly like Ext GWT 2 had in place.

  4. #4
    Sencha Premium Member
    Join Date
    Jun 2012
    Posts
    21
    Vote Rating
    0
    joseph.j.valerio@gmail.com is on a distinguished road

      0  

    Default


    I'll try the the hide mode, but 2, the display issue, happens even when visable.

  5. #5
    Sencha Premium Member
    Join Date
    Jun 2012
    Posts
    21
    Vote Rating
    0
    joseph.j.valerio@gmail.com is on a distinguished road

      0  

    Default


    HideMode.OFFSETS works when set on the parent container, thanks. Do you think there will ever be a fix for this other than the work around?

  6. #6
    Sencha Premium Member
    Join Date
    Jun 2012
    Posts
    21
    Vote Rating
    0
    joseph.j.valerio@gmail.com is on a distinguished road

      0  

    Default


    To be more specific, it would be great if the control knew it wasn't rendered because it was hidden, and then on re-attach to the dom, it would lay itself out correctly.

    I am having the same issue where the LiveGrid is not on a tab panel, but in a completely different view. I want to update data in the store, depending on actions in the other view, and have the data waiting for when the user inevitably returns. I now I could change the architecture of the site and use decks, but I shouldn't have to design my app according to what I consider a bug.

Thread Participants: 2