Flux React gulp - javascript

Trying to create a Flux store. When I run gulp and check my index.html I get an error "Uncaught TypeError: listener must be a function"
var AppDispatcher = require('../dispatchers/app-dispatcher');
var AppConstants = require('../constants/app-constants');
var assign = require('object-assign');
var EventEmitterProto = require('events').EventEmitter.prototype;
var CHANGE_EVENT = 'CHANGE'; //broadcast this everytime there is a change
var _catalog = [];
var _cartItems = [];
var AppStore = assign(EventEmitterProto, {
emitChange: function(){
this.emit(CHANGE_EVENT)
},
addChangeListener: function(callback){
this.on(CHANGE_EVENT, callback); //<---if I comment this out code runs perfect
},
removeChangeListener: function(callback){
this.removeListener(CHANGE_EVENT, callback)
},
getCart: function(){
return _cartItems
},
getCatalog: function(){
return _catalog
},
getCartTotals: function(){
return _cartTotals()
}
});
module.exports = AppStore;
Below is the only component with a listener
var React = require('react');
var AppStore = require('../stores/app-store.js');
var RemoveFromCart = require('./app-removefromcart.js'); //this is a component
var Increase = require('./app-increaseitem'); //this is a component
var Decrease = require('./app-decreaseitem'); //this is a component
function cartItems(){
return {items: AppStore.getCart()}
}
var Catalog = React.createClass({
getInitialState:function(){
return cartItems();
},
componentWillMount: function(){
AppStore.addChangeListener(this.onChange)
},
_onChange: function(){
this.setState(cartItems());
},
render: function(){
var total = 0;
var items = this.state.items.map(function(item, i){
var subtotal = item.cost * item.qty;
total += subtotal;
return (
<tr key={i}>
<td><RemoveFromCart /></td>
<td>{item.title}</td>
<td>{item.qty}</td>
<td>
<Increase index={i} />
<Decrease index={i} />
</td>
<td>${subtotal}</td>
</tr>
);
})//end map
return (
<table className="table table-hover">
<thead>
<tr>
<th></th>
<th>Item</th>
<th>Qty</th>
<th></th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
{items}
</tbody>
<tfoot>
<tr>
<td colSpan="4" className="text-right">Total</td>
</tr>
</tfoot>
</table>
);
}
});
module.exports = Catalog;
Please help. This is really hurting my head

you might need to change
AppStore.addChangeListener(this._onChange)
logic to componentDidMount function like
componentDidMount:function(){
AppStore.addChangeListener(this._onChange)
}

Related

How to call a javascript method with knockout

I am using knockout for binding, and the issue I have is can't seem to know how to call the remove method. I have two class convocation, and vague.
class Convocation {
constructor(sessionId, description)
{
var self = this;
this.ConvocationID = ko.observable(sessionId);
this.ConvDesc = ko.observable(description);
this.Vagues = ko.observableArray();
addVague(start, end) {
this.Vagues.push(new Vague(start, end));
}
removeVague() {
self.Vagues.remove(this)
}
}
class Vague {
constructor(start, end) {
this.startDate = ko.observable(start);
this.endDate = ko.observable(end);
}
}
I initialize my knockout using this viewModel, witch works.
function ViewModel() {
var self = this;
this.Convocations = ko.observableArray();
// Get information
this.Initialize = function () {
$.ajax({
url: "/Convocations/GetConvocationList",
dataType: 'json',
//data: { id: id },
success: function (data) {
for (var i = 0; i < data.length; i++) {
self.Convocations.push(new Convocation(data[i].sessionCode, data[i].desc));
for (var j = 0; j < data[i].vagues.length; j++) {
self.Convocations()[i].addVague(data[i].vagues[j].start, data[i].vagues[j].end);
}
}
}
});
}
}
This is my jquery calling the viewModel once ready.
(function ($) {
// we can now rely on $ within the safety of our "bodyguard" function
$(document).ready(function () {
var vm = new ViewModel();
ko.applyBindings(vm);
vm.Initialize();
});
})(jQuery);
But when it comes to delete a vague, I can't seem to know how to call it this is a snip of my view
<tbody data-bind="foreach: Convocations">
<tr>
<td><Input data-bind="value: $data.ConvocationID"></td>
<td><Input data-bind="value: $data.ConvDesc"></td>
</tr>
<tr>
<td colspan="3">
<div class="panel-body">
<table class="table">
<thead>
<tr>
<th>Start Date</th>
<th>End Date</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: $data.Vagues">
<tr>
<td><span type="date" data-bind="text: $data.startDate"></span></td>
<td><span type="date" data-bind="text: $data.endDate"></span></td>
<td><a href='#' data-bind='click: $parent.removeVague'>Delete</a></td>
</tr>
</tbody>
</table>
If i conver addRemove() to something like this, it use to work, but i can't define this in a class.
this.remove = function () {
self.Vagues.remove(this);
}
I suspect that there may be some confusion around what $data and $parent represents in the html bindings.
for the nested foreach knockout bindings like you have its generally a good idea to give each level its own object name rather than just using $data.
Personally I am still learning the javascript syntax around classes etc, so there is probably a better way of doing the javascript than what I have done.
var data = [{
sessionCode: 1,
desc: 'Convocation 1',
vagues: [{
start: '2020-07-01',
end: '2020-07-30'
}]
}, {
sessionCode: 2,
desc: 'Convocation 2',
vagues: [{
start: '2020-07-02',
end: '2020-07-29'
}]
}];
class Convocation {
constructor(sessionId, description) {
var self = this;
self.ConvocationID = ko.observable(sessionId);
self.ConvDesc = ko.observable(description);
self.Vagues = ko.observableArray();
self.addVague = function addVague(start, end) {
self.Vagues.push(new Vague(start, end));
}
self.removeVague = function removeVague(item) {
self.Vagues.remove(item);
}
}
}
class Vague {
constructor(start, end) {
this.startDate = ko.observable(start);
this.endDate = ko.observable(end);
}
}
function ViewModel() {
var self = this;
self.Convocations = ko.observableArray();
//helper function that mimics the success function of the ajax call to allow loading data
self.processData = function(data) {
for (var i = 0; i < data.length; i++) {
self.Convocations.push(new Convocation(data[i].sessionCode, data[i].desc));
for (var j = 0; j < data[i].vagues.length; j++) {
self.Convocations()[i].addVague(data[i].vagues[j].start, data[i].vagues[j].end);
}
}
}
// Get information
self.Initialize = function() {
$.ajax({
url: "/Convocations/GetConvocationList",
dataType: 'json',
//data: { id: id },
success: function(data) {
for (var i = 0; i < data.length; i++) {
self.Convocations.push(new Convocation(data[i].sessionCode, data[i].desc));
for (var j = 0; j < data[i].vagues.length; j++) {
self.Convocations()[i].addVague(data[i].vagues[j].start, data[i].vagues[j].end);
}
}
}
});
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
//vm.Initialize();
vm.processData(data);
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table class="table">
<tbody data-bind="foreach: {data: Convocations, as: 'convocation'}">
<tr>
<td>
<input data-bind="value: convocation.ConvocationID" />
</td>
<td>
<input data-bind="value: convocation.ConvDesc" />
</td>
</tr>
<tr>
<td colspan="3">
<div class="panel-body">
<table class="table">
<thead>
<tr>
<th>Start Date</th>
<th>End Date</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach:{data: convocation.Vagues, as: 'vague'}">
<tr>
<td><span type="date" data-bind="text: vague.startDate"></span></td>
<td><span type="date" data-bind="text: vague.endDate"></span></td>
<td><a href='#' data-bind='click: convocation.removeVague'>Delete</a></td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>

Jquery plugin not work properly on multiple element

I have created my own simple jquery plugin,but im having some problem when i put 2 elements and call the plugin on each element
my js code:
function fTable(element,options){
self = this;
this.$element = $(element);
this.table = $(this.$element).find('table');
this.thead = $(this.table).find('thead');
this.tbody = $(this.table).find('tbody');
coloumn = options.coloumn;
this.defaults = {
}
//Merge default options with user options
this.options = $.extend(true, {}, this.defaults, options);
this.init();
}
fTable.prototype = {
init : function(){
self = this;
this.td = $(this.thead).find('tr td:first');
$(this.td).html('<a class="add">Plus</a>');
this.bindEvents();
},
bindEvents : function(){
self = this;
console.log(this.table);
$(this.table).on('click', '.add', function(){
$row = '<tr>';
$row += '<td></td>';
$.each(coloumn, function(index, value){
$row += '<td><input type="text" value="" name='+value.name+' '+value.prop+'></td>';
});
$row += '</tr>';
console.log(self);
$($row).appendTo(self.table);
lastTR = $(self.tbody).find('tr:last');
$(lastTR).find('td:first').html('<a class="remove">Remove</a>');
});
$(this.table).on('click', '.remove', function(){
row = $(this).closest('tr');
$(row).remove();
});
}
}
$.fn.fTable = function(options){
return this.each(function(){
new fTable(this,options);
});
}
$('.crud').fTable({
coloumn:[
{'type':'text','name':'NIK','prop':'disabled'},
{'type':'text','name':'NAME','prop':''},
]
});
$('.crud2').fTable({
coloumn:[
{'type':'text','name':'NIK','prop':'disabled'},
{'type':'text','name':'NAME','prop':''},
]
});
HTML :
<div class="crud">
<table class="table table-bordered">
<thead>
<tr>
<td style="width:10%"></td>
<td>NIK</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>1</td>
<td>Ardhi</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td>Mega</td>
</tr>
</tbody>
</table>
</div>
<div class="crud2">
<table class="table table-bordered">
<thead>
<tr>
<td style="width:10%"></td>
<td>NIK</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>1</td>
<td>Zaphire</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td>Rexa</td>
</tr>
</tbody>
</table>
</div>
The problem is when i clicked the 'plus' on 1st table(class='crud') it will add new row to 2nd table(class='crud2') instead of 1st table(class='crud')
Any help?
You have a problem with scope. In your bindEvents prototype function, you declare self=this but you're not referring to the current scope. You actually have a scope problem everywhere. Please review JavaScript scope.
Change that line to either var self or even better let self to grab the functions scope rather than anything higher (global) or a self that was previously declared.
function fTable(element,options){
let self = this; // you omitted let or var here
this.$element = $(element);
this.table = $(this.$element).find('table');
this.thead = $(this.table).find('thead');
this.tbody = $(this.table).find('tbody');
this.column = options.column; // it was omitted here also but for sake of consistency, I applied column as a member to fTable.
this.defaults = {
}
//Merge default options with user options
this.options = $.extend(true, {}, this.defaults, options);
this.init();
}
fTable.prototype = {
init : function(){
let self = this; // omitted here too
this.td = $(this.$element).find('tr td:first');
$(this.td).html('<a class="add">Plus</a>');
this.bindEvents();
},
bindEvents : function(){
let self = this;
$(this.table).on('click', '.add', function(){
let $row = '<tr>';
$row += '<td></td>';
$.each(self.column, function(index, value){
$row += '<td><input type="text" value="" name='+value.name+' '+value.prop+'></td>';
});
$row += '</tr>';
$($row).appendTo(self.table);
let lastTR = $(self.tbody).find('tr:last');
$(lastTR).find('td:first').html('<a class="remove">Remove</a>');
});
$(this.table).on('click', '.remove', function(){
let row = $(self).closest('tr');
$(row).remove();
});
}
}
$.fn.fTable = function(options){
var self = this; // and here
return this.each(function(){
new fTable(self,options);
});
}
$('.crud').fTable({
column:[
{'type':'text','name':'NIK','prop':'disabled'},
{'type':'text','name':'NAME','prop':''},
]
});
$('.crud2').fTable({
column:[
{'type':'text','name':'NIK','prop':'disabled'},
{'type':'text','name':'NAME','prop':''},
]
});

Knockout.js - Sum table, add row and fill the table with AJAX

Im using this table to add materials and using Knockoutjs-3.4.0.js to add row and to sum it. My problem is when i try to edit the code i want to populate the table with a AJAX request. The problem is that i don't know how to fill the table with the AJAX response.
If i use the code below i get this error:
ReferenceError: Unable to process binding "click: function (){return
addMaterial }" Message: Can't find variable: addMaterial
<table class="table table-bordered">
<thead>
<tr>
<th>Moment</th>
<th>Antal </th>
<th>Kostnad</th>
<th>Totalt</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: materials">
<tr>
<td><input data-bind="value: name" /></td>
<td><input data-bind="value: quantity" /></td>
<td><input data-bind="value: rate" /></td>
<td data-bind="text: formattedTotal"></td>
<td></td>
</tr>
<tfoot>
<tr>
<th colspan="2"><button class="fa fa-plus btn-success" data-bind="click: addMaterial, enable: materials().length < 20"> Lägg till rad</button></th>
<th class="text-right">Totalt</th>
<th class="text-center"><span data-bind="text: totalSurcharge().toFixed(0)"></span></th>
<th> </th>
</tr>
<tr id="momsRow" class="hidden">
<th colspan="3" class="text-right">Moms</th>
<th class="text-center"><span data-bind="text: totalVat().toFixed(1)"></span></th>
<th> </th>
</tr>
<tr id="byggmomsRow" class="hidden">
<th colspan="3" class="">Omvänd byggmoms</th>
<th class="text-center"></th>
<th> </th>
</tr>
<tr>
<th colspan="3" class="text-right">Totalt:</th>
<th class="text-center"><span data-bind="text: totalPlusVat().toFixed(2)"></span></th>
<th> </th>
</tr>
</tfoot>
</tbody>
</table>
The knockout.js code:
/*------------- Load rows ------------- */
function LoadRows() {
var self = this;
self.materials = ko.observableArray([]);
$.getJSON("/json/tender_offer_edit_moment_json.asp", function(data) {
self.materials(data);
})
}
//ko.applyBindings(new dealModel());
ko.applyBindings(new LoadRows());
/*------------- Sum table ------------- */
function addMaterial() {
this.name = ko.observable("");
this.quantity = ko.observable("");
this.rate = ko.observable(0);
this.formattedTotal = ko.computed(function() {
return this.rate() * this.quantity();
}, this);
}
function documentViewModel(){
var self = this;
//create a materials array
self.materials = ko.observableArray([
new addMaterial()
]);
// Computed data
self.totalSurcharge = ko.computed(function() {
var total = 0;
for (var i = 0; i < self.materials().length; i++)
total += self.materials()[i].formattedTotal();
return total;
});
// add VAT(moms 25%) data
self.totalVat = ko.computed(function() {
var totalWithVat = 0;
for (var i = 0; i < self.materials().length; i++)
totalWithVat += self.materials()[i].formattedTotal();
totalWithVat = totalWithVat*0.25;
return totalWithVat;
});
// Totalt with VAT(moms 25%) data
self.totalPlusVat = ko.computed(function() {
var totalWithVat = 0;
for (var i = 0; i < self.materials().length; i++)
totalWithVat += self.materials()[i].formattedTotal();
totalWithVat = totalWithVat*1.25;
return totalWithVat;
});
// Operations
self.addMaterial = function() {
self.materials.push(new addMaterial());
}
self.removeMaterial = function(material) { self.materials.remove(material) }
}
ko.applyBindings(new documentViewModel());
/*------------- Sum table END ------------- */
There is a correct json format on the AJAX request.
[{"name":"Moment 1","quantity":"1","rate":"10","formattedTotal":"10"},{"name":"Moment 2","quantity":"2","rate":"20","formattedTotal":"40"}]
$.ajax({
url: "/json/tender_offer_edit_moment_json.asp",
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
alert(data);
//new addMaterial(data);
new addMaterial(data);
}
});
JsFiddle
First of all, you call ko.applyBindings() twice and to whole page,
it is not suitable in your situation:
To load the initial data you can do smth like this:
var vm = new documentViewModel();
$.getJSON("/json/tender_offer_edit_moment_json.asp", function(data) {
vm.materials(data);
})
ko.applyBindings(vm);
and delete this lines:
function LoadRows() {
var self = this;
self.materials = ko.observableArray([]);
$.getJSON("/json/tender_offer_edit_moment_json.asp", function(data) {
self.materials(data);
})
}
//ko.applyBindings(new dealModel());
ko.applyBindings(new LoadRows());

How have I broken this Todo list in ReactJS code?

An earlier draft of code to handle a Todo list, with fewer features, works:
{
return 0;
}
});
return (
<div id="Todo">
<h1>Todo</h1>
<form onSubmit={that.handleSubmit}>
<table>
{table_rows}
<tfoot>
<textarea name='todo-textarea' id='todo-textarea'
onChange={that.onChange}></textarea><br />
<button>{'Add activity'}</button>
</tfoot>
</table>
</form>
</div>
);
}
});
My present version is getting an InvariantViolation:
react-with-addons.js:20237 Uncaught Error: Invariant Violation: findComponentRoot(..., .0.1.1.0.0:0:0.0:1.0): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an parent. Try inspecting the child nodes of the element with React ID ``.
The present code is:
var Todo = React.createClass(
{
mixins: [React.addons.LinkedStateMixin],
getInitialState: function()
{
var result = parse(initial_todo, {
'next_todo_index': 1,
'items': [],
'text': ''
});
return result;
},
handle_change: function(event)
{
var that = this;
var address = jQuery(event.target).attr('data-index').split('.', 2);
var identifier = parseInt(address[0], 10);
for(var candidate = 0; candidate < this.state.next_todo_index;
candidate += 1)
{
if (parseInt(jQuery(this.state.items[candidate]).attr('index'), 10)
=== identifier)
{
(this.state.items[candidate][address[1]] =
!this.state.items[candidate][address[1]]);
save('Todo', this.state);
}
}
that.render();
},
handleSubmit: function(event)
{
event.preventDefault();
var new_item = get_todo_item(this);
new_item.description = this.state.text;
this.state.items.unshift(new_item);
document.getElementById('todo-textarea').value = '';
save('Todo', this.state);
if (!one_shot)
{
one_shot = true;
}
// this.forceUpdate();
// React.render(<Todo />,
// document.getElementById('Todo'));
},
onChange: function(event)
{
this.setState({text: event.target.value});
},
render: function()
{
var that = this;
var table_rows = [];
var display_item_details = function(label, item)
{
var html_id = item.index + '.' + label;
return (
<td className={label} title={label}>
<input onChange={that.handle_change} data-index={html_id}
className={label} type="checkbox"
defaultChecked={item[label]} />
</td>
);
};
var display_item = function(item)
{
var rendered_nodes = [];
if (item['Completed'] || item['Delete'] || item['Invisible'])
{
return '';
}
else
{
for(var index = 0; index < todo_item_names.length;
index += 1)
{
rendered_nodes.push(
display_item_details(todo_item_names[index], item)
);
}
return (
<tr>{rendered_nodes}
<td className="description" dangerouslySetInnerHTML={{__html:
converter.makeHtml(item.description)}} /></tr>
);
}
};
table_rows.push(that.state.items.map(display_item));
table_rows.sort(function(a, b)
{
if (a.index > b.index)
{
return 1;
}
else if (b.index > a.index)
{
return -1;
}
else
{
return 0;
}
});
return (
<div id="Todo">
<h1>Todo</h1>
<form onSubmit={that.handleSubmit}>
<table>
<tbody>
{table_rows}
<tbody>
<tfoot>
<textarea name='todo-textarea' id='todo-textarea'
onChange={that.onChange}></textarea><br />
<button>{'Add activity'}</button>
</tfoot>
</table>
</form>
</div>
);
}
});
How have I broken this?
Do check through your html table structure. Other than the <tbody> fix, the usage of <tfoot> is also invalid markup.
The <tfoot> element can only contain <tr> tags inside.
i.e.
<tfoot>
<tr>
<td>
<textarea name='todo-textarea' id='todo-textarea'
onChange={that.onChange}></textarea><br />
<button>{'Add activity'}</button>
</td>
</tr>
</tfoot>

AngularJS with AngularUI Bootsrap pagination directive doesn't hide results

I'm trying to use Angular-ui pagination directive for the first time and am confused why it isn't working. I can see the pagination buttons and it properly displays two pages to paginate through since there are 8 results and items-per-page="5" But all my data items are showing and not being hidden to five per page.
controller
dataService.get(uri).then(function (data) {
$scope.testimonials = data;
$scope.totalItems = $scope.testimonials.length;
$scope.currentPage = 1;
$scope.setPage = function(pageNo) {
$scope.currentPage = pageNo;
};
$scope.pageChanged = function() {
console.log('Page changed to: ' + $scope.currentPage);
}
});
view
<table class="table table-striped" ng-show="testimonials.length">
<thead>
<th>Name</th>
<th>Message</th>
</thead>
<tbody>
<tr ng-repeat="testimonial in testimonials">
<td>{{testimonial.name}}</td>
<td>{{testimonial.message}}</td>
<td>Edit</td>
<td><button class="btn btn-danger" ng-click="delete(testimonial)">Delete</button></td>
</tr>
</tbody>
<pagination total-items="totalItems" ng-model="currentPage" items-per-page="5" ng-change="pageChanged()"></pagination>
</table>
I appreciate any advice, thanks!
Yo need filter data in your ng-reapeter code below should works
<table class="table table-striped" ng-show="testimonials.length">
<thead>
<th>Name</th>
<th>Message</th>
</thead>
<tbody>
<tr ng-repeat="testimonial in testimonials | startFrom: (currentPage-1)*5| limitTo: 5">
<td>{{testimonial.name}}</td>
<td>{{testimonial.message}}</td>
<td>Edit</td>
<td><button class="btn btn-danger" ng-click="delete(testimonial)">Delete</button></td>
</tr>
</tbody>
<pagination total-items="totalItems" ng-model="currentPage" items-per-page="5" ng-change="pageChanged()"></pagination>
</table>
filter starts from:
app.filter('startFrom', function () {
return function (input, start) {
if (input === undefined || input === null || input.length === 0
|| start === undefined || start === null || start.length === 0 || start === NaN) return [];
start = +start; //parse to int
try {
var result = input.slice(start);
return result;
} catch (e) {
// alert(input);
}
}
});
I can't find the original example I used, but this is what I have in my app.
The filter part isn't important, but the filterProducts object is what gets sliced and shown in your view. Check out the $watch for how it works.
app.controller('ProductController', function($scope, $filter, $routeParams, $rootScope, $location, Products){
$scope.Products = Products;
Products.brandLimit = $routeParams.brandLimit;
Products.brand = $routeParams.brand;
// try to avoid reloading the prod data
if (!Products.products){
Products.getProducts().then(function(data){
Products.products = data.products;
Products.pagination();
});
}else{
Products.pagination();
}
// watch for when the pagination changes
$scope.$watch('Products.currentPage + Products.numPerPage', function() {
var begin = ((Products.currentPage - 1) * Products.numPerPage);
var end = begin + Products.numPerPage;
Products.pagedProducts = Products.filteredProducts.slice(begin, end);
});
});
And in the service:
app.factory('Products', function($http, $filter, $location, $routeParams){
var Products = {
search: '',
searching: false,
filteredProducts: '',
pagedProducts: '',
getProduct: function(id){
delete Products.detail;
$http.get('/product/' + id).then(function(response){
Products.detail = response.data.product;
});
},
getProducts: function(){
return $http.get('/product').then(function(response){
return response.data;
});
},
pagination: function(){
// relies on fulltext filter
this.filteredProducts = $filter('fulltext')(this.products, this.brandLimit);
// set up default values to feed to ui pagination
this.currentPage = 1;
this.numPerPage = 10;
this.maxSize = 10;
// check the length of filtered items based on search or brand clicked (in the URL)
this.totalItems = this.filteredProducts.length;
this.numPages = Math.ceil(this.totalItems / this.numPerPage);
},
brandTitle: function() {
if (this.searching === false || this.brand) {
this.search = '';
return $routeParams.brand + " Products";
} else {
return 'Searching "' + $routeParams.brandLimit + '"';
}
},
searchTerm: function(){
if(this.search){
$location.path("search/" + this.search);
this.searching = true;
}else{
$location.path("/");
this.searching = false;
}
}
};
return Products;
});
And HTML:
<pagination ng-show="Products.numPages" total-items="Products.totalItems" ng-model="Products.currentPage" max-size="Products.maxSize" class="pagination-small" boundary-links="true" rotate="false" num-pages="Products.numPages"></pagination>
<table class="table table-striped">
<tr>
<th>Maker</th>
<th>Title</th>
<th ng-bind="product.priceDealer">Dealer Price</th>
<th>MSRP</th>
</tr>
<tr ng-repeat="product in Products.pagedProducts">
<td>{{product.brand}}</td>
<td>{{product.title}}</td>
<td ng-bind="product.priceDealer | currency"></td>
<td>{{product.msrp | currency:"$"}}<td>
</tr>
</table>
No Need of all that, use attribute of angular UI Bootstrap:
HTML
<pager total-items="totalItems" ng-model="currentPage" items-per-page="itemsPerPage"></pager>
====
and add below code in your controller
===========
$scope.totalItems = $scope.testimonials.length;
$scope.itemsPerPage = 5;
$scope.currentPage = 1;
$scope.$watch('currentPage + itemsPerPage', function () {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.filteredtestimonials= $scope.alerts.slice(begin, end);
});
===========
Note that you need to mention ng-repeat="testimonial in filteredtestimonials"
and attribute should be in same scope of where you have used you used ng-repeat
Please let me know if you still face any issue and you can see more examples of this on: http://angular-ui.github.io/bootstrap/#/pagination
Do include :
in your page or layout page and items-per-page will not take direct value, it seems

Categories

Resources