-
19 Feb 2013 10:48 AM #1
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);
-
20 Feb 2013 11:30 AM #2
Guys,
I posed two questions here, are they both bugs?
-
21 Feb 2013 12:35 AM #3
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.
-
21 Feb 2013 7:17 AM #4
I'll try the the hide mode, but 2, the display issue, happens even when visable.
-
21 Feb 2013 8:33 AM #5
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?
-
21 Feb 2013 1:11 PM #6
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.
You found a bug! We've classified it as
EXTGWT-2826
.
We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.


Reply With Quote