-
25 Nov 2012 2:49 AM #1
List Items with height > 47px not rendered correctly.
List Items with height > 47px not rendered correctly.
I just upgraded an app from Sencha Touch 2.0.1.1 to 2.1.0, no code changes, and it broke the rendering of my List items. This is a restaurant menu app that shows pictures inside list items, typically resulting in a x-list-item height of 140px. With 2.0.1.1, the rendered list items looked like this:
<div class="x-list-item" id="ext-element-20"><div class="x-list-item-label"><img style="float: left; margin-right: 15px" class="eyb-thumbnail" src="/images/items/120/8.jpg" width="120">Sashimi Simples R$33.90<br><span style="color: #666; font-size: 80%;">5 Atum, 5 Salmão e 5 Peixe Branco</span><div style="clear: both"></div></div></div>
Which is pretty beautiful in my opinion, and worked perfectly. In 2.1.0, it gets rendered to this monstrosity:
<div class="x-container x-list-item x-stretched" id="ext-listitem-4" style="min-height: 47px !important; -webkit-transform: translate3d(0px, 166px, 0px); "><div class="x-dock x-dock-horizontal x-stretched" id="ext-element-49"><div class="x-unsized x-list-header x-item-hidden" id="ext-component-16" style="display: none !important; "><div class="x-innerhtml " id="ext-element-51"> </div></div><div class="x-dock-body" id="ext-element-50"><div class="x-inner x-list-item-inner" id="ext-element-48"><div class="x-unsized x-list-item-body" id="ext-component-14"><div class="x-innerhtml " id="ext-element-52"><img style="float: left; margin-right: 15px" class="eyb-thumbnail" src="/images/items/120/8.jpg" width="120">Sashimi Simples R$33.90<br><span style="color: #666; font-size: 80%;">5 Atum, 5 Salmão e 5 Peixe Branco</span><div style="clear: both"></div></div></div></div></div><div class="x-unsized x-item-hidden x-list-disclosure x-dock-item x-docked-right" id="ext-component-15" style="display: none !important; "></div></div></div>
Which, apart from the awful "!important" CSS, and the unnecessary DIV nesting, simply doesn't work. The -webkit-transform CSS used to position the list items starts with the default spacing of 47px per list item, and when you scroll the list somewhat this gets recalculated to the 140px actual list item size gap, _if_ the list is long enough so that you can scroll it to force the recalculation.
IMHO the 2.0.1.1 solution was much cleaner both in the HTML it generated and in how it actually works, which is by allowing the items to flow instead of absolutely positioning them.
-jd
-
25 Nov 2012 9:26 AM #2
I am facing the exact same problem at the moment when trying to embed images in my list items template. I read in another thread that you can try to add this to the listConfig:
The description looks promising like it should solve our problem (allowing different row heights) although it does not have any effect in my situation.Code:variableHeights: true
Also I strongly agree about your point about the generated HTML by Sencha. The output from 2.0.1.1 is more efficient and allows for better flow of your elements.
-
25 Nov 2012 10:05 AM #3
welcome to the club: http://www.sencha.com/forum/showthre...leHeights-true
As a work around I found out that adding a deferred refresh() on the list helps most of the time.
-
25 Nov 2012 11:14 AM #4
Partial solution and another bug uncovered
Partial solution and another bug uncovered
Browsing through the source code I found the (documented) config "itemHeight" which in my case works (at least for most items) as the heights in this specific list are constant. So just setting that (in this case to 114) made the initial rendering of the list almost correct.
The new bug is that when you set the itemHeight, _and_ have grouped items (yes I have those :P), the first item in the group is not positioned correctly because the group header seems to be a part of the list item itself. As with the initial rendering problem, this is all fixed when you scroll the list up and down some. The problem here is that the x-list-header is being rendered _inside_ the x-list-item.
I tried using the variableHeights and refresh() suggestions and they didn't work for me. Ingo could you supply a snippet showing how you use refresh()? I tried it on the console and nothing happened.
The new absolutely positioned list items seem to try to guess what the DOM elements will be rendered to, and this will break in a lot of cases. I'd rather then not try to calculate those in advance and leave it to the browser to adjust the heights at actual render time. The rendering only happens once so it should not be very expensive.Last edited by jdrowell; 25 Nov 2012 at 11:22 AM. Reason: clarification
-
25 Nov 2012 11:18 AM #5
I indeed also tried setting 'itemHeight' and although this does what it promises, I preferably do not use it. Just because I use percentages for my width values in my item template, so the content scales nicely with the end-users resolution. If I set the items height to a fixed value that of course stops working.
Using the refresh function is not an option since I am working with a NestedList and this function seems to be only present in the List component. Thanks for your suggestion though. Switching back to 2.0.1 seems to be the best solution for now.
-
25 Nov 2012 11:32 AM #6
I get my list data from a server. I have autoLoad=false and do a store.load() in my controller. In the store loads callback I then do this:
I noticed that doing a refresh() immediately does not change anything. It needs to be deferred.Code:// refresh the list to update the item heights var myList = this.getMyList(); Ext.defer(function(){ myList.refresh(); }, 100, myList);
I have pics and icons in my lists. So without the refresh the lists are really messy until one resizes the browser window...
-
25 Nov 2012 9:17 PM #7
Tks for the code ingo. I think that works in your case because the list has already been painted. In my case calling refresh does nothing. I add lists to a TabPanel at startup.
I hacked a bit more on this and have a very ugly workaround. Here's how I fix the heights for a list:
list.fixItemHeights = function () {
list.getItems().first().items.each(function(item) {
list.updatedItems.push(item);
});
list.updateItemHeights();
list.updateScrollerSize();
};
Basically you have to push all list items into the "updateItems" array and the force an update. There are still big problems with this. First, it only worked deferred, even when called from the "painted" event. In my box I'm deferring this by 100ms:
painted: function(el, eOpts) {
var me = list;
console.log('painted');
console.log(me);
setTimeout( function () { list.fixItemHeights(); }, 100);
},
Second, if you resize the browser window, the wrong sizes actually _come back_ to haunt you. So you have to fire this in the "resize" event also. Lots of blinking. But, it's a starting point for getting this fixed, now we need to clean it up. I'll look into hooking up other events to get rid of the defer, but I must say I was really disappointed that the "painted" event is not ready for DOM lookups yet, being that the description for the event states exactly that.
-
26 Nov 2012 4:50 AM #8
This css fixed that for me
This css fixed that for me
.x-list-item
{
position: absolute;
top:0;
width:100%;
}
-
26 Nov 2012 5:37 AM #9
-
26 Nov 2012 5:43 AM #10
I'm not using the default css, that's why I had problems
I'm not using the default css, that's why I had problems
Maybe it's just me.
You found a bug! We've classified it as
TOUCH-3781
.
We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.


Reply With Quote