Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

md-virtual-repeat does not work without predefined height #4314

Closed
uriva opened this issue Aug 25, 2015 · 42 comments
Closed

md-virtual-repeat does not work without predefined height #4314

uriva opened this issue Aug 25, 2015 · 42 comments
Labels
- Lots of Comments g3: reported The issue was reported by an internal or external product team. P4: minor Minor issues. May not be fixed without community contributions. resolution: works as expected The functionality works as designed and documented.
Milestone

Comments

@uriva
Copy link

uriva commented Aug 25, 2015

codepen: http://codepen.io/uriva/pen/doxdVP

@Pusnow
Copy link

Pusnow commented Aug 25, 2015

I think md-virtual-repeat-container should have fixed height

@uriva
Copy link
Author

uriva commented Aug 25, 2015

Yup. That was the issue. Perhaps a doc clarification on that point?

@Pusnow
Copy link

Pusnow commented Aug 25, 2015

I referred to official doc's sample codes

@uriva uriva changed the title md-virtual-repeat does not work inside a table md-virtual-repeat does not work without predefined height Aug 26, 2015
@ThomasBurleson ThomasBurleson modified the milestone: 0.12.0 Sep 2, 2015
@ghost
Copy link

ghost commented Sep 3, 2015

+1 Would be nice to figure out a way to allow flexable heights.

@kseamon
Copy link
Contributor

kseamon commented Sep 8, 2015

It's on my to-do list. It's tricky because any solution comes with performance trade-offs.

@0xdevalias
Copy link

+1 This tripped me up for a while, a note on the docs would be cool.

@colinskow
Copy link
Contributor

Here's my workaround in the mean time:

this.getListHeight = function() {
  return {height: '' + ($window.innerHeight - 72) + 'px'};
};
$window.addEventListener('resize', onResize);
function onResize() {
  $scope.$digest();
}
$scope.$on('$destroy', function() {
  $window.removeEventListener('resize', onResize);
});

Then in the HTML

<md-virtual-repeat-container id="vertical-container" ng-style="ctrl.getListHeight()">
...
</md-virtual-repeat-container>

@Madd0g
Copy link

Madd0g commented Oct 10, 2015

@colinskow - Thanks, it's close to working, it works for me on refresh, but not on regular state-changes
(Note that I'm measuring the parent node of the virtual list, not the body like in your example).

A huge +1 for making virtual-repeat flexable.

@colinskow
Copy link
Contributor

@Madd0g - I actually refactored it a little bit and it seems to work better. At least on Safari and Chrome it always appears to be the right size.

this.listStyle = {
      height: ($window.innerHeight - 112) + 'px'
    };
    $window.addEventListener('resize', onResize);
    function onResize() {
      self.listStyle.height = ($window.innerHeight - 112) + 'px';
      if(!$scope.$root.$$phase) $scope.$digest();
    }
<md-virtual-repeat-container id="vertical-container" ng-style="ctrl.listStyle">
...
</md-virtual-repeat-container>

@Madd0g
Copy link

Madd0g commented Oct 10, 2015

@colinskow - that does work better, but it seems like the internal md-list doesn't get resized to the necessary height, I don't even understand what causes it to be smaller in size, I've combed through the styles tab and don't see anything that can cause it :(

EDIT: it's not a CSS issue, the problem is that the virtual repeater runs before that sizing script and renders a smaller number of items. Maybe there's a way to solve it with a directive and priorities?

EDIT: this is my solution, it calls an internal setSize_ method of the virtual container:

return {
    restrict: 'A',
    require: '^mdVirtualRepeatContainer',
    link: function(scope, element, attributes, mdVirtualRepeatContainer) 
    {
        angular.element(element).css('height', element[0].parentNode.offsetHeight + 'px');

        scope.$watch(function ()
        {
            return element[0].parentNode.offsetHeight;
        }, function(value){
            angular.element(element).css('height', value + 'px');
            mdVirtualRepeatContainer.setSize_(value);
        });
    }
};

@colinskow
Copy link
Contributor

@Madd0g if I open and close the Javascript console or developer tools, it will thereafter render an incorrect height. As long as I don't do that, my implementation seems to render correctly.

Do you have a CodePen to demonstrate your issue?

@colinskow
Copy link
Contributor

Here's my CSS that is working perfectly. Note that the repeat items all must be the EXACT specified height without any padding or overflow, otherwise scrolling will be really glitchy.

#vertical-container {
    min-height: 300px;
    width: 100%;
}

.repeated-item {
    border-bottom: 1px dotted #757575;
    box-sizing: border-box;
    height: 50px;
    overflow: hidden;
    margin-right: 16px;
}

The min-height on the container seems to be important. This is later overridden by the actual height from your script. Also, overflow: hidden on the repeat item keeps any items from accidentally getting taller than 50px.

@Madd0g
Copy link

Madd0g commented Oct 11, 2015

@colinskow - it's definitely something about my HTML that's causing it (and weirdly it only breaks on ui-router state change, not a page refresh), but the directive I posted solves my problem perfectly, so I'm not worried, it will be enough for me until the virtual repeater is officially flexable.

Thanks for your help

@ThomasBurleson ThomasBurleson modified the milestones: 1.0-rc1, 1.0-rc2 Oct 27, 2015
@guiporto
Copy link

+1

1 similar comment
@SpenceDiNicolantonio
Copy link

+1

@ThomasBurleson ThomasBurleson modified the milestones: Deprecated, Backlog Apr 20, 2016
@ThomasBurleson
Copy link
Contributor

This issue is closed as part of our deprecation effort.
For details, see our post Spring Cleaning 2016.

@johnSowingo
Copy link

+1

2 similar comments
@wallzero
Copy link

+1

@AndrewEastwood
Copy link

+1

@timactive
Copy link

+1

1 similar comment
@davidwilcox
Copy link

+1

@Jervelund
Copy link

Please use the reaction feature instead of posting more "+1" updates to this thread.

@warent
Copy link

warent commented Sep 17, 2016

@jualvarez It is, but that was some time ago. I'll see if I can remake it using the latest updates and if so I'll submit a PR :)

@nkoterba
Copy link

@Jervelund

Please use the reaction feature instead of posting more "+1" updates to this thread.

I'm a little out of touch following the MD issues, what do you mean by 'reaction feature'?

@Jervelund
Copy link

Sorry for not being clearer. Read about reactions here:
https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments

On 18 Sep 2016 23:17, "nkoterba" notifications@github.com wrote:

@Jervelund https://github.com/Jervelund

Please use the reaction feature instead of posting more "+1" updates to
this thread.

I'm a little out of touch following the MD issues, what do you mean by
'reaction feature'?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#4314 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AEA4eqcuDtAqyKAoGLQFpX3cQIVnqttMks5qrapfgaJpZM4FxlKR
.

@davasqueza
Copy link

I found a little workaround that worked for me, first make a class like this:

.virtual-repeat-full-height{
  height: 100%;
  position: initial;
}

and next in the HTLM do something like this:

<md-content flex>
  <md-virtual-repeat-container class="virtual-repeat-full-height">
    <div md-virtual-repeat="thing in vm.things" md-on-demand>{{thing.name}}</div>
  </md-virtual-repeat-container>
</md-content>

PD: sorry for my english

@iRealNirmal
Copy link

I added below css

.md-autocomplete-suggestions-container{
    .md-virtual-repeat-sizer{
        height:auto!important;
    }
}

@tylerjames
Copy link

Has anyone found a reliable way to set the height using a directive or otherwise?

Ideally the height would be responsive, but without setting it explicitly in the CSS the virtual repeat container will not layout anything at all.

I've tried setting it in the link function of a directive but simply attaching a directive to my md-virtual-repeat-container element will cause it to not lay out any items, even if the directive doesn't do anything.

@tylerjames
Copy link

tylerjames commented Jan 30, 2017

Ugh.

The problem with my directive was that it had a controller attached to it and that was preventing it from working properly when I eventually did find the correct method.

Here is a working directive that will resize the container:

(function (){
	'use strict';

	angular.module('vyNewReportModule').directive('runtimeHeight', runtimeHeight);
	function runtimeHeight() {
		var directive = {
			link: link,
			require: 'mdVirtualRepeatContainer'
		};
		return directive;

		function link(scope, elem, attr, mdVirtualRepeatContainer) {
			elem.css('height', newSize);			
		}
	}
})();

Doesn't seem like mdVirtualRepeatContainer.updateSize(); or anything like that is even needed.

federicoiosue pushed a commit to federicoiosue/omni-notes-desktop that referenced this issue May 31, 2017
@0101adm
Copy link

0101adm commented Aug 23, 2017

+1 responsive

@mckinleymedia
Copy link

mckinleymedia commented Aug 28, 2017

None of those answers quite worked for me. I ended up coding a new solution. This one just updates with window resize. In my build, I've got a fixed footer.

angular.module('app')
  .directive('updateSize',['$window', function ($window) {
        return {
            restrict: 'A',
            require: '^mdVirtualRepeatContainer',
            link: function(scope, element, attributes, mdVirtualRepeatContainer) {
                var footer = 45;
                function getHeight() {
                  var height = $window.innerHeight - (element[0].getBoundingClientRect().top + footer);
                  angular.element(element).css('height', height + 'px');
                  return height;
                }
                function onResize() {
                  mdVirtualRepeatContainer.setSize_(getHeight());
                }
                getHeight();
                angular.element($window).on('resize', onResize);
            }
        };
      }
  ]);

Then add it here:
<md-virtual-repeat-container update-size>...

@isaacwein
Copy link

isaacwein commented Dec 12, 2018

for me this worked

md-virtual-repeat-container {
    height: calc(100vh - 75px);
}

@Splaktar
Copy link
Member

There is work happening in PR #11516 to allow variable height items in autocomplete via ng-repeat instead of md-virtual-repeat.

Also the Angular CDK has a *cdkVirtualFor directive that can be used in Angular or hybrid projects to create a virtual scroll component that can have items of different heights.

@angular angular locked as resolved and limited conversation to collaborators Dec 12, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
- Lots of Comments g3: reported The issue was reported by an internal or external product team. P4: minor Minor issues. May not be fixed without community contributions. resolution: works as expected The functionality works as designed and documented.
Projects
None yet
Development

No branches or pull requests