Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set scroll-target on an iron-list within an app-header-layout with has-scrolling-region

I am trying to use an iron-list (and iron-scroll-threshold) within a app-header-layout with has-scrolling-region.

I generated the basic app layout with the polymer-CLI.

If I do not use has-scrolling-region on the app-header-layout and use "document" for scroll-target on the iron-list it kinda works. But with this solution the scrollbar belongs to the window and does not slide beneath the header and I obviously cannot get the nice "waterfall" behaviour that is usually associated with these kinds of layouts.

Therefore, I use has-scrolling-region on the app-header-layout, but what is the right way to pass the corresponding scoller to the scroll-target property of the iron-list?

  <!-- Main content -->
  <app-header-layout has-scrolling-region id="layout">
    <app-header condenses reveals effects="waterfall">
      <app-toolbar>
        <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
        <div title>Twiamo</div>
      </app-toolbar>
    </app-header>

    <iron-pages role="main" selected="[[page]]" attr-for-selected="name" id="page">
      <my-iron-list name="view1" scroll-target="[[_getScrollTarget()]]"></my-iron-list>
      <my-view2 name="view2"></my-view2>
      <my-view3 name="view3"></my-view3>
    </iron-pages>
  </app-header-layout>

I looked into the implementation of app-header-layout to find the right element. This expression actually yields me the right element and everything works fine.

_getScrollTarget: function() {
    return this.$.layout.shadowRoot.querySelector("#contentContainer");        
}

But there has to be a better, a right way? Grabbing into the shadow DOM of the app-header-layout is not exactly using "public interface"!

To complete the example, here my code for my-iron-list. My-iron-list wraps and iron-list, iron-scroll-theshold, and some dummy data provider stuff. The scroll-target on my-iron-list is just passed to the iron-list and iron-scroll-threshold within my-iron-list:

<dom-module id="my-iron-list">
  <template>
    <iron-list items="[]" as=item id="list" scroll-target="[[scrollTarget]]">
      <template>
        <div class="item">[[item]]</div>
      </template>
    </iron-list>

    <iron-scroll-threshold
        id="scrollTheshold"
        lower-threshold="100"
        on-lower-threshold="_loadMoreData"
        scroll-target="[[scrollTarget]]">      
    </iron-scroll-threshold>    
  </template>

  <script>
    Polymer({

      is: 'my-iron-list',

      properties: {
        page: {
            type : Number,
            value : 0
        },
        perPage: {
            type : Number,
            value : 100
        },
        scrollTarget: HTMLElement,
      },

      _pushPage: function() {
          for (i = 0; i < this.perPage; i++) {
            this.$.list.push('items', 'Entry number ' + (i+1+this.page*this.perPage));   
          }
      },

      _loadMoreData: function() {
          this._pushPage();
          this.page = this.page + 1;
          this.$.scrollTheshold.clearTriggers();
      }
    });
  </script>
</dom-module>
like image 926
Markus Avatar asked May 31 '16 11:05

Markus


2 Answers

I have the same problem as you, for now the cleanest anwser I have was to use the app-header scrollTarget.

In your case move add an id to the app-header

 <app-header condenses reveals effects="waterfall" id="header">
      <app-toolbar>
        <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
        <div title>Twiamo</div>
      </app-toolbar>
 </app-header>

and then instead of

_getScrollTarget: function() {
    return this.$.layout.shadowRoot.querySelector("#contentContainer");        
}

just use the scrollTarget property

_getScrollTarget: function() {
    return this.$.header.scrollTarget;     
}

If you found out a better way let me know.

Cheers,

like image 149
José Manuel da Costa Santos Avatar answered Jan 04 '23 10:01

José Manuel da Costa Santos


I struggled with the same issue. While I was using iron-scroll-target-behavior instead of iron-scroll-threshold, I still needed to pass a scroll-target reference to an element inside a app-layout-header.

If has-scrolling-region is true, app-header-layout sets the scroll-target to be an internal div with an ID of #contentContainer. You can target this div and pass it as the scroll-target to your iron-list.

You would just need to alter the _getScrollTarget function inside your original code.

_getScrollTarget: function() {
    return this.$.layout.$.contentContainer;     
}

Hope it helps!

like image 39
Aundra Miller Avatar answered Jan 04 '23 11:01

Aundra Miller