Expandable cards with dynamic content loading skeleton stop working when created with {{#each}}...{{/each}} handlebars

It is possible to have expandable cards to work with dynamic content…
I am using

<template>
<div class="page">
  <div class="navbar">
    <div class="navbar-inner sliding">
      <div class="left">
        <a href="#" class="link back">
          <i class="icon icon-back"></i>
          <span class="ios-only">Back</span>
        </a>
      </div>
      <div class="title">Cards Expandable</div>
    </div>
  </div>
  <div class="page-content">




    <div class="demo-expandable-cards">

      <div class="card card-expandable" data-id="1">
        <div class="card-content">


          <div data-pagination='{"el": ".swiper-pagination"}' data-navigation='{"nextEl": ".swiper-button-next", "prevEl": ".swiper-button-prev"}' data-lazy='{"enabled": true}'
          class="swiper-container swiper-init hotels hotels-swiper-multiple hotels-swiper-multiple-auto">
            <div class="swiper-wrapper">


              <div class="swiper-slide swiper-lazy ease" data-background="https://cdn.framework7.io/placeholder/nature-1024x1024-1.jpg">
                <div class="preloader swiper-lazy-preloader"></div>

                <ul class="hotel-name">
                  <li>
                    <p>Hotel Sharaton Trento</p>
                  </li>
                </ul>
                <a href="#" class="link card-close card-opened-fade-in color-white" style="position: absolute; right: 15px; top: 15px">
                  <i class="icon f7-icons">close_round_fill</i>
                </a>

              </div>

              <div class="swiper-slide swiper-lazy ease" data-background="https://cdn.framework7.io/placeholder/nature-1024x1024-2.jpg">
                <div class="preloader swiper-lazy-preloader"></div>
                <a href="#" class="link card-close card-opened-fade-in color-white" style="position: absolute; right: 15px; top: 15px">
                  <i class="icon f7-icons">close_round_fill</i>
                </a>

              </div>

            </div>
            <div class="swiper-pagination"></div>
          </div>



          <div class="card-header text-color-black display-block" style="height: 60px">
            Beach, Goa
          </div>
          <div class="card-content-padding">


            <div class="list media-list">
              <ul>
                {{#if loading}}
                {{#each '1'}}
                  <li class="item-content skeleton-text skeleton-effect-{{../effect}}">
                    <div class="item-media">
                      <div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
                    </div>
                    <div class="item-inner">
                      <div class="item-title-row">
                        <div class="item-title">Full Name</div>
                      </div>
                      <div class="item-subtitle">Position</div>
                      <div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis. Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi aliquet urna, nec imperdiet felis sapien at enim.</div>
                    </div>
                  </li>
                {{/each}}
                {{else}}

                {{#each content}}

                <li class="item-content">
                  <div class="item-media">
                    <img src="https://placeimg.com/80/80/people/1" style="width: 40px; height: 40px; border-radius: 50%">
                  </div>
                  <div class="item-inner">
                    <div class="item-text">{{name}}</div>
                  </div>
                </li>
                {{/each}}


                {{/if}}
              </ul>
            </div>





          </div>
        </div>
      </div>


      <div class="card card-expandable" data-id="1">
        <div class="card-content">


          <div data-pagination='{"el": ".swiper-pagination"}' data-navigation='{"nextEl": ".swiper-button-next", "prevEl": ".swiper-button-prev"}' data-lazy='{"enabled": true}'
          class="swiper-container swiper-init hotels hotels-swiper-multiple hotels-swiper-multiple-auto">
            <div class="swiper-wrapper">


              <div class="swiper-slide swiper-lazy ease" data-background="https://cdn.framework7.io/placeholder/nature-1024x1024-1.jpg">
                <div class="preloader swiper-lazy-preloader"></div>

                <ul class="hotel-name">
                  <li>
                    <p>Hotel Sharaton Trento</p>
                  </li>
                </ul>
                <a href="#" class="link card-close card-opened-fade-in color-white" style="position: absolute; right: 15px; top: 15px">
                  <i class="icon f7-icons">close_round_fill</i>
                </a>

              </div>

              <div class="swiper-slide swiper-lazy ease" data-background="https://cdn.framework7.io/placeholder/nature-1024x1024-2.jpg">
                <div class="preloader swiper-lazy-preloader"></div>
                <a href="#" class="link card-close card-opened-fade-in color-white" style="position: absolute; right: 15px; top: 15px">
                  <i class="icon f7-icons">close_round_fill</i>
                </a>

              </div>

            </div>
            <div class="swiper-pagination"></div>
          </div>



          <div class="card-header text-color-black display-block" style="height: 60px">
            Beach, Goa
          </div>
          <div class="card-content-padding">


            <div class="list media-list">
              <ul>
                {{#if loading}}
                {{#each '1'}}
                  <li class="item-content skeleton-text skeleton-effect-{{../effect}}">
                    <div class="item-media">
                      <div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
                    </div>
                    <div class="item-inner">
                      <div class="item-title-row">
                        <div class="item-title">Full Name</div>
                      </div>
                      <div class="item-subtitle">Position</div>
                      <div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis. Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi aliquet urna, nec imperdiet felis sapien at enim.</div>
                    </div>
                  </li>
                {{/each}}
                {{else}}

                {{#each content}}

                <li class="item-content">
                  <div class="item-media">
                    <img src="https://placeimg.com/80/80/people/1" style="width: 40px; height: 40px; border-radius: 50%">
                  </div>
                  <div class="item-inner">
                    <div class="item-text">{{name}}</div>
                  </div>
                </li>
                {{/each}}


                {{/if}}
              </ul>
            </div>





          </div>
        </div>
      </div>



    </div>
  </div>
</div>
</template>


<script>
  return {
    data: function() {
      return {
        content : null,
        loading: false,
        effect: null,
      }
    },
    methods: {

      load: function (effect) {
        var self = this;
        if (self.loading) return;
        self.$setState({
          effect: effect,
          loading: true,
        });
        setTimeout(function() {
          self.$setState({ loading: false });
        }, 3000);
      }

    },

    on: {
      pageMounted: function(e, page) {
        console.log('pageMounted', page);
      },
      pageInit: function(e, page) {
        console.log('pageInit', page);
        var self = this;


        $(".card").on("card:beforeopen", function(el, prevent) {
          console.log(prevent);
          //el.detail.prevent();

          console.log({id:$(el.target).data('id')});


          console.log('fade');
          self.load('blink');


          app.request({
            headers: {
              'Authorization': app.data.servertoken,
            },
            url: 'core/js/autocomplete-languages.json',
            dataType: 'json',
            async: true,
            method: 'POST',
            cache: false,
            tryCount: 0, //starting request,,,
            retryLimit: 5, //no of retries...
            timeout: 35000, //must set so it doesnt request forever, between trials...
            data: '',
            crossDomain: true,
            statusCode: {
              404: function(xhr) {
                console.log('not found');
              },
              500: function(xhr) {
                console.log('syntax error!');
              }

            },
            beforeSend: function() {
              console.log('beforeSend');
            },
            complete: function() {
              console.log('complete');
            },
            success: function(content) {
              console.log('success');
              console.log(content);

              setTimeout(function() {
                self.$setState({
                  content: content,
                });
              }, 1000);



            },
            error: function(xhr, textStatus, errorThrown) {

              console.log('error flights...')
              console.log(xhr);

            }
          });



        });

        $(".card").on("card:open", function(el) {
          console.log("popup:open");

        });

        $(".card").on("card:opened", function(el) {
          console.log("popup:opened");

        });

        $(".card").on("card:close", function(el) {
          console.log("popup:close");


                        setTimeout(function() {
                          self.$setState({
                            content : null,
                            loading: false,
                            effect: null,
                          });
                        }, 100);


        });

        $(".card").on("card:closed", function(el) {
          console.log("popup:closed");

        });

      },
      pageBeforeOut: function(e, page) {
        console.log('pageBeforeOut', page);
      },
      pageAfterOut: function(e, page) {
        console.log('pageAfterOut', page);
      },
      pageBeforeRemove: function(e, page) {
        console.log('pageBeforeRemove', page);
      },
    }

  }
</script>  

but the problem it is that the skeleton and loading stop working when printing all cards dynamically using handlebars each for each items… also with infinite scrolling not working anymore… loading and skeleton not working anymore using each handlebars to create the list… :frowning:

<template>
<div class="page">
  <div class="navbar">
    <div class="navbar-inner sliding">
      <div class="left">
        <a href="#" class="link back">
          <i class="icon icon-back"></i>
          <span class="ios-only">Back</span>
        </a>
      </div>
      <div class="title">Cards Expandable</div>
    </div>
  </div>
  <div class="page-content">



    {{#each items}}
    <div class="demo-expandable-cards">

      <div class="card card-expandable" data-id="1">
        <div class="card-content">


          <div data-pagination='{"el": ".swiper-pagination"}' data-navigation='{"nextEl": ".swiper-button-next", "prevEl": ".swiper-button-prev"}' data-lazy='{"enabled": true}'
          class="swiper-container swiper-init hotels hotels-swiper-multiple hotels-swiper-multiple-auto">
            <div class="swiper-wrapper">


              <div class="swiper-slide swiper-lazy ease" data-background="https://cdn.framework7.io/placeholder/nature-1024x1024-1.jpg">
                <div class="preloader swiper-lazy-preloader"></div>

                <ul class="hotel-name">
                  <li>
                    <p>Hotel Sharaton Trento</p>
                  </li>
                </ul>
                <a href="#" class="link card-close card-opened-fade-in color-white" style="position: absolute; right: 15px; top: 15px">
                  <i class="icon f7-icons">close_round_fill</i>
                </a>

              </div>

              <div class="swiper-slide swiper-lazy ease" data-background="https://cdn.framework7.io/placeholder/nature-1024x1024-2.jpg">
                <div class="preloader swiper-lazy-preloader"></div>
                <a href="#" class="link card-close card-opened-fade-in color-white" style="position: absolute; right: 15px; top: 15px">
                  <i class="icon f7-icons">close_round_fill</i>
                </a>

              </div>

            </div>
            <div class="swiper-pagination"></div>
          </div>



          <div class="card-header text-color-black display-block" style="height: 60px">
            Beach, Goa
          </div>
          <div class="card-content-padding">


            <div class="list media-list">
              <ul>
                {{#if loading}}
                {{#each '1'}}
                  <li class="item-content skeleton-text skeleton-effect-{{../effect}}">
                    <div class="item-media">
                      <div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
                    </div>
                    <div class="item-inner">
                      <div class="item-title-row">
                        <div class="item-title">Full Name</div>
                      </div>
                      <div class="item-subtitle">Position</div>
                      <div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis. Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi aliquet urna, nec imperdiet felis sapien at enim.</div>
                    </div>
                  </li>
                {{/each}}
                {{else}}

                {{#each content}}

                <li class="item-content">
                  <div class="item-media">
                    <img src="https://placeimg.com/80/80/people/1" style="width: 40px; height: 40px; border-radius: 50%">
                  </div>
                  <div class="item-inner">
                    <div class="item-text">{{name}}</div>
                  </div>
                </li>
                {{/each}}


                {{/if}}
              </ul>
            </div>





          </div>
        </div>
      </div>
      {{/each}}




    </div>
  </div>
</div>
</template>


<script>
  return {
    data: function() {
      return {
        content : null,
        loading: false,
        effect: null,
        items: app.data.cards_to_load
      }
    },
    methods: {

      load: function (effect) {
        var self = this;
        if (self.loading) return;
        self.$setState({
          effect: effect,
          loading: true,
        });
        setTimeout(function() {
          self.$setState({ loading: false });
        }, 3000);
      }

    },

    on: {
      pageMounted: function(e, page) {
        console.log('pageMounted', page);
      },
      pageInit: function(e, page) {
        console.log('pageInit', page);
        var self = this;


        $(".card").on("card:beforeopen", function(el, prevent) {
          console.log(prevent);
          //el.detail.prevent();

          console.log({id:$(el.target).data('id')});


          console.log('fade');
          self.load('blink');


          app.request({
            headers: {
              'Authorization': app.data.servertoken,
            },
            url: 'core/js/autocomplete-languages.json',
            dataType: 'json',
            async: true,
            method: 'POST',
            cache: false,
            tryCount: 0, //starting request,,,
            retryLimit: 5, //no of retries...
            timeout: 35000, //must set so it doesnt request forever, between trials...
            data: '',
            crossDomain: true,
            statusCode: {
              404: function(xhr) {
                console.log('not found');
              },
              500: function(xhr) {
                console.log('syntax error!');
              }

            },
            beforeSend: function() {
              console.log('beforeSend');
            },
            complete: function() {
              console.log('complete');
            },
            success: function(content) {
              console.log('success');
              console.log(content);

              setTimeout(function() {
                self.$setState({
                  content: content,
                });
              }, 1000);



            },
            error: function(xhr, textStatus, errorThrown) {

              console.log('error flights...')
              console.log(xhr);

            }
          });



        });

        $(".card").on("card:open", function(el) {
          console.log("popup:open");

        });

        $(".card").on("card:opened", function(el) {
          console.log("popup:opened");

        });

        $(".card").on("card:close", function(el) {
          console.log("popup:close");


                        setTimeout(function() {
                          self.$setState({
                            content : null,
                            loading: false,
                            effect: null,
                          });
                        }, 100);


        });

        $(".card").on("card:closed", function(el) {
          console.log("popup:closed");

        });

      },
      pageBeforeOut: function(e, page) {
        console.log('pageBeforeOut', page);
      },
      pageAfterOut: function(e, page) {
        console.log('pageAfterOut', page);
      },
      pageBeforeRemove: function(e, page) {
        console.log('pageBeforeRemove', page);
      },
    }

  }
</script>

any solution?
thanks

Would be good to see JSFiddle with the issue

1 Like

The issue only occurs when using handlebars to print the cards using for instance

{{#each items}} 

... card to print... 

{{/each}}

Using handlebars, any element inside the card stops working… in my case I have the skeleton to show something is to be loaded and I load external data and show the results on screen…

This does not work when I use handlebars to print the items…

{{#each items}}

… card to print…

{{/each}}

I will try to load to JSFiddle …

I couldn’t upload to Fiddle … but here I send you the link to the .zip file with the two samples of extendable cards with dynamic content …

here the link:
https://mega.nz/#!EUpB1QwA!wFYA0m4l3yJbNOHrZpymlNqgQQTBIKcyq0CeAcrMfG0

The one created with handlebars is not working. The skeleton not showing and the loading of dynamic content not working… but in the console the content it is there…

I will appreciate your reply to spot the issue. thanks

You just have error in template, it should be {{#if ../loading}}

1 Like

Sorry You are right! if inside {{#each items}} it should be …/ for the others… my fault…

Yes now I had to change the skeleton effect to

<li class="item-content skeleton-text skeleton-effect-{{../../../effect}}">

and it works!!!

do you think that I can put any element inside expandable cards and it should work?
I need to include tabs inside expandable cards so I can click the card and load everything dynamically…

thanks for spotting the error!! It was my fault not viewing this simple thing! now I know it can work for my purpose!!!

big thanks

now the working code looks like:

          {{#each items}}
....

  {{#if ../loading}}
                      {{#each '1'}}
                        <li class="item-content skeleton-text skeleton-effect-{{../../../effect}}">
                          <div class="item-media">
                            <div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
                          </div>
                          <div class="item-inner">
                            <div class="item-title-row">
                              <div class="item-title">Full Name</div>
                            </div>
                            <div class="item-subtitle">Position</div>
                            <div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis. Praesent nec
                              pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi aliquet urna, nec imperdiet felis sapien at enim.</div>
                          </div>
                        </li>
                      {{/each}}
                    {{else}}

                      {{#each ../../items}}

                        <li class="item-content">
                          <div class="item-media">
                            <img src="https://placeimg.com/80/80/people/1" style="width: 40px; height: 40px; border-radius: 50%">
                          </div>
                          <div class="item-inner">
                            <div class="item-text">{{name}}</div>
                          </div>
                        </li>
                      {{/each}}


                    {{/if}}            

I share something that serves me, modify it to your needs.

  <template>
  <div class="page" data-name="about">
   <div class="navbar" style="background-color:white;">
  <div class="navbar-inner sliding">
    <div class="left">
      <a href="#" class="link back">
        <i class="icon icon-back"></i>
        <span class="ios-only">Back</span>
      </a>
    </div>
    <div class="title">Sesiones Creadas</div>
  </div>
</div>
<div class="page-content">
  <div class="card">
    <div class="card-content">
      <div class="list media-list">
        <ul>
          {{#if loading}}
            {{#each 'users  '}}

              <li class="item-content skeleton-text skeleton-effect-blink">
                <div class="item-media"><i class="f7-icons color-custom">person_round_fill</i></div>
                <div class="item-inner">
                  <div class="item-title-row">
                    <div class="item-title">loading...</div>
                  </div>
                  <div class="item-subtitle">
                    loading...<br>
                    loading...
                  </div>
                </div>
              </li>
            {{/each}}
          {{else}}

            {{#each users}}

              <li class="item-content">

                <div class="item-media">
                  <i class="f7-icons color-custom">person_round_fill</i>
                </div>
                <div class="item-inner">
                  <div class="item-title-row">
                    <div class="item-title">{{nombre}}</div>
                  </div>
                  <div class="item-subtitle">
                    Correo: {{correo}}<br>
                    Telefono: {{telefono}}
                  </div>
                </div>
              </li>

            {{/each}}
          {{/if}}
        </ul>
      </div>
    </div>
    </div>

    </div>
  </div>
 </template>

        <script>
        return {
       data: function() {
         return {
           loading: true,
            users: []

          }
       },
          on: {
         pageInit: function() {
            var self = this;
          var app = self.$app;
          let _users = [];
          var este = dbstore.collection("martin")
          este.get().then((querySnapshot) => {
            querySnapshot.forEach((doc) => {
               _users.push({
                id: doc.id,
                correo: doc.data().correo,
               nombre: doc.data().nombre,
               telefono: doc.data().telefono
              })
             self.$setState({
               users: _users,
            });
             self.$setState({
              loading: false
            });
          });
        });
        
      },
     },
   };
  </script>

play eliminating the {{each}} and just leave the if and in the script try to load this in some button self.$setState ({
loading: false
});

2 Likes

great job!! I think it is nice to see it working with skeleton :slight_smile: :wink:

1 Like