How to Paginate a Computed Property in Vue











up vote
0
down vote

favorite












I am creating a Vue app, where a list of jobs will be displayed and this data is coming from a JSON object. In this app I also am adding filtering functionality as well as pagination. So what I have so far is:



    <div id="app" v-cloak>

<h2>Location</h2>
<select v-model="selectedLocation" v-on:change="setPages">
<option value="">Any</option>
<option v-for="location in locations" v-bind:value="location" >{{ location }}</option>
</select>

<div v-for="job in jobs">

<a v-bind:href="'/job-details-page/?entity=' + job.id"><h2>{{ job.title }}</h2></a>
<div v-if="job.customText12"><strong>Location:</strong> {{ job.customText12 }}</div>

</div>

<div class="paginationBtns">
<button type="button" v-if="page != 1" v-on:click="page--">Prev</button>
<button type="button" v-for="pageNumber in pages.slice(page-1, page+5)" v-on:click="page = pageNumber"> {{pageNumber}} </button>
<button type="button" v-if="page < pages.length" v-on:click="page++">Next</button>
</div>




<script>

var json = <?php echo getBhQuery('search','JobOrder','isOpen:true','id,title,categories,dateAdded,externalCategoryID,employmentType,customText12', null, 200, '-dateAdded');?>;
json = JSON.parse(json);
var jsonData = json.data;

var app = new Vue({
el: '#app',
data() {
return {
//assigning the jobs JSON data to this variable
jobs: jsonData,

locations: ['Chicago', 'Philly', 'Baltimore'],

//Used to filter based on selected filter options
selectedLocation: '',

page: 1,
perPage: 10,
pages: ,
}
},

methods: {
setPages () {
this.pages = ;
let numberOfPages = Math.ceil(this.jobs.length / this.perPage);
for (let i = 1; i <= numberOfPages; i++) {
this.pages.push(i);
}
},

paginate (jobs) {
let page = this.page;
let perPage = this.perPage;
let from = (page * perPage) - perPage;
let to = (page * perPage);
return jobs.slice(from, to);
},
}

watch: {
jobs () {
this.setPages();
}
},

})


computed: {

filteredJobs: function(){
var filteredList = this.jobs.filter(el=> {
return el.customText12.toUpperCase().match(this.selectedLocation.toUpperCase())
});

return this.paginate(filteredList);
}

}


</script>


So the issue I am running into is that I want the amount of pages to change when the user filters the list using the select input. The list itself changes, but the amount of pages does not, and there ends up being a ton of empty pages once you get past a certain point.



I believe the reason why this is happening is the amount of pages is being set based on the length of the jobs data object. Since that never changes the amount of pages stays the same as well. What I need to happen is once the setPages method is ran it needs to empty the pages data array, then look at the filteredJobs object and find the length of that instead of the base jobs object.



The filteredJobs filtering is a computed property and I am not sure how to grab the length of the object once it has been filtered.



EDIT: Okay so I added this into the setPages method:



let numberOfPages = Math.ceil(this.filteredJobs.length / this.perPage);


instead of



let numberOfPages = Math.ceil(this.jobs.length / this.perPage);


and I found out it is actually grabbing the length of filteredJobs, but since I am running the paginate method on that computed property, it is saying there is only 10 items in the filteredJobs array currently and will only add one pagination page. So grabbing the length of filteredJobs may not be the best route for this. Possibly setting a data variable to equal the filtered jobs object may be better and grab the length of that.










share|improve this question
























  • Hi @user9664977 can you replicate this issue on jfiddle and post the link here ?
    – Mazino S Ukah
    Nov 7 at 15:01










  • You should put your filter into another computed method and call paginate on that one. Then you can easily get the length of the filtered array.
    – Mroz
    Nov 7 at 15:37










  • @Mroz Okay awesome making it to separate computed properties instead of trying to do it all in one worked! Thanks!
    – user9664977
    Nov 7 at 16:15















up vote
0
down vote

favorite












I am creating a Vue app, where a list of jobs will be displayed and this data is coming from a JSON object. In this app I also am adding filtering functionality as well as pagination. So what I have so far is:



    <div id="app" v-cloak>

<h2>Location</h2>
<select v-model="selectedLocation" v-on:change="setPages">
<option value="">Any</option>
<option v-for="location in locations" v-bind:value="location" >{{ location }}</option>
</select>

<div v-for="job in jobs">

<a v-bind:href="'/job-details-page/?entity=' + job.id"><h2>{{ job.title }}</h2></a>
<div v-if="job.customText12"><strong>Location:</strong> {{ job.customText12 }}</div>

</div>

<div class="paginationBtns">
<button type="button" v-if="page != 1" v-on:click="page--">Prev</button>
<button type="button" v-for="pageNumber in pages.slice(page-1, page+5)" v-on:click="page = pageNumber"> {{pageNumber}} </button>
<button type="button" v-if="page < pages.length" v-on:click="page++">Next</button>
</div>




<script>

var json = <?php echo getBhQuery('search','JobOrder','isOpen:true','id,title,categories,dateAdded,externalCategoryID,employmentType,customText12', null, 200, '-dateAdded');?>;
json = JSON.parse(json);
var jsonData = json.data;

var app = new Vue({
el: '#app',
data() {
return {
//assigning the jobs JSON data to this variable
jobs: jsonData,

locations: ['Chicago', 'Philly', 'Baltimore'],

//Used to filter based on selected filter options
selectedLocation: '',

page: 1,
perPage: 10,
pages: ,
}
},

methods: {
setPages () {
this.pages = ;
let numberOfPages = Math.ceil(this.jobs.length / this.perPage);
for (let i = 1; i <= numberOfPages; i++) {
this.pages.push(i);
}
},

paginate (jobs) {
let page = this.page;
let perPage = this.perPage;
let from = (page * perPage) - perPage;
let to = (page * perPage);
return jobs.slice(from, to);
},
}

watch: {
jobs () {
this.setPages();
}
},

})


computed: {

filteredJobs: function(){
var filteredList = this.jobs.filter(el=> {
return el.customText12.toUpperCase().match(this.selectedLocation.toUpperCase())
});

return this.paginate(filteredList);
}

}


</script>


So the issue I am running into is that I want the amount of pages to change when the user filters the list using the select input. The list itself changes, but the amount of pages does not, and there ends up being a ton of empty pages once you get past a certain point.



I believe the reason why this is happening is the amount of pages is being set based on the length of the jobs data object. Since that never changes the amount of pages stays the same as well. What I need to happen is once the setPages method is ran it needs to empty the pages data array, then look at the filteredJobs object and find the length of that instead of the base jobs object.



The filteredJobs filtering is a computed property and I am not sure how to grab the length of the object once it has been filtered.



EDIT: Okay so I added this into the setPages method:



let numberOfPages = Math.ceil(this.filteredJobs.length / this.perPage);


instead of



let numberOfPages = Math.ceil(this.jobs.length / this.perPage);


and I found out it is actually grabbing the length of filteredJobs, but since I am running the paginate method on that computed property, it is saying there is only 10 items in the filteredJobs array currently and will only add one pagination page. So grabbing the length of filteredJobs may not be the best route for this. Possibly setting a data variable to equal the filtered jobs object may be better and grab the length of that.










share|improve this question
























  • Hi @user9664977 can you replicate this issue on jfiddle and post the link here ?
    – Mazino S Ukah
    Nov 7 at 15:01










  • You should put your filter into another computed method and call paginate on that one. Then you can easily get the length of the filtered array.
    – Mroz
    Nov 7 at 15:37










  • @Mroz Okay awesome making it to separate computed properties instead of trying to do it all in one worked! Thanks!
    – user9664977
    Nov 7 at 16:15













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am creating a Vue app, where a list of jobs will be displayed and this data is coming from a JSON object. In this app I also am adding filtering functionality as well as pagination. So what I have so far is:



    <div id="app" v-cloak>

<h2>Location</h2>
<select v-model="selectedLocation" v-on:change="setPages">
<option value="">Any</option>
<option v-for="location in locations" v-bind:value="location" >{{ location }}</option>
</select>

<div v-for="job in jobs">

<a v-bind:href="'/job-details-page/?entity=' + job.id"><h2>{{ job.title }}</h2></a>
<div v-if="job.customText12"><strong>Location:</strong> {{ job.customText12 }}</div>

</div>

<div class="paginationBtns">
<button type="button" v-if="page != 1" v-on:click="page--">Prev</button>
<button type="button" v-for="pageNumber in pages.slice(page-1, page+5)" v-on:click="page = pageNumber"> {{pageNumber}} </button>
<button type="button" v-if="page < pages.length" v-on:click="page++">Next</button>
</div>




<script>

var json = <?php echo getBhQuery('search','JobOrder','isOpen:true','id,title,categories,dateAdded,externalCategoryID,employmentType,customText12', null, 200, '-dateAdded');?>;
json = JSON.parse(json);
var jsonData = json.data;

var app = new Vue({
el: '#app',
data() {
return {
//assigning the jobs JSON data to this variable
jobs: jsonData,

locations: ['Chicago', 'Philly', 'Baltimore'],

//Used to filter based on selected filter options
selectedLocation: '',

page: 1,
perPage: 10,
pages: ,
}
},

methods: {
setPages () {
this.pages = ;
let numberOfPages = Math.ceil(this.jobs.length / this.perPage);
for (let i = 1; i <= numberOfPages; i++) {
this.pages.push(i);
}
},

paginate (jobs) {
let page = this.page;
let perPage = this.perPage;
let from = (page * perPage) - perPage;
let to = (page * perPage);
return jobs.slice(from, to);
},
}

watch: {
jobs () {
this.setPages();
}
},

})


computed: {

filteredJobs: function(){
var filteredList = this.jobs.filter(el=> {
return el.customText12.toUpperCase().match(this.selectedLocation.toUpperCase())
});

return this.paginate(filteredList);
}

}


</script>


So the issue I am running into is that I want the amount of pages to change when the user filters the list using the select input. The list itself changes, but the amount of pages does not, and there ends up being a ton of empty pages once you get past a certain point.



I believe the reason why this is happening is the amount of pages is being set based on the length of the jobs data object. Since that never changes the amount of pages stays the same as well. What I need to happen is once the setPages method is ran it needs to empty the pages data array, then look at the filteredJobs object and find the length of that instead of the base jobs object.



The filteredJobs filtering is a computed property and I am not sure how to grab the length of the object once it has been filtered.



EDIT: Okay so I added this into the setPages method:



let numberOfPages = Math.ceil(this.filteredJobs.length / this.perPage);


instead of



let numberOfPages = Math.ceil(this.jobs.length / this.perPage);


and I found out it is actually grabbing the length of filteredJobs, but since I am running the paginate method on that computed property, it is saying there is only 10 items in the filteredJobs array currently and will only add one pagination page. So grabbing the length of filteredJobs may not be the best route for this. Possibly setting a data variable to equal the filtered jobs object may be better and grab the length of that.










share|improve this question















I am creating a Vue app, where a list of jobs will be displayed and this data is coming from a JSON object. In this app I also am adding filtering functionality as well as pagination. So what I have so far is:



    <div id="app" v-cloak>

<h2>Location</h2>
<select v-model="selectedLocation" v-on:change="setPages">
<option value="">Any</option>
<option v-for="location in locations" v-bind:value="location" >{{ location }}</option>
</select>

<div v-for="job in jobs">

<a v-bind:href="'/job-details-page/?entity=' + job.id"><h2>{{ job.title }}</h2></a>
<div v-if="job.customText12"><strong>Location:</strong> {{ job.customText12 }}</div>

</div>

<div class="paginationBtns">
<button type="button" v-if="page != 1" v-on:click="page--">Prev</button>
<button type="button" v-for="pageNumber in pages.slice(page-1, page+5)" v-on:click="page = pageNumber"> {{pageNumber}} </button>
<button type="button" v-if="page < pages.length" v-on:click="page++">Next</button>
</div>




<script>

var json = <?php echo getBhQuery('search','JobOrder','isOpen:true','id,title,categories,dateAdded,externalCategoryID,employmentType,customText12', null, 200, '-dateAdded');?>;
json = JSON.parse(json);
var jsonData = json.data;

var app = new Vue({
el: '#app',
data() {
return {
//assigning the jobs JSON data to this variable
jobs: jsonData,

locations: ['Chicago', 'Philly', 'Baltimore'],

//Used to filter based on selected filter options
selectedLocation: '',

page: 1,
perPage: 10,
pages: ,
}
},

methods: {
setPages () {
this.pages = ;
let numberOfPages = Math.ceil(this.jobs.length / this.perPage);
for (let i = 1; i <= numberOfPages; i++) {
this.pages.push(i);
}
},

paginate (jobs) {
let page = this.page;
let perPage = this.perPage;
let from = (page * perPage) - perPage;
let to = (page * perPage);
return jobs.slice(from, to);
},
}

watch: {
jobs () {
this.setPages();
}
},

})


computed: {

filteredJobs: function(){
var filteredList = this.jobs.filter(el=> {
return el.customText12.toUpperCase().match(this.selectedLocation.toUpperCase())
});

return this.paginate(filteredList);
}

}


</script>


So the issue I am running into is that I want the amount of pages to change when the user filters the list using the select input. The list itself changes, but the amount of pages does not, and there ends up being a ton of empty pages once you get past a certain point.



I believe the reason why this is happening is the amount of pages is being set based on the length of the jobs data object. Since that never changes the amount of pages stays the same as well. What I need to happen is once the setPages method is ran it needs to empty the pages data array, then look at the filteredJobs object and find the length of that instead of the base jobs object.



The filteredJobs filtering is a computed property and I am not sure how to grab the length of the object once it has been filtered.



EDIT: Okay so I added this into the setPages method:



let numberOfPages = Math.ceil(this.filteredJobs.length / this.perPage);


instead of



let numberOfPages = Math.ceil(this.jobs.length / this.perPage);


and I found out it is actually grabbing the length of filteredJobs, but since I am running the paginate method on that computed property, it is saying there is only 10 items in the filteredJobs array currently and will only add one pagination page. So grabbing the length of filteredJobs may not be the best route for this. Possibly setting a data variable to equal the filtered jobs object may be better and grab the length of that.







javascript vue.js pagination filtering






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 7 at 13:55

























asked Nov 7 at 13:44









user9664977

357




357












  • Hi @user9664977 can you replicate this issue on jfiddle and post the link here ?
    – Mazino S Ukah
    Nov 7 at 15:01










  • You should put your filter into another computed method and call paginate on that one. Then you can easily get the length of the filtered array.
    – Mroz
    Nov 7 at 15:37










  • @Mroz Okay awesome making it to separate computed properties instead of trying to do it all in one worked! Thanks!
    – user9664977
    Nov 7 at 16:15


















  • Hi @user9664977 can you replicate this issue on jfiddle and post the link here ?
    – Mazino S Ukah
    Nov 7 at 15:01










  • You should put your filter into another computed method and call paginate on that one. Then you can easily get the length of the filtered array.
    – Mroz
    Nov 7 at 15:37










  • @Mroz Okay awesome making it to separate computed properties instead of trying to do it all in one worked! Thanks!
    – user9664977
    Nov 7 at 16:15
















Hi @user9664977 can you replicate this issue on jfiddle and post the link here ?
– Mazino S Ukah
Nov 7 at 15:01




Hi @user9664977 can you replicate this issue on jfiddle and post the link here ?
– Mazino S Ukah
Nov 7 at 15:01












You should put your filter into another computed method and call paginate on that one. Then you can easily get the length of the filtered array.
– Mroz
Nov 7 at 15:37




You should put your filter into another computed method and call paginate on that one. Then you can easily get the length of the filtered array.
– Mroz
Nov 7 at 15:37












@Mroz Okay awesome making it to separate computed properties instead of trying to do it all in one worked! Thanks!
– user9664977
Nov 7 at 16:15




@Mroz Okay awesome making it to separate computed properties instead of trying to do it all in one worked! Thanks!
– user9664977
Nov 7 at 16:15

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53190691%2fhow-to-paginate-a-computed-property-in-vue%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53190691%2fhow-to-paginate-a-computed-property-in-vue%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud

Zucchini