Paginating an AngularJS blog - javascript

I'm trying to paginate my blogroll using AngularJS and the MEAN Stack. I have my Articles (blog posts) controller set up, and I've list.html to display everything. I can either get all the blogs to display, or I can get the pagination to increment, but I can't get the blogroll to show 5 items at a time and increment with the pagination.
angular.module('mean.articles')
.controller('ArticlesController', ['$scope', '$routeParams', '$location', 'Global', 'Articles', function ($scope, $routeParams, $location, Global, Articles) {
$scope.global = Global;
$scope.currentPage = 0;
$scope.pageSize = 5;
//I've my create, update and delete methods here.
$scope.find = function() {
Articles.query(function(articles) {
$scope.articles = articles;
});
};
$scope.numPages = function() {
return Math.ceil($scope.Articles.length / $scope.pageSize);
};
And here's my list.html:
<div class="container" style="width:900px; margin:auto">
<div class="container" style="width:600px; float:left">
<section data-ng-controller="ArticlesController" data-ng-init="find()">
<ul class="articles unstyled" style="width:600px">
<li data-ng-repeat="article in articles | filter:search | limitTo:pageSize">
<h2><a data-ng-href="#!/articles/{{article._id}}">{{article.title}}</a></h2>
<div>{{article.content}}</div>
<div>{{article.tags}}</div>
<h4><small>
<div class="well well-small text-center" style="width:300px">
<div style="margin:auto">
<span>{{article.created | date:'medium'}}</span> /
<span>{{article.user.name}}</span>
</div>
</div>
</small></h6>
</li>
</ul>
<h1 data-ng-hide="!articles || articles.length">No articles yet. <br> Why don't you Create One?</h1>
<button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">
Previous
</button>
{{currentPage+1}}/{{numPages()}}
<button ng-disabled="currentPage >= numPages()-1" ng-click="currentPage=currentPage+1">
Next
</button>
</section>
</div>
<div class="container" style="width:300px; float:left">
<input type="text" ng-model="search" placeholder="Enter your search terms" />
</div>

http://jsfiddle.net/2ZzZB/56/ from Pagination on a list using ng-repeat. It looks like the main thing you're missing is a way to indicate where to start your ng-repeat. The fiddle I linked to solves it by creating a startFrom filter.

Related

AngularJS 1 - ng-repeat not re-rendering after array push

I'm trying to make a simpliest chat app in Angular 1.
Controller code:
app.controller('mainCtrl', function ($scope, $rootScope, $routeParams, $location, $http) {
$scope.messages=[{'name':'user','text':'test'}];
$scope.submitMessage = function () {
$scope.messages.push({'name':'newuser','text':$scope.mymessage});
}
});
Template:
<div class="page-content" ng-controller="mainCtrl" ng-init="init()">
<div class="messages">
<p class="chat-message" ng-repeat="message in messages"><span class="username">{{message.name}}: </span>{{message.text}}</p>
</div>
<div style="clear:both"></div>
<form ng-submit="submitMessage()" ng-controller="mainCtrl">
<input type="text" ng-model="mymessage" class="message-input" ></input>
</form>
When trying to console.log the $scope.messages array, it shows the new values, but the list itself does not change at all. What can be the reason?
You've got ng-controller="mainCtrl" defined twice, this will actually instantiate 2 different instances of the controller, so the messages you push will be on the array in the second instance of your controller while you're repeating over the messages that are on the first instance of your controller.
You only need it on the surrounding div, everything that is nested inside this tag will be able to access the $scope on your controller.
<div class="page-content" ng-controller="mainCtrl" ng-init="init()">
<div class="messages">
<p class="chat-message" ng-repeat="message in messages"><span class="username">{{message.name}}: </span>{{message.text}}</p>
</div>
<div style="clear:both"></div>
<form ng-submit="submitMessage()">
<input type="text" ng-model="mymessage" class="message-input"/>
</form>
</div>

Filter search with AngularJs not working

I am trying to adapt the following search filter seen here but with little sucesss. What am I getting wrong?
This is my code so far:
controllers.js
angular.module('starter.controllers', ['starter.services'])
.controller('AppCtrl', function($scope, $ionicModal, $timeout) {
})
.controller('SearchCtrl', ["$scope", "ServicesData", function($scope, ServicesData, filterFilter) {
// Get list items
$scope.categoryList = ServicesData.getAllCategories();
$scope.serviceList = ServicesData.getAllServices();
$scope.businessList = ServicesData.getAllBusinesses();
// Filter search
$scope.filterOptions = function(){
$scope.filteredArray = filterFilter($scope.categoryList, $scope.serviceList, $scope.businessList);
};
}]);
search.html
<div class="bar bar-subheader" style="border-bottom: 1px solid #ddd; height: 4em">
<div class="bar bar-header item-input-inset">
<label class="item-input-wrapper" style="margin-left: -0.5em;">
<i class="icon ion-ios-search placeholder-icon"></i>
<input type="search" placeholder="Search" ng-model="data" ng-change="filterOptions()">
</label>
<button class="button button-clear">
Cancel
</button>
</div>
</div>
<div id="result-list" ng-show="data.length > 0" style="margin-top: 3.9em" ng-model="data">
<ul class="list">
<li class="item" ng-repeat="item in categoryList | orderBy:'title'">{{item.title}}</li>
<li class="item" ng-repeat="item in serviceList | orderBy:'title'">{{item.title}}</li>
<li class="item" ng-repeat="item in businessList | orderBy:'title'">{{item.name}}</li>
</ul>
</div>
First you have to annotate you controller correctly.
e.g:
.controller('SearchCtrl', ["$scope", "ServicesData", "filterFilter" function($scope, ServicesData, filterFilter) {
Second filterFilter takes as arguments, one array, an expression to filter that array and a comparator. Meaning you cannot pass just three arrays and expect some result.
If you want to filter all three arrays with one Input you have to call the filter function against each array separately. Or apply the filter directly in the ng-repeat of each <li>.
e.g:
<li class="item" ng-repeat="item in filteredCategory = (categoryList | orderBy:'title' | filter:data )">{{item.title}}</li>
<li class="item" ng-repeat="item in filteredService = (serviceList | orderBy:'title' | filter:data)">{{item.title}}</li>
<li class="item" ng-repeat="item in filterredBussiness = (businessList | orderBy:'title' | filter:data)">{{item.name}}</li>
Keep in mind that this way you don't need the ng-change in the input.

Dynamic list for Ionic App using Angular JS in two views

I have a Ionic app with Angular JS. I have a Dynamic checkbox list which is called from an array in app.js. I have it so that when a user clicks on a checkbox, the list above gets updated with their choice, what I want is for the choice to get put into another view not another div i.e tab 1 = List, tab - 2 = choices. The code is:
$scope.myList = [
{name:'Choice one'},
{name:'Choice two)'}
];
$scope.myChoices = [];
$scope.stateChanged = function(checked,indx){
var item = $scope.myList[indx];
if(checked){
$scope.myChoices.push(item);
}else{
var index = $scope.myChoices.indexOf(item);
$scope.myChoices.splice(index,1);
}
}
html:
<div>
<div class="item item-dark item-icon-right">
My Choices
</div>
<ul class="list" >
<li class="item" ng-repeat='item in myChoices'>
<p>{{item.name}}</p>
</li>
</ul>
<div class="item item-dark item-icon-right">
University list
</div>
<div class="item item-input-inset">
<label class="item-input-wrapper">
<i class="icon ion-ios-search placeholder-icon"></i>
<input type="text" placeholder="Search" ng-model="search">
</label>
<button class="button ion-close-circled input-button button-small"
ng-click="search = ''" ng-show="search.length">
Clear search
</button>
</div>
<ul class="list" >
<li class="item item-checkbox" ng-repeat='item in myList | filter: search'>
<label class="checkbox">
<input type="checkbox" ng-model="checked" ng-change='stateChanged(checked,$index)'>
</label>
<p>{{item.name}}</p>
</li>
</ul>
</div>
Tabs:
<ion-tabs class="tabs-icon-top tabs-dark">
<ion-tab title ="List" icon-on="home" icon-off="home" href="#/tab/list">
<ion-nav-view name="list-tab"></ion-nav-view></ion-tab>
<ion-tab title ="My choices" icon-on="choices" icon-off="choices" href="#/tab/choice">
<ion-nav-view name="choice-tab"></ion-nav-view></ion-tab>
</ion-tabs>
When you are trying to send data across multiple views, the easiest way is to store the data in a factory variable. Whenever you need the data, you can get it from the factory with a simple get.
// This module can be in its own javascript file
angular.module('choicesFactory', [])
.factory('choicesFactory', function() {
var choicesStored = [];
return {
storeChoices: function(choices) {
choicesStored = choices;
return;
},
getChoices: function() {
return choicesStored;
},
};
});
Now, to implement this bit of code, all you have to do is include the javascript file after your inclusion of angularjs in your index.html and add choicesFactory to your app dependencies.
When you call the function from your controller, you can say:
.controller('choicesController', [
'$scope',
'$state',
'choicesFactory'
function($scope, $state, choicesFactory) {
// An example with getting the choices
var choices = choicesFactory.getChoices()
}]);
If this doesn't quite make sense, I made a codepen example app that demonstrates all the pieces working together.
Click here to check out the example. :) Happy coding

How to get parent's parent's parent's id in Angularjs

I have a problem. I need to know how to get grandparent's ID in AngularJS.
I need "{{parent}}" to become "grand-parent".
(it should be <div id="me-and-my-grand-parent">)
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
var pid = document.getElementsByClassName("i-am-a-child");
var pid = this.parentNode.id;
if (this.parentNode&&this.parentNode.id)
var pid=this.parentNode.id;
$scope.parent = var pid;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div id="grand-parent{{$index}}" ng-repeat="item in items">
<div>
<div>
<div id="me-and-my-{{parent}}" class="i-am-a-child">
</div>
</div>
</div>
</div>
</div>
My actual code
<li ng-repeat="project in projects" ng-class="{active: project.childToggle, '': !project.childToggle,hasChild: project.children.length > 0 }" ng-dblclick="childToggleCt(project)" id="project-{{$index}}">
<div class="project-overview">
<header class="clearfix flip-area">
<span ng-if="!project.inCart" class="status dropdown-button warning pull-left" id="id-{{ParentIdShow}}" data-intro="Status bar" data-position="right">Pending</span>
And for now JS was like tis :
$scope.ParentIdShow = function(obj)
{
alert(obj.target.parentNode.parentNode.parentNode.id);
}
The answer to these types of "parent of my parent of my parent of my..." is to use the controller as syntax. Read more about it here. In short, it lets you do stuff like
<div ng-controller="ctrl1 as first">
<div ng-controller="ctrl2 as second">
...
<div ng-controller="ctrlN as Nth">
<div ng-repeat="i in arr">
{{first.property}}
{{second.otherProperty}}
{{Nth.nProperty}}
Note how you dont need any parent calls.

Template is compiled before the result is returenf from $http service

Hi I am trying to retrieve data from the server using $http, and correct data is being retrieved from the service, the data is -
[{
"URL":"someimg.jpg",
"TITLE":"Test Demo",
"DATE_ADDED":"2014-02-08 00:46:00",
"SUMMARY":"this is summary"
}]
the template that I wrote is as follows -
<article class="span8" ng-controller="allBlogs">
<div ng-show="success">
<div ng-repeat="blog in blogs.data">
<div class="row">
<div class="span3">
<img ng-src="{{blog['URL']}}" alt="" />
</div>
<div class="span5" ng-repeat-end>
<h4>{{blog.TITLE}}</h4>
<p>{{blog.DATE_ADDED}}</p>
<p>{{blog.SUMMARY}}</p>
</div>
</div>
</div >
</div>
</article>
the controller for the above template is as follows -
pk.controller("allBlogs", function($scope, $http, BlogsHandler){
$scope.success = false;
(function(){
BlogsHandler.getAllBlogs().success(function(data){
console.log(data);
$scope.success = true;
$scope.blogs = data.data;
});
})();
});
I am trying to set the success as true when the service returns data and thus the remaining part of the template should run. But this is not happening. Is it not that any change to $scope variable is being watched by the framework itself?
Help needed. I even tried with ng-switch with no effect.
Thanks
You assign data.data to $scope.blogs, so you don't need to add .data before blogs again.
$scope.blogs = data.data;
So, try this:
<div ng-repeat="blog in blogs track by $index">
<div class="row">
<div class="span3">
<img ng-src="{{blog.URL}}" alt="" />
</div>
<div class="span5">
<h4>{{blog.TITLE}}</h4>
<p>{{blog.DATE_ADDED}}</p>
<p>{{blog.SUMMARY}}</p>
</div>
</div>
</div >

Categories

Resources