0

I am trying to create a pagination feature to display html blocks in increments of 2 and then a user can choose a page. The amount of blocks it'll go through is defined by a v-for. Here's the block of code to show this

<template v-for="(ad, index) in ads" v-cloak>
                  <div class="box ad-box" v-if="showAds(index)" @click="hideInput(index)">
                    <span> {{ lines(index, 'headline1') }} | </span>
                    <span> {{ lines(index, 'headline2') }} | </span>
                    <span> {{ lines(index, 'headline3') }} </span>
                    <span class="icon is-pulled-right has-text-grey-light has-text-weight-light" @click="deleteAd()">
                      <div v-show="ad.boolean">
                        <p class="">X</p>
                      </div>
                    </span>
                    <br>
                    <p><span class="is-size-7">{{lines(index, 'finalurl')}}</span><span class="is-size-7 has-text-success" v-if="lines(index, 'path1') !== '' ">/{{lines(index, 'path1')}}/{{lines(index,'path2')}}</span></p>
                    <span class="is-size-7 is-grey">{{lines(index, 'desc1') + lines(index, 'desc2')}} </span>
                  </div>
                  <br />
</template>
                <nav class="pagination" role="navigation" aria-label="pagination">
                  <ul class="pagination-list">
                    <li>
                      <a class="pagination-link is-current">1</a>
                    </li>
                    <li v-show="ads.length > 2">
                      <a class="pagination-link" @click="adPage = 2">2</a>
                    </li>
                    <li v-show="ads.length > 4">
                      <a class="pagination-link" @click="adPage = 3">3</a>
                    </li>
                    <li v-show="ads.length > 6">
                      <a class="pagination-link" @click="adPage = 4">4</a>
                    </li>
                    <li v-show="ads.length > 8">
                      <a class="pagination-link" @click="adPage = 5">5</a>
                    </li>
                  </ul>
                </nav>

I've got adPage in the data property to keep track of when a user clicks on a page and the page numbers will only appear as the proper amount of templates is actually available. I've got simple logic in a function but not really sure where to go from here. I was thinking I would check the index of what's being iterated and check it to be within a delta of 2 from what ever that adPage is.

newAds:[
  [
    {
      id: 0,
    headline1: 'first 1',
    headline2: 'Headline 2',
    headline3: 'headline3',
    desc1: 'This is your description 1',
    desc2: 'This is your description 2',
    finalurl: 'www.finalURL.com',
    path1: '',
    path2: '',
    boolean: true
    },
    {
     id: 0,
    headline1: 'first 2',
    headline2: 'Headline 2',
    headline3: 'headline3',
    desc1: 'This is your description 1',
    desc2: 'This is your description 2',
    finalurl: 'www.finalURL.com',
    path1: '',
    path2: '',
    boolean: false
    }
  ],
  [
    {
      id: 1,
    headline1: 'second 1',
    headline2: 'Headline 2',
    headline3: 'headline3',
    desc1: 'This is your description 1',
    desc2: 'This is your description 2',
    finalurl: 'www.finalURL.com',
    path1: '',
    path2: '',
    boolean: false
    },
    {
     id: 1,
    headline1: 'second 2',
    headline2: 'Headline 2',
    headline3: 'headline3',
    desc1: 'This is your description 1',
    desc2: 'This is your description 2',
    finalurl: 'www.finalURL.com',
    path1: '',
    path2: '',
    boolean: false
    }
  ]
]
1
  • You should use a computed to get the slice of ads that go on the current page, and v-for over that. For your page list, do v-for="p in Math.ceil(ads.length / 2)" Commented Jan 31, 2019 at 1:08

1 Answer 1

1

Here's a snippet showing what I mentioned in my comment. You can even change the number of ads per page

new Vue({
  el: '#app',
  data: {
    perPage: 2,
    ads: ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ay', 'bee', 'cee'],
    adPage: 1
  },
  computed: {
    currentAds() {
      const startIndex = this.perPage * (this.adPage - 1);
      const endIndex = startIndex + this.perPage;
      return this.ads.slice(startIndex, endIndex);
    }
  }
});
.is-current {
  font-weight: bold;
}
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app">
  <input v-model.number="perPage">
  <template v-for="(ad, index) in currentAds" v-cloak>
    <div>{{ad}}</div>
  </template>
  <nav class="pagination" role="navigation" aria-label="pagination">
    <ul class="pagination-list">
      <li v-for="p in Math.ceil(ads.length/perPage)">
        <a class="pagination-link" :class="{'is-current': adPage == p}" @click="adPage = p">{{p}}</a>
      </li>
    </ul>
  </nav>
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for that! I got part of it to work but I've also got inputs that correspond to what ever box a user clicks. I've set up a full version of what i've got in Codepen if you wouldn't mind taking a look. When I create a new ad the second page is created and my form inputs also correspond to the ad showing but when I click an ad on a page other than 1, it changes to index 0 or 1 rather than index 4 or 5 or what ever the index should be on the higher pages. codepen.io/luis4flames/pen/exgdLx
I notice that you're passing index from your v-for on currentAds to hideInput, which uses it in ads. The indexes do not correlate. Instead of passing index, you could pass the ad itself.
Hey hoping you can help with this snippet one more time. How would this work if the array currentAds is pulling from is an array full of arrays containing objects(ads). I edited the post to show an example of what I mean, 'newAds'
So you have to flatten a level of arrays to make it a single array?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.