Hey Guys,
I am trying to split my responses from my RSS feed reader up into pages. I'm doing this by populating a feedList array with RSS Items, and taking 2 items at a time to display and placing them in a displayList array connected to an ng-repeat. When you click next page it will update the displayList array with 2 new items from the feedArray.
I got a simplified version running with an array of names http://jsfiddle.net/halfasleep/ZJFke/4/
When I tried to implement it with the feed reader code, it doesn't populate the displayList array before trying to display it, when you hit "Next Page" it will drop some items into the displayList array and start to display it (though for some reason only moving 1 item at a time instead of 2). Any help would be appreciated!
JS Fiddle: http://jsfiddle.net/WDL8U/
Html
<html ng-app="FeedReader">
<head>
<meta charset="UTF-8">
<title>Reader Trial</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular-resource.js"></script>
<link rel="stylesheet" href="FeedReader.css" />
</head>
<body ng-controller="blogCtrl">
There are {{feedList.length}} entries.
<ul class="blogPosts" ng-class="listClass" ng-init="populate();">
<li ng-repeat="list in displayList"><h2><a ng-click="publish(list.content);">{{list.title}}</a></h2><p>{{list.contentSnippet}}</p><span> - {{list.author}}</span></li>
</ul>
<div class="blogPosts fullWidth" style="height: 500px; overflow: scroll;" ng-hide="noCont" ng-bind-html="htmlContent"></div>
<div style="clear: both;">
<a ng-click="prev()" ng-hide="hideP">Previous Page</a>
<a ng-click="next()" ng-hide="hideN">Next Page</a>
</div>
<script src="./feedReader2.js"></script>
</body>
</html>
JS
var feedList = [];
var displayList = [];
var app = angular.module('FeedReader',['ngResource']);
app.factory('feedLoader',['$resource', function($resource){
var googleAPI = $resource('http://ajax.googleapis.com/ajax/services/feed/load',{},{
collect: {
method: 'JSONP',
params: {
v: '1.0',
callback: 'JSON_CALLBACK'
}
}
});
return googleAPI;
}]);
app.service('createFeedList',['feedLoader', function(feedLoader){
this.get = function(){
var feed = {
feedName: 'Slashdot',
feedURL: 'http://rss.slashdot.org/Slashdot/slashdot'
};
feedLoader.collect({
q: feed.feedURL,
num: 10
},{},function(result){
var feed = result.responseData.feed.entries;
for(i = 0; i < feed.length; i++){
feedList.push(feed[i]);
}
});
return feedList;
}
}]);
app.controller('blogCtrl',['$scope', '$sce', 'createFeedList', function($scope, $sce, createFeedList){
$scope.feedList = createFeedList.get();
// Page Code
$scope.hideP = true;
var begin = 0;
var end = 2;
$scope.displayList = [$scope.feedList[begin],$scope.feedList[end]];
$scope.next = function(){
if(end <= $scope.feedList.length - 2){
begin += 2;
end += 2;
$scope.displayList = [$scope.feedList[begin],$scope.feedList[end]];
$scope.hideP = false;
}
if(end == $scope.feedList.length-1) {
$scope.hideN = true;
}
}
$scope.prev = function(){
if(end == 3){
$scope.hideP = true;
}
if(end >= 1) {
begin -= 2;
end -= 2;
$scope.displayList = [$scope.feedList[begin],$scope.feedList[end]];
$scope.hideN = false;
}
}
// Display Content Code
$scope.noCont = true;
$scope.listClass = 'fullWidth';
$scope.publish = function(cont) {
$scope.noCont = false;
$scope.htmlContent = $sce.trustAsHtml(cont);
$scope.listClass = 'halfWidth';
}
}]);
You need to return a promise and then populate $scope.feedList when the data is ready. Then you can perform actions on the other $scope variables as well. Give this a try:
var feedList = [];
var displayList = [];
var app = angular.module('FeedReader',['ngResource']);
app.factory('feedLoader',['$resource', function($resource){
var googleAPI = $resource('http://ajax.googleapis.com/ajax/services/feed/load',{},{
collect: {
method: 'JSONP',
params: {
v: '1.0',
callback: 'JSON_CALLBACK'
}
}
});
return googleAPI;
}]);
app.service('createFeedList',['feedLoader', '$q', function(feedLoader, $q){
this.get = function(){
var feed = {
feedName: 'Slashdot',
feedURL: 'http://rss.slashdot.org/Slashdot/slashdot'
};
var deferred = $q.defer();
feedLoader.collect({
q: feed.feedURL,
num: 10
},{},function(result){
var feed = result.responseData.feed.entries;
for(i = 0; i < feed.length; i++){
feedList.push(feed[i]);
}
deferred.resolve(feedList);
});
return deferred.promise;
}
}]);
app.controller('blogCtrl',['$scope', '$sce', 'createFeedList', function($scope, $sce, createFeedList){
//$scope.feedList = createFeedList.get();
createFeedList.get().then(function(data) {
$scope.feedList = data;
$scope.displayList = [$scope.feedList[begin],$scope.feedList[end]];
$scope.next = function(){
if(end <= $scope.feedList.length - 2){
begin += 2;
end += 2;
$scope.displayList = [$scope.feedList[begin],$scope.feedList[end]];
$scope.hideP = false;
}
if(end == $scope.feedList.length-1) {
$scope.hideN = true;
}
}
$scope.prev = function(){
if(end == 3){
$scope.hideP = true;
}
if(end >= 1) {
begin -= 2;
end -= 2;
$scope.displayList = [$scope.feedList[begin],$scope.feedList[end]];
$scope.hideN = false;
}
}
});
// Page Code
$scope.hideP = true;
var begin = 0;
var end = 2;
// Display Content Code
$scope.noCont = true;
$scope.listClass = 'fullWidth';
$scope.publish = function(cont) {
$scope.noCont = false;
$scope.htmlContent = $sce.trustAsHtml(cont);
$scope.listClass = 'halfWidth';
}
}]);
Hope that helps.
Related
I'm trying to put pagination with ng-repeat. Getting result but by the time showing old data and suddenly hide and show new set data, like jerking. My angularjs version is "1.5.8".
$scope.gap = 5;
$scope.filteredItems = [];
$scope.groupedItems = [];
$scope.itemsPerPage = 5;
$scope.pagedItems = [];
$scope.currentPage = 0;
var resultData = [...];
var searchMatch = function (haystack, needle) {
if (!needle) {
return true;
}
return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
};
// init the filtered items
$scope.search = function () {
$scope.filteredItems = $filter('filter')(resultData, function (item) {
for(var attr in item) {
if (searchMatch(item[attr], $scope.query))
return true;
}
return false;
});
// take care of the sorting order
$scope.currentPage = 0;
// now group by pages
$scope.groupToPages();
};
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.itemsPerPage === 0) {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
} else {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
}
}
console.log($scope.pagedItems)
};
$scope.range = function (size,start, end) {
var ret = [];
//console.log(size,start, end);
if (size < end) {
end = size;
start = size-$scope.gap;
}
for (var i = start; i < end; i++) {
ret.push(i);
}
// console.log(ret);
return ret;
};
$scope.prevPage = function () {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.nextPage = function () {
if ($scope.currentPage < $scope.pagedItems.length - 1) {
$scope.currentPage++;
}
};
$scope.setPage = function () {
console.log($scope.pagedItems[$scope.currentPage]);
$scope.currentPage = this.n;
};
$scope.search();
html
<tr ng-repeat="user in pagedItems[currentPage]" >
<td>{{user.name}} {{$index}}</td>
</tr>
As above code, that table row update as 5 row. but when I click next or page numbers showing 10 rows and hide 5 rows. I hope you understand guys! Help me.
In my opinion you are thinking wrong, it's simpler to use custom filter and break up your business logic like this
app.filter('startFrom', function() {
return function(input, start) {
start = +start;
return input.slice(start);
}
});
then in the controller you can do
$scope.showResults = function() {
$scope.list = $filter('startFrom')($scope.initialList, $scope.page * $scope.itemsPerPage);
$scope.list = $filter('limitTo')($scope.list, $scope.itemsPerPage);
}
};
now you need only to update $scope.page and reuse $scope.showResults() to update the view
<tr ng-repeat="user in list" >
<td>{{user.name}} {{$index}}</td>
</tr>
I don't think that your problem is cause by ng-repeat. I just take your code, add some dummy data and do a test and it's totally work fine.
You can check it here https://codepen.io/Cushdrive/pen/zvPPXd
Because angular is two way binding, so I'm wonder that could it be some paging info was triggered somewhere. Could you double check on some variable like currentPage itemPerPages or pagedItems to see if it being used somewhere else?
I'm having problem displaying a JSON-object named "currentSet" from session-storage. When I instead use a JSON-file from a folder everything works fine, which means the HTML-code is probably fine. I have narrowed the problem down to either the $scope.set or the loadQuiz-function and have tried several things, but can't get it to work. This is the relevant parts from the controller:
$scope.set = angular.fromJson(sessionStorage.getItem('currentSet')); //doesn't work
//$scope.set = 'data/konflikter.js'; //works
$scope.defaultConfig = {
'autoMove': true,
'pageSize': 1,
'showPager': false
}
$scope.onSelect = function (question, choice) {
question.choices.forEach(function (element, index, array) {
question.Answered = choice;
});
if ($scope.defaultConfig.autoMove == true && $scope.currentPage < $scope.totalItems) {
$scope.currentPage++;
}
else {
$scope.onSubmit();
}
}
$scope.onSubmit = function () {
var answers = [];
$scope.questions.forEach(function (question, index) {
answers.push({'questionid': question._id, 'answer': question.Answered});
});
$http.post('https://fhsclassroom.mybluemix.net/api/quiz/submit', answers).success(function (data, status) {
$location.path('/');
});
}
$scope.pageCount = function () {
return Math.ceil($scope.questions.length / $scope.itemsPerPage);
};
$scope.loadQuiz = function (data) {
$http.get(data)
.then(function (res) {
$scope.name = res.data.name;
$scope.questions = res.data.questions;
$scope.totalItems = $scope.questions.length;
$scope.itemsPerPage = $scope.defaultConfig.pageSize;
$scope.currentPage = 1;
$scope.$watch('currentPage + itemsPerPage', function () {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.filteredQuestions = $scope.questions.slice(begin, end);
});
});
}
$scope.loadQuiz($scope.set);
Ok I figured out what's wrong, you are loading file so you need to get file - or import it to get the contents that's why it works with your:
$scope.set = 'data/konflikter.js'; //works but combined with http request
If you wish to pass data from dataStorage you will need to change your loadQuiz not to have http request like this:
$scope.loadQuiz = function (res) {
$scope.name = res.data.name;
$scope.questions = res.data.questions;
$scope.totalItems = $scope.questions.length;
$scope.itemsPerPage = $scope.defaultConfig.pageSize;
$scope.currentPage = 1;
$scope.$watch('currentPage + itemsPerPage', function () {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.filteredQuestions = $scope.questions.slice(begin, end);
});
}
With the help of #pegla I was able to solve the problem like this:
$scope.loadQuiz = function () {
$scope.set = angular.fromJson(sessionStorage.getItem('currentSet'));
$scope.questionsetid = $scope.set.questions[0].questionsetid;
$scope.name = $scope.set.name;
$scope.questions = $scope.set.questions;
$scope.totalItems = $scope.set.questions.length;
$scope.itemsPerPage = $scope.defaultConfig.pageSize;
$scope.currentPage = 1;
$scope.$watch('currentPage + itemsPerPage', function () {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.filteredQuestions = $scope.questions.slice(begin, end);
});
}
$scope.loadQuiz();
DEMO
I'am developing a Pagination Functionality using handlebars js and fetching the data from JSON.
First 5 results will be shown on page load.
on click of next pagination another set of 5 results will be displayed and so on.
If i have total number of results 100 by displaying each 5 Results in page. Page Numbers will be 1 of 20.
if the pagination has more then 5 number of Pages , I want to display "1,2,3 ... last Page Number (20)" same vice versa
on load Previous Button Should be hidden when ever next page is clicked it has to be enabled.
Request to you please look into this and give some advice / suggestion on this.
Should be Like Below
Appreciate your kind help !
Thanks
some code sample :
$(function () {
var opts = {
pageMax: 5,
postsDiv: $('#posts'),
dataUrl: "searchResult.json"
}
function range(i) { return i ? range(i - 1).concat(i) : [] }
function loadPosts(posts) {
opts.postsDiv.empty();
posts.each(function () {
var source = $("#post-template").html();
var template = Handlebars.compile(source);
var context = {
title: this.title,
desc: this.body,
};
var html = template(context);
opts.postsDiv.append(html);
});
}
function paginate(pageCount) {
var source = $("#pagination-template").html();
var template = Handlebars.compile(source);
var context = { pages: range(pageCount) };
var html = template(context);
opts.postsDiv.after(html);
function changePage(pageNumber) {
pageItems.removeClass('active');
pageItems.filter('[data-page="' + pageNumber + '"]').addClass('active');
loadPosts(data.slice(pageNumber * opts.pageMax - opts.pageMax, pageNumber * opts.pageMax));
}
var pageItems = $('.pagination>li.pagination-page');
pageItems.on('click', function () {
changePage(this.getAttribute('data-page'));
}).filter('[data-page="1"]').addClass('active');
$('.pagination>li.pagination-prev').on('click', function () {
gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) - 1;
if (gotoPageNumber <= 0) { gotoPageNumber = pageCount; }
changePage(gotoPageNumber);
});
$('.pagination>li.pagination-next').on('click', function () {
gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) + 1;
if (gotoPageNumber > pageCount) { gotoPageNumber = 1; }
changePage(gotoPageNumber);
});
}
$.ajax({
dataType: 'json',
url: opts.dataUrl,
success: function (response_json) {
data = $(response_json.records.page);
dataCount = data.length;
pageCount = Math.ceil(dataCount / opts.pageMax);
if (dataCount > opts.pageMax) {
paginate(pageCount);
posts = data.slice(0, opts.pageMax);
} else {
posts = data;
}
loadPosts(posts);
}
});
});
I had to solve a similar issue a few months ago. I found this Gist from kottenator.
Your range function is modified thusly, with c being the current page, and m your pageCount. Calls to the function have been modified a bit and a recursive call to your paginate(...) function is also added to recompute the tag after navigation (also, a branch was added to your DOM appending function calls, to modify the pagination tag, I used a ternary operator. There may be more elegant to achieve this).
See this CodePen
function range(c,m) {
var current = c || 1,
last = m,
delta = 2,
left = current - delta,
right = parseInt(current) + delta + 1,
range = [],
rangeWithEllipsis = [],
l,
t;
range.push(1);
for (var i = c - delta ; i <= c + delta ; i++) {
if (i >= left && i < right && i < m && i > 1) {
range.push(i);
}
}
range.push(m);
for (var i of range) {
if (l) {
if (i - l === 2) {
t = l+1;
rangeWithEllipsis.push(t);
} else if (i - l !== 1) {
rangeWithEllipsis.push("...");
}
}
rangeWithEllipsis.push(i);
l = i;
}
return rangeWithEllipsis;
}
It doesn't solve exactly your problem per say, but it does paginate correctly.
If I have some time, I'll try and make it paginate the exact way you want to (it's really only about customizing the delta, left and right operand in the algorithm, and changing your pagination next and pagination prev event handler calls).
Edit I changed the algorithm to find the left and right boundary. Your index.html is also modified a bit.
The idea is to compute the left and right boundary by multiples of 5. You then create a range of the indexes to show and add an elipsis if the difference is too big. This should effectively solves your original problem.
JavaScript
getFirstDigits = (t) => {
return parseInt(t.toString().slice(0,-1))
}
getLastDigit = (t) => {
return parseInt(t.toString().slice(-1))
}
isMultipleOf5 = (t) => {
return [0,5].reduce((res,curr)=>{
return res = res || curr === getLastDigit(t);
},false);
}
isBetween0and5 = (t) => {
const _t = getLastDigit(t);
return _t < 5;
}
isBetween5and9 = (t) => {
const _t = getLastDigit(t);
return _t => 5 && _t <= 9;
}
appendDigit = (t,d) => {
return parseInt(getFirstDigits(t).toString() + d.toString())
}
getSecondRightMostDigit = (t) => {
return parseInt(t.toString().slice(-2,-1))
}
incrementSecondDigit = (t) => {
return t+10;
}
getLeft = (t) => {
if(t>=10){
if(isBetween0and5(t)) return appendDigit(t,0);
else return appendDigit(t,5);
} else {
if (t<5) return 0;
else return 5;
}
}
getRight = (t) => {
if(t<5) return 5;
else if (t<10) return 10;
else if(isBetween0and5(t)) return appendDigit(t,5)
else return appendDigit(incrementSecondDigit(t),0);
}
function range(c,m) {
var current = c || 1,
last = m,
delta = 2,
left = getLeft(c),
right = getRight(c),
range = [],
rangeWithEllipsis = [],
l,
t;
var rightBoundary = right < 5 ? 5 : right;
for (var i = left ; i < rightBoundary ; ++i) {
if( i < m && i > 0) range.push(i);
}
range.push(m);
for (var i of range) {
if (l) {
if (i - l === 2) {
t = l+1;
rangeWithEllipsis.push(t);
} else if (i - l !== 1){
rangeWithEllipsis.push("...");
}
}
rangeWithEllipsis.push(i);
l = i;
}
return rangeWithEllipsis;
}
HTML/HandleBars
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Handlebars Pagination</title>
<link href="main.css" rel="stylesheet" />
<script src="jquery.min.js"></script>
<script src="handlebars.min.js"></script>
<script src="functions.js"></script>
</head>
<body class="container">
<div id="posts"></div>
<script id="pagination-template" type="text/x-handlebars-template">
<ul class="pagination">
<li class="pagination-prev">«</li>
{{#each pages}}
<li class="pagination-page" data-page="{{this}}">{{this}}</li>
{{/each}}
<li class="pagination-next">»</li>
</ul>
</script>
<script id="post-template" type="text/x-handlebars-template">
<div class="score-structural score-column2-wideright search-listings post">
<div class="score-right">
<h4>{{record_count}}</h4>
<h5 style="z-index: 1;">
{{ title }}
</h5>
<p style="z-index: 1;"> {{ desc }} </p>
</div>
</div>
<hr>
</script>
</body>
</html>
<script>
$(function () {
var opts = {
pageMax: 2,
postsDiv: $('#posts'),
dataUrl: "searchResult.json"
}
function loadPosts(posts) {
opts.postsDiv.empty();
posts.each(function () {
var source = $("#post-template").html();
var template = Handlebars.compile(source);
var context = {
title: this.title,
desc: this.body,
};
var html = template(context);
opts.postsDiv.append(html);
});
hidePrev();
}
function hidePrev() { $('.pagination .pagination-prev').hide(); }
function showPrev() { $('.pagination .pagination-prev').show(); }
function hideNext() { $('.pagination .pagination-next').hide(); }
function showNext() { $('.pagination .pagination-next').show(); }
function paginate(page,pageCount) {
var source = $("#pagination-template").html();
var template = Handlebars.compile(source);
var context = { pages: range(page,pageCount) };
console.log(range(page,pageCount));
var html = template(context);
var paginationTag = opts.postsDiv.parent().find(".pagination");
paginationTag.length > 0 ? paginationTag.replaceWith(html) : opts.postsDiv.before(html);
function changePage(page) {
pageItems.removeClass('active');
pageItems.filter('[data-page="' + page + '"]').addClass('active');
loadPosts(data.slice(page * opts.pageMax - opts.pageMax, page * opts.pageMax));
paginate(page,pageCount);
if (gotoPageNumber <= 1) {
hidePrev();
}
}
var pageItems = $('.pagination>li.pagination-page');
var pageItemsLastPage = $('.pagination li').length - 2;
pageItems.removeClass('active');
pageItems.filter('[data-page="' + page + '"]').addClass('active');
pageItems.on('click', function () {
getDataPageNo = this.getAttribute('data-page')
console.log(getDataPageNo)
changePage(getDataPageNo);
if (getDataPageNo == 1) {
hidePrev()
}
else if (getDataPageNo == pageItemsLastPage) {
hideNext();
}
else {
showPrev();
showNext();
}
});
$('.pagination>li.pagination-prev').on('click', function () {
gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) - 1;
changePage(gotoPageNumber);
});
$('.pagination>li.pagination-next').on('click', function () {
gotoPageNumber = parseInt($('.pagination>li.active').attr('data-page')) + 1;
if (gotoPageNumber > pageCount) {
gotoPageNumber = 1;
showPrev();
}
changePage(gotoPageNumber);
});
}
$.ajax({
dataType: 'json',
url: opts.dataUrl,
success: function (response_json) {
data = $(response_json.records.page);
dataCount = data.length;
pageCount = Math.ceil(dataCount / opts.pageMax);
if (dataCount > opts.pageMax) {
paginate(1,pageCount);
posts = data.slice(0, opts.pageMax);
} else {
posts = data;
}
loadPosts(posts);
}
});
});
</script>
Here is the page where I'm trying to display content. It's showing up blank. My application is a single page application, so most of the code is in the index.html file
verbPractice.html
<div>
<h1>Practice verbs here</h1>
<div class="row" ng-repeat="sentence in listOfSentences">
<div class="col-xs-12">
<p>{{sentence.first}} {{sentence.second}} {{sentence.third}}</p>
</div>
</div>
</div>
This page is linked to from another page called verbSelect.html. Here is the relevant code from that page
<div class="btn btn-primary" ui-sref="app.verbPractice" ng-click="storeInfo(); generateSentences()">Submit</div>
Both the above pages are under the same controller called verbController:
(function() {
'use strict';
angular.module('arabicApp')
.controller('verbController', ['$scope', 'verbFactory', 'pronounFactory', 'attachedFactory', function($scope, verbFactory, pronounFactory, attachedFactory){
//Gets verbs from server
$scope.verbArray = verbFactory.getVerbs().query(
function(response) {
$scope.verbArray = response;
}
);
//Gets pronouns from server
$scope.pronouns = pronounFactory.getPronouns().query(
function(response) {
$scope.pronouns = response;
}
);
$scope.attached = attachedFactory.getAttached().query(
function(response) {
$scope.attached = response;
}
);
//Stores the array of selected verbs
$scope.selectedVerbs = [];
$scope.numSelectedVerbs = 0;
//Searches theArray for name and returns its index. If not found, returns -1
$scope.searchArray = function(theArray, name) {
for (var i = 0; i < theArray.length; i++) {
if (theArray[i].name === name) {
return i;
}
}
return -1;
};
//Adds verbs to selected list
$scope.addToSelected = function(theVerb) {
var num = $scope.searchArray($scope.selectedVerbs, theVerb.name);
var divToChange = document.getElementById("verbSelect_"+theVerb.name);
if (num > -1) { //Found. Remeove it from selectedVerbs
$scope.selectedVerbs.splice(num, 1);
divToChange.className = divToChange.className.replace( /(?:^|\s)listItemActive(?!\S)/g , '' );
$scope.numSelectedVerbs = $scope.numSelectedVerbs - 1;
} else { //Not found. Add it in
$scope.selectedVerbs.push(theVerb);
divToChange.className += " listItemActive";
$scope.numSelectedVerbs = $scope.numSelectedVerbs + 1;
}
};
//Stores how many practice questions the user wants
$scope.howMany = 0;
//Stores what tense of verbs the user wants
$scope.verbTense = "Both";
//Stores what form the user wants
$scope.verbVoice = "Both";
//Include commands?
$scope.includeCommands = false;
//Sentense that will be generated
$scope.listOfSentences = [];
$scope.generateSentence = function(isCommand, theTense, theVoice) {
var sent = {"first": "", "second": "", "third": ""};
var attachedPicker = Math.floor(Math.random()*14);
var attachedToUse = $scope.attached[attachedPicker].attached;
var pronounPicker = Math.floor(Math.random()*14);
var pronounToUse = $scope.pronouns[pronounPicker].pronoun;
sent.first = pronounToUse;
var verbPicker = Math.floor(Math.random()*$scope.numSelectedVerbs);
var verbToUse = $scope.selectedVerbs[verbPicker][theTense][pronounToUse];
if (isCommand === true) {
sent.second = verbToUse;
} else {
if (theVoice === "Passive") {
if (theTense === "Past") { sent.second = "were"; }
else { sent.second = "are"; }
sent.third = verbToUse;
} else {
sent.second = verbToUse;
sent.third = attachedToUse;
}
}
return sent;
};
$scope.storeInfo = function() {
localStorage.setItem("howMany", $scope.howMany);
localStorage.setItem("verbTense", $scope.verbTense);
localStorage.setItem("verbVoice", $scope.verbVoice);
localStorage.setItem("includeCommands", $scope.includeCommands);
};
$scope.getStoredInfo = function() {
$scope.howMany = localStorage.getItem("howMany");
$scope.verbTense = localStorage.getItem("verbTense");
$scope.verbVoice = localStorage.getItem("verbVoice");
$scope.includeCommands = localStorage.getItem("includeCommands");
};
//Generates sentences using the variables from verbSelect
$scope.generateSentences = function() {
$scope.getStoredInfo();
var tensePicker;
var voicePicker;
var doCommand;
var rand;
for (var i = 0; i < $scope.howMany; i++) {
//Picks the verb tense
if ($scope.verbTense === "Both") {
rand = Math.floor(Math.random());
if (rand === 0) { tensePicker = "Past"; }
else { tensePicker = "Present"; }
} else {
tensePicker = $scope.verbTense;
}
//Picks the verb voice
if ($scope.verbVoice === "Both") {
rand = Math.floor(Math.random());
if (rand === 0) { voicePicker = "Active"; }
else { voicePicker = "Passive"; }
} else {
voicePicker = $scope.verbVoice;
}
//If the voice is passive, use past tense
if ($scope.verbVoice === "Passive") { tensePicker = "Past"; }
//Determines if the sentence will be a command sentence or not
if ($scope.includeCommands === true) {
rand = Math.floor(Math.random() * 6);
if (rand === 0) { doCommand = true; }
else { doCommand = false; }
} else {
doCommand = false;
}
var sentence = $scope.generateSentence(doCommand, tensePicker, voicePicker);
$scope.listOfSentences.push(sentence);
}
console.log($scope.listOfSentences);
};
}])
;
})();
The variables: howMany, verbTense, verbVoice, isCommand, are set on this verbSelect.html page using ng-model. Both the verbSelect.html page and verbPractice.html page are under the same controller.
Everything seems to be working fine. At the end of my generateSentences() function, I output $scope.listOfSentences to the log, and it shows up without any problems, the array is being populated just fine. However, in my verbPractice.html page, nothing is showing up except the <h1> heading. For some reason, even though the $scope.listOfSentences array is populated, ng-repeat doesn't seem to be looping. Does anyone have any idea why?
Sorry for the long post
Thanks for taking the time to read and answer this question!
I am trying to add pagination in Angular js.Sinch my server returns huge number of rows on each query So i am using some limit offset to get only 101 rows(required rows+1) at a time.(Building array of 20 pages ,reusing extra row value for next request.)
No- of rows per page=5
So on getting 101 rows means i can paginate upto 20 pages. Since i already have an extra row So i know there is more data left , So on next page request again am querying to get rows 101-201. But my doubt here is how to add logic in next page and previous page function and how to build next or previous set of data?
My app.js-
My 1st time request-
$scope.startingid = null;
$scope.numberofrows= 101;
Api.customer.query({ productId : $scope.customer , productperiod :$scope.customerPeriod,startingid:$scope.startingid,numberofrows:$scope.numberofrows }).$promise.then(function(result) {
if(result){
if(result&&result.length==0){
$scope.addErrorAlert("No Customer data found with this productId and Period.", true);
$scope.displayPage = 'search';
return;
}
$scope.customerResult = result;
$scope.displayPage = 'drill';
$scope.showData();
}
// Pagination Logic-
My code is working fine if result set is small number of data. But need to implement in such a way that it can handle large number of rows as well.
few doubts-
1. how to build the data for request 101-201.
2. next and previous page logic
$scope.paged = function (valLists,itemsPerPage)
{
var retVal = [];
for (var i = 0; i < valLists.length; i++) {
if (i % itemsPerPage === 0) {
retVal[Math.floor(i / itemsPerPage)] = [valLists[i]];
} else {
retVal[Math.floor(i / itemsPerPage)].push(valLists[i]);
}
}
return retVal;
};
$scope.pagination = function () {
$scope.ItemsByPage = $scope.paged( $scope.customerResult, $scope.itemsPerPage );
};
$scope.showData = function( ){
// $scope.noOfrows = 101;
$scope.itemsPerPage = 5;
$scope.currentPage = 0;
$scope.pagination();
$scope.range = function() {
var rangeSize = 4;
var ps = [];
var start;
start = $scope.currentPage;
if ( start > $scope.pageCount()-rangeSize ) {
start = $scope.pageCount()-rangeSize+1;
}
for (var i=start; i<start+rangeSize; i++) {
ps.push(i);
}
return ps;
};
$scope.prevPage = function() {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.DisablePrevPage = function() {
return $scope.currentPage === 0 ? "disabled" : "";
//?? TODO add logic for samething as disabled next page and build table data
};
$scope.pageCount = function() {
return Math.ceil($scope.customerResult.length/$scope.itemsPerPage)-1;
};
$scope.nextPage = function() {
if ($scope.currentPage < $scope.pageCount()) {
$scope.currentPage++;
}
};
$scope.DisableNextPage = function() {
if($scope.currentPage === $scope.pageCount()){
if($scope.noOfrows >$scope.customerResult.length)
return $scope.currentPage === $scope.pageCount() ? "disabled" : "";
$scope.noOfrows = $scope.noOfrows+ 100;
Api.customerReq.query({ productId : $scope.customerProduct , productperiod :$scope.customerPeriod, noOfrows:$scope.noOfrows }).$promise.then(function(result) {
if(result){
if(result&&result.length==0){
return $scope.currentPage === $scope.pageCount() ? "disabled" : "";
}
$scope.showData();// how to build all data on when i query for 101-201 data?
}
});
}
};
$scope.setPage = function(n) {
$scope.currentPage = n;
};
};