Calcultate collection item height of collection repeat

I’m trying to achieve this as well but curious if there’s any way to calculate the height after it’s been rendered to the dom or have access to the div via the custom getItemHeight function.

I have a list of div’s where the text could vary between 3-6 rows and would be nice to get the innerHeight or scrollHeight of the inside content to determine the height and force it to that.

Right now I only see access to the index and the item object

Any hints to where to start? I’ve looked into the renderItem function in the ionic code but still a bit lost

Thanks

This is also my question.
Since calculating the height of an item is the key to use collection repeat,
I think it should be described with more detail in the doc/manual.

1 Like

I’m also in search of a way to do this.

I am thinking along the lines of:

  $scope.getItemHeight = function(item) {
    return angular.element(item).offsetHeight;
  };

But this doesn’t seem to work. Anyone else know how to do this?

Discourse, the forums that we’re using here on the Ionic site funnily enough, have implemented a solution for Ember. I’ve not read the code closely, but the same logic/underlying principles should work within Ionic too:

http://eviltrout.com/2014/01/04/hiding-offscreen-ember.html

It’s close, but I still can’t quite figure out how this can be achieved. Anyone had some luck with this? @mhartington?

After doing some digging we can conclude that at this stage collection-repeat can not be used when the height of an item is unknown before the list renders. For instance when your items consists of text elements that have varying lengths. One item might have 20 characters leading it to have one height, the other item might have 8 characters, giving it a smaller height. In this scenario, collection-repeat is not useable in its current form.

More information can be found here:

and

1 Like

I’m having the same issue, I have a list of items that vary in height, it seems like there are a bunch of us.

I haven’t spent the time to look at the collection repeat code but I’m guessing that it calculates which items to display based on the scroll position and the height of the item. If so, for fast scrolling (large swipes) would it be possible to give collection repeat a minimum item height and have it display items based on a minimum height and for slow scrolling (viewing each item after item) just display the next items. Also, once an item is displayed but is no longer on screen collection repeat could keep that items height for more accurate scrolling incase the user scrolls back up. Does that make sense? Would that be possible or are my guesses of how collection repeat works totally off?

BTW, Ionic rocks!! Thanks for building it.

@Tom, a lot of this has already been tested when building collection repeat. When we reworked a bit a few release ago, the second option was tested and proved to kill performance. The collection repeat is right now is probably the best it will be for now

Hi @mhartington!

After this months, I don’t know if the thread is too old, but is there a way to use collection-repeat with different heightselements?

This is my current scenario:

Regards!
Thanks you guys for the great work with Ionic!!!

Could be necesary to add this css?

.item-content 
{
height: 100%;
}

My code is this:

<ion-list>
	  <ion-item 
	  collection-repeat="row in rows"
	  collection-item-height="100"
	  ng-click="navigate(row)" style="width:100%; height:100px">
		Id: {{row.id}}
		Customer: {{row.customercontact}} {{row.customerlocation.customer.name}} {{row.customerlocation.fulladdress}}
		<ion-option-button class="button-assertive" ng-click="edit(row)">Edit</ion-option-button>
		<ion-option-button class="button-positive" ng-click="delete(row)">Delete</ion-delete-button>
	  </ion-item>
	</ion-list>

Tested in web browser and ionic v.1.0.0 beta 13

how about this example? codepen

in controller

  $scope.getHeight = function (check) {
            if (check == null)
            {
                return 53;
            }
            else
            {
                return 70;
            }

};
in html–>

 <div collection-repeat="list in List1"
                         item-height="getHeight(list.FloorBlockName)">

same problem i faced…i did like this. :slight_smile:

Still no great solution to use collection-repeat with items that have variable height that must be calculated on the fly (like text written by users, simply).

1 Like

I solved this by pre-calculating the height of the items when created using a dummy measurement div and save it on the item.

1 Like

Hi,

Can you explain how you did that?

Thanks

Hello yohairosen,

I am trying to do something similar. I created a dummy element (which is a custom directive) and I compiled it against an isolated scope (created with $rootScope.$new()). I updated the directive’s scope with each of my items but since it is not rendered in the actual DOM how did you get the size ?

In order for the CSS rules to be applied did you insert it in the view ? Do you have a dummy directive as hidden ? But then how do you get the size for each item since by updating the scope of that element will not update the content instantly.

Thank you

I encountered the same use case and I would like to share my solution for the problem.

First I created a dummy list-item that has the same style as the collection repeat (same width, icons, classes …).
Also add the specific style (visibility:hidden) to keep the height of the item, but don’t show it to the user.

<ion-item id="dummyItem" class="item-text-wrap item-icon-right" style="visibility: hidden;">
      <i class="icon ion-ios-arrow-forward"></i>
    </ion-item>

You can place this anywhere on your page (preferrably just before ion-content gets closed).

In the controller of the page, I create a dummy variable that holds the element of the dummyItem.
This makes sure that we don’t have to do an “getElementById” everything a dynamic height has to be calculated.
var dummy = document.getElementById("dummyItem");
I’ve placed this code at the top of the controller, outside a function, so it gets assigned with the load of the page.

The method to calculate the height works pretty easy. The text that you want to display gets passed to the function and the dummy text is changed with the received text.
After that we get the height of the dummyItem and return that.

$scope.getHeight = function(text)
{
dummy.textContent = text;
return dummy.clientHeight;
}

Back in the HTML of our collection-repeat, we add the item-height directive and pass the text of you want to use.

item-height="getHeight(article.name)

This has a very small hit on performance of the list, but in most cases you won’t even notice it. I’ve tested it with a list of 3300+ dynamic items and it just great and smooth.

1 Like

Is it possible to somehow use this direction:

thanks a lot
very nice

1 Like

This last comment is related to? :slight_smile: