how can i remove ng repeat data in angularjs - javascript

I have two table and i want to append second table data in $scope.notiData and how can i remove ng repeat data if i click remove symbol X. I have some code but it is not working.please help anyone
http://jsfiddle.net/A6bt3/118/
var app = angular.module('myApp', []);
function checkBoxCtrl($scope) {
$scope.tableOne = [{
firstname: 'robert',
value: 'a'
}, {
firstname: 'raman',
value: 'b'
}, {
firstname: 'kavi',
value: 'c'
}, {
firstname: 'rorank',
value: 'd'
}
];
$scope.tableTwo = [];//the table to be submitted
function removeitems(tableRef) { //revmove items from tableRef
var i;
for (i = tableRef.length - 1; i >= 0; i -= 1) {
if (tableRef[i].checked) {
tableRef.splice(i, 1);
}
}
}
$scope.btnRight = function () {
//Loop through tableone
$scope.tableOne.forEach(function (item, i) {
// if item is checked add to tabletwo
if (item.checked) {
$scope.tableTwo.push(item);
}
})
removeitems($scope.tableOne);
}
$scope.btnAllRight = function () {
$scope.tableOne.forEach(function (item, i) {
item.checked = true;
$scope.tableTwo.push(item);
})
removeitems($scope.tableOne);
}
$scope.btnLeft = function () {
$scope.tableTwo.forEach(function (item, i) {
if (item.checked) {
$scope.tableOne.push(item);
}
})
removeitems($scope.tableTwo);
}
$scope.btnAllLeft = function () {
$scope.tableTwo.forEach(function (item, i) {
item.checked = true;
$scope.tableOne.push(item);
})
removeitems($scope.tableTwo);
}
$scope.done = function () {
//alert(angular.toJson($scope.tableTwo));
$scope.notiData = $scope.tableTwo;
}
$scope.removeRow = function () {
}
};

do it like that :
$scope.removeRow = function (item) {
var index = $scope.notiData.indexOf(item);
$scope.notiData.splice(index, 1);
}
and to merge the arrays:
$scope.done = function () {
angular.extend($scope.notiData, $scope.tableTwo);
}
dont forget to initialize notiData :
$scope.notiData = [];
to resolve the problem of redirecting remove the target="_blank" and change href:
<a ng-repeat="data in notiData" class="emailButton" href="#">{{data.firstname}}<div class="" ng-click="removeRow()">X</div></a>
http://jsfiddle.net/A6bt3/122/

html element
<a ng-repeat="data in notiData" class="emailButton">{{data.firstname}}
<div class="" ng-click="removeRow($index)">X</div>
</a>
remove function
$scope.removeRow = function (index) {
$scope.notiData.splice(index,1);
}

pass the index of the data element in the removeRow() function from the view.
<a ng-repeat="data in notiData" class="emailButton" href="#">{{data.firstname}}
<div class="" ng-click="removeRow($index)">X</div>
</a>
and in controller filter the passed index element from the list.
$scope.removeRow = function (index) {
$scope.notiData = $scope.notiData.filter(function(elem){
return elem !== $scope.notiData[index]
})
}
fiddle : http://jsfiddle.net/w5upkawt/

Related

click event listener not stiking . Vanila js

I've created a store with a list of products that are generated from js and i attached an event listener to every product.
For sorting purposes, i've decided to recreate the dom to put the products in the order that i want but the problem is that the click event doesnt work and i dont know why. My line of thinking is that if something is declared globally, it should be accesable from all corners of the aplication. Am i right?
const grid = document.querySelector('.grid');
//arr of products
const productsArr = [{
name: 'Aname1',
price: 200
},
{
name: 'Cname2',
price: 2000
},
{
name: 'Zname3',
price: 28
},
{
name: 'Pname4',
price: 5
}
];
const paintProducts = function() {
productsArr.forEach(product, () => {
let price = product.price;
let name = product.name;
//create html
productsHtml = `<div product data-price="${price}" data-name = "${name}">
<h6 class="price">${price} coco</h6>
<p class="product-descr">${description}</p>
</div>`
});
//insert html
grid.insertAdjacentHTML('beforeend', productsHtml);
};
paintProducts();
// filter
const aZBtn = document.querySelector('.a-z');
const filterAlphabetically = () => {
allInstruments.sort(function(i, j) {
if (i.name < j.name) {
return -1;
}
if (i.name > j.name) {
return 1;
}
return 0;
});
};
//clean the dom
const cleanGrid = function() {
grid.innerHTML = '';
};
aZBtn.addEventListener('click', function() {
filterAlphabetically();
cleanGrid();
paintProducts();
clickOnProduct();
});
const products = document.querySelectorAll(".product")
const clickOnProduct = function() {
products.forEach(function(product) {
product.addEventListener('click', () => {
console.log("something here")
})
})
}
<div class="grid-container">
<div class="a-z">Alphabetically</div>
<div class="grid">
</div>
</div>
First I found a logical flaw in paintProducts
The following line was outside the loop, so only 1 item could ever be rendered, the last one.
grid.insertAdjacentHTML('beforeend', productsHtml);
Second was in filterAlphabetically. There a mistery variable pops up allInstruments, replaced it with productsArr.
Third problem was const products = document.querySelectorAll(".product"). This was outside the clickOnProduct function.
As every repaint generates new DOM elements, after sorting, the events need to be bound to the new elements.
Fourth problem is the product div itself, it countained <div product ... but you are using a queryselector referring a class so this should be <div class="product" ...
When fixing all the above, we result in this:
<html>
<body>
<div class="grid-container">
<div class="a-z">Alphabetically</div>
<div class="grid">
</div>
</div>
</body>
<script>
const grid = document.querySelector('.grid');
//arr of products
const productsArr = [{
name: 'Aname1',
price: 200
},
{
name: 'Cname2',
price: 2000
},
{
name: 'Zname3',
price: 28
},
{
name: 'Pname4',
price: 5
}
];
const paintProducts = function() {
productsArr.forEach(product => {
let price = product.price;
let name = product.name;
//create html
productsHtml = `<div class="product" data-price="${price}" data-name = "${name}">
<h6 class="price">${price} coco</h6>
<p class="product-descr">${name}</p>
</div>`
//insert html
grid.insertAdjacentHTML('beforeend', productsHtml);
});
};
paintProducts();
// filter
const aZBtn = document.querySelector('.a-z');
const filterAlphabetically = () => {
productsArr.sort(function(i, j) {
if (i.name < j.name) {
return -1;
}
if (i.name > j.name) {
return 1;
}
return 0;
});
};
//clean the dom
const cleanGrid = function() {
grid.innerHTML = '';
};
aZBtn.addEventListener('click', function() {
filterAlphabetically();
cleanGrid();
paintProducts();
clickOnProduct();
});
const clickOnProduct = function() {
var products = document.querySelectorAll(".product")
products.forEach(function(product) {
product.addEventListener('click', () => {
console.log("something here")
});
});
}
clickOnProduct()
</script>
</html>

AngularJS filter | orderBy with custom order

I am trying to order a list in a ng-repeat. What i want to do is set the order by hand, so i can say players first, coach second and waterboy last in the list. This is where i got but now got stuck with filters (kinda new to me):
$scope.Team= [{
Name: "Saras"
Role: "coach"
},{
Name: "Arya"
Role: "player"
},{
Name: "Adam"
Role: "waterboy"
},{
Name: "Theo"
Role: "player"
},{
Name: "Mark"
Role: "player"
},{
Name: "Oscar"
Role: "player"
},{
Name: "Tom"
Role: "player"
},{
Name: "Gus"
Role: "coach"
}];
<div ng-repeat="person in Team | orderBy:Role>
<div>{{person.Name}}</div>
</div>
i would like to orderBy 'Role' this way, where i can set the order
'player', 'coach', 'waterboy'
with the filter below i am able to set the order correct and add the label of the Role (coach, player etc.), however the labels sometimes get repeated. How could i fix that?
<div ng-repeat="person in Team | myOrder:'Role'>
<h2 ng-show="item.Role_CHANGED">{{item.Role}}</h2>
<p>{{person.Name}}</p>
</div>
app.filter('myOrder', function () {
return function (list, group_by) {
function CustomOrder(item) {
switch (item) {
case 'coach':
return 2;
case 'player':
return 1;
case 'waterboy':
return 3;
}
}
var filtered = [];
var prev_item = null;
var group_changed = false;
var new_field = group_by + '_CHANGED';
angular.forEach(list, function (item) {
group_changed = false;
if (prev_item !== null) {
if (prev_item[group_by] !== item[group_by]) {
group_changed = true;
}
} else {
group_changed = true;
}
if (group_changed) {
item[new_field] = true;
} else {
item[new_field] = false;
}
filtered.push(item);
prev_item = item;
});
filtered.sort(function (a, b) {
return (CustomOrder(a.Role) > CustomOrder(b.Role) ? 1 : -1);
});
return filtered;
};
})
try this example :
html :
<div class="test" ng-controller="Ctrl">
<div ng-repeat="division in divisions | orderBy:['group','sub']">{{division.group}}-{{division.sub}}</div>
<div>
js :
var app = angular.module('app', []);
function Ctrl($scope) {
$scope.divisions = [{'group':1,'sub':1}, {'group':2,'sub':10}, {'group':1,'sub':2},{'group':1,'sub':20},{'group':2,'sub':1},{'group':2,'sub':11}];
}
alright what i did to solve this is that i moved the sort function to the front when i GET the data from the JSON repsonse.
$http({
method: 'Get',
url: "https://xxxxxxx.azurewebsites.net/api/team/" + id_company
})
.success(function (data) {
var neworder = [];
function CustomOrder(item) {
switch (item) {
case 'player':
return 1;
case 'coach':
return 2;
case 'waterboy':
return 3;
}
}
angular.forEach(data, function (item) {
neworder.push(item);
});
neworder.sort(function (a, b) {
return (CustomOrder(a.Role) > CustomOrder(b.Role) ? 1 : -1);
});
$scope.Team = neworder;
});
after i just run the filter without the sort function;
<div ng-repeat="person in Team | myOrder:'Role'>
<h2 ng-show="item.Role_CHANGED">{{item.Role}}</h2>
<p>{{person.Name}}</p>
</div>
app.filter('myOrder', function () {
return function (list, group_by) {
var filtered = [];
var prev_item = null;
var group_changed = false;
var new_field = group_by + '_CHANGED';
angular.forEach(list, function (item) {
group_changed = false;
if (prev_item !== null) {
if (prev_item[group_by] !== item[group_by]) {
group_changed = true;
}
} else {
group_changed = true;
}
if (group_changed) {
item[new_field] = true;
} else {
item[new_field] = false;
}
filtered.push(item);
prev_item = item;
});
return filtered;
};
})
it's a bit of a work-around but it did the job
just to be complete, if you just want to sort the ng-repeat in a filter and no need for the lables. you can just do this:
<div ng-repeat="person in Team | Sorter:'Role'>
<p>{{person.Name}}</p>
</div>
app.filter('Sorter', function () {
function CustomOrder(item) {
switch (item) {
case 'player':
return 1;
case 'coach':
return 2;
case 'waterboy':
return 3;
}
}
return function (items, field) {
var filtered = [];
angular.forEach(items, function (item) {
filtered.push(item);
});
filtered.sort(function (a, b) {
return (CustomOrder(a.Role) > CustomOrder(b.Role) ? 1 : -1);
});
return filtered;
};
});

Lodash/JS - Convert _.find statement to _.forEach

I'm having trouble converting the following Lodash statement to something that works in an application that I inherited at work and am trying to fix bugs in. At the moment, we are having issues with only one device on our system returning when two devices have the same name and the following code seems to be the culprit as it would only return the first "true" value in an array:
var group = _.find(groupList, {id: id});
How would I successfully convert this to a statement that iterates over all objects in an array and then returns those objects? I've tried the following options to no avail:
var group = _.filter(groupList, {id: id});
and
var group = _.every(groupList, {id: id});
and
var group = _.forEach(groupList, {id: id})
return {id};
I know I am probably missing something in my syntax. Any help would be much appreciated. Running Lodash v3.7.0
Here's the rest of the code in the directive in case anyone is interested or sees something else I might be missing:
define(['./../_module'], function (directives) {
'use strict';
directives.directive('dmGroupedList', ['$compile', '$state', 'APP_CONSTANTS', function ($compile, $state, APP_CONSTANTS) {
return {
restrict: 'A',
scope: {
items: '=',
groupBy: '=',
actions: '=',
nonameGroupLabel: '='
},
templateUrl: function (elem, attrs) {
return attrs.templateUrl || 'views/shared-templates/grouped-list.html';
},
link: function (scope, element, attrs) {
scope.$watchGroup(['items', 'groupBy', 'nonameGroupLabel'], function () {
scope.groupList = [];
scope.groupedItems = {};
var actions = scope.actions[scope.groupBy];
_.forEach(scope.items, function (item) {
scope.handlers.getGroups(scope.groupList, item, scope.items, scope.groupBy, actions);
});
_.forEach(scope.groupList, function (group) {
var items = scope.groupedItems[group.id];
items = _.sortBy(items, function (item) {
return item.description;
});
scope.groupedItems[group.id] = items;
});
var groupsToSort = _.where(scope.groupList, {unassigned: false});
var unassignedGroups = _.sortBy(_.where(scope.groupList, {unassigned: true}), 'name');
scope.groupList = _.sortBy(groupsToSort, function (group) {
return group.name;
});
//adds unassigned groups to a new array via the javascript "push" method
if (angular.isDefined(unassignedGroups)) {
for (var i = 0; i < unassignedGroups.length; i++) {
scope.groupList.push(unassignedGroups[i]);
}
}
});
scope.handlers = {
getGroups: function (groupList, item, items, groupBy, actions) {
var group = item[groupBy];
if (_.isEmpty(group)) {
scope.handlers.addGroupToList(groupList, APP_CONSTANTS.DEVICE_NONE_NAME_MAPPING.NONE, items, groupBy, item, actions, scope);
}
else {
if (angular.isArray(group) || angular.isObject(group)) {
_.forEach(group, function (groupName) {
if (groupName == APP_CONSTANTS.ZERO) {
scope.handlers.addGroupToList(groupList, APP_CONSTANTS.DEVICE_NONE_NAME_MAPPING.NONE, items, groupBy, item, actions, scope);
return;
}
scope.handlers.addGroupToList(groupList, groupName, items, groupBy, item, actions, scope);
})
} else {
scope.handlers.addGroupToList(groupList, group, items, groupBy, item, actions, scope);
}
}
},
addGroupToList: function (groupList, groupId, items, groupBy, item, handlers, scope) {
var id = _.camelCase(groupId);
var group = _.find(groupList, {id: id});
//var group = _.forEach(groupList, {id: id})
//return {id};
if (!group) {
var name = '';
var unassigned = false;
var link = null;
if (groupId == APP_CONSTANTS.DEVICE_NONE_NAME_MAPPING.NONE || groupId == APP_CONSTANTS.DEVICE_NONE_NAME_MAPPING.NONE_PARENT_ID) {
if (groupId == APP_CONSTANTS.DEVICE_NONE_NAME_MAPPING.NONE_PARENT_ID) {
name = APP_CONSTANTS.DEVICE_NONE_NAME_MAPPING.NONE;
} else {
name = APP_CONSTANTS.DEVICE_NONE_NAME_MAPPING.UNASSIGNED;
}
unassigned = true;
} else {
link = handlers.getGroupLink(groupId);
name = handlers.getGroupName(groupId, items);
}
group = {id: id, name: name, unassigned: unassigned, link: link};
groupList.push(group);
}
scope.groupedItems[group.id] = scope.groupedItems[group.id] || [];
if (angular.isDefined(handlers.processingGroup)) {
handlers.processingGroup(group, groupList, groupId, items, groupBy, item, handlers, scope);
} else {
scope.groupedItems[group.id].push({
description: handlers.getItemDescription(item),
link: handlers.getItemLink(item)
})
}
}
};
}
};
}]);
});
You can just use filter:
var group = groupList.filter((group) => group.id === id);
EDIT: to return only the element, and not an array, when there is only one match, you can do the following:
var checkSingle = (groups) => groups.length === 1 ? groups[0] : groups;
var group = checkSingle(groupList.filter((group) => group.id === id));
You can _(groupList).groupBy('id').get(id):
var groupList = [
{ id: 1, name: 'site' },
{ id: 2, name: 'test' },
{ id: 2, name: 'prod' },
{ id: 3, name: 'dev' },
{ id: 4, name: 'back' },
{ id: 4, name: 'front' },
{ id: 5, name: 'sprint' }
];
console.log(_(groupList).groupBy('id').get(2));
console.log(_(groupList).groupBy('id').get(3));
console.log(_(groupList).groupBy('id').get(4));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Storing checked checkboxes into array in angularjs tree structure

Currently i am able to display item that have parent child relation in tree structure using checkboxes. Now I need to store the checked checkboxes into one array so that I can submit that data to server via ajax.
I am new to angularjs. I tried printing using ng-model value. But it doesn't work.
Can you help me with how I can store the checked checkboxes into array.
Below is the code.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script>
var app, list;
list = [
{
name: 'Developer',
opened: true,
children: [
{
name: 'Front-End',id:1,
children: [
{
name: 'Jack',id:2,
title: 'Leader'
},
{
name: 'John',id:3,
title: 'Senior F2E'
},
{
name: 'Jason',id:4,
title: 'Junior F2E'
}
]
},
{
name: 'Back-End',id:5,
children: [
{
name: 'Mary',id:6,
title: 'Leader'
},
{
name: 'Gary',id:7,
title: 'Intern'
}
]
}
]
},
{
name: 'Design',id:8,
children: [{
name: 'Freeman',id:9,
title: 'Designer'
}]
},
{
name: 'S&S',id:10,
children: [{
name: 'Nikky',id:11,
title: 'Robot'
}]
}
];
app = angular.module('testApp', []).controller('treeTable', [
'$scope',
'$filter',
function ($scope, $filter) {
$scope.list = list;
//$scope.item.selected={};
$scope.initCheckbox = function (item, parentItem) {
return item.selected = parentItem && parentItem.selected || item.selected || false;
};
$scope.toggleCheckbox = function (item, parentScope) {
if (item.children != null) {
$scope.$broadcast('changeChildren', item);
}
if (parentScope.item != null) {
return $scope.$emit('changeParent', parentScope);
}
};
$scope.$on('changeChildren', function (event, parentItem) {
var child, i, len, ref, results;
ref = parentItem.children;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
child = ref[i];
child.selected = parentItem.selected;
if (child.children != null) {
results.push($scope.$broadcast('changeChildren', child));
} else {
results.push(void 0);
}
}
return results;
});
return $scope.$on('changeParent', function (event, parentScope) {
var children;
children = parentScope.item.children;
parentScope.item.selected = $filter('selected')(children).length === children.length;
parentScope = parentScope.$parent.$parent;
if (parentScope.item != null) {
return $scope.$broadcast('changeParent', parentScope);
}
});
}
]);
app.filter('selected', [
'$filter',
function ($filter) {
return function (files) {
return $filter('filter')(files, { selected: true });
};
}
]);
</script>
</head>
<body>
<div class="wrapper" ng-app="testApp" ng-controller="treeTable">
<table class="table-nested">
<tbody ng-class="{opened: item.opened}" ng-include="'table_tree.html'" ng-repeat="item in list"></tbody>
</table>
<script id="table_tree.html" type="text/ng-template">
<tr ng-class="{parent: item.children}" ng-init="parentScope = $parent.$parent; initCheckbox(item, parentScope.item)">
<td class="cell-name">
<div class="indent" ng-click="item.opened = !item.opened"></div>
<input ng-change="toggleCheckbox(item, parentScope)" ng-model="item.selected" type="checkbox" />
{{item.name}}
</td>
</tr>
<tr class="children" ng-if="item.children && item.children.length > 0">
<td colspan="4">
<table class="table-child">
<tbody ng-class="{opened: item.opened}" ng-include="'table_tree.html'" ng-init="level = level + 1" ng-repeat="item in item.children"></tbody>
</table>
</td>
</tr>
</script>
{{item.selected | json}}
</div>
</body>
check plunker here
Maybe you can do it like this:
JS:
$scope.seleceds = {};
$scope.initCheckbox = function (item, parentItem) {
return $scope.seleceds[item.id] = parentItem && $scope.seleceds[parentItem.id] || $scope.seleceds[item.id] || false;
};
$scope.toggleCheckbox = function (item, parentScope) {
if (item.children != null) {
$scope.$broadcast('changeChildren', item);
}
if (parentScope.item != null) {
return $scope.$emit('changeParent', parentScope);
}
};
$scope.$on('changeChildren', function (event, parentItem) {
var child, i, len, ref, results;
ref = parentItem.children;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
child = ref[i];
$scope.seleceds[child.id] = $scope.seleceds[parentItem.id];
if (child.children != null) {
results.push($scope.$broadcast('changeChildren', child));
} else {
results.push(void 0);
}
}
return results;
});
return $scope.$on('changeParent', function (event, parentScope) {
var children;
children = parentScope.item.children;
$scope.seleceds[parentScope.item.id] = $filter('selected')(children, $scope.seleceds).length === children.length;
parentScope = parentScope.$parent.$parent;
if (parentScope.item != null) {
return $scope.$broadcast('changeParent', parentScope);
}
});
Extra filter:
app.filter('selected', ['$filter', function ($filter) {
return function (files, obj) {
return $filter('filter')(files, function (value) {
return obj[value.id]
});
};
}]);
app.filter('objToArray', function () {
return function (input) {
var results = [];
for (var key in input) {
input[key] && results.push(Number(key))
}
return results;
}
});
HTML:
<input ng-change="toggleCheckbox(item, parentScope)" ng-model="seleceds[item.id]" type="checkbox"/>
And change {{item.selected | json}} to {{seleceds|objToArray}}
you can see a demo HERE

Adding and removing items from ng-repeat, simple cart implementation, using angular

I'm trying to achieve an array with items that displays as a title and image and when the user click the title the item should be added to a div. However, I canĀ“t make it to work as when I click on "Add me", there is only a blank item added, with no image and no title.
I got the delete-function to work but not the add-function.
Here is what I got:
The "Add me"-button and the list of items
<li ng-repeat="item in items.data">
{{item.title}} <img ng-src="{{ item.image }}" /><a ng-click="deleteItem($index)" class="delete-item">x</a>
<button ng-click="addItem()">Add Me</button>
</li>
The array
var myApp = angular.module("myApp", []);
myApp.factory("items", function () {
var items = {};
items.data = [{
title: "Item 1",
image: "img/item01.jpg"
}, {
title: "Item 2",
image: "img/item02.jpg"
}, {
title: "Item 3",
image: "img/item03.jpg"
}, {
title: "Item 4",
image: "img/item04.jpg"
}];
return items;
});
And the functions for add and delete
function ItemsController($scope, items) {
$scope.items = items;
$scope.deleteItem = function (index) {
items.data.splice(index, 1);
}
$scope.addItem = function () {
items.data.push({
title: $scope.items.title
});
}
}
You need to pass the item under iteration.
<button ng-click="addItem(item)">Add Me</button>
and add the title to the newly added:
$scope.addItem = function(item) {
items.data.push({
title: item.title
});
}
it is better not to use $index (it can cause issue when used with filters eg: orderBy filter) instead just pass the item to delete and:
$scope.deleteItem = function(item) {
items.data.splice(items.indexOf(item), 1);
}
You also have an invalid html, li must be a child of ul or ol.
A sample implementation:
function($scope, items) {
$scope.items = items;
$scope.cart = [];
$scope.deleteItem = function(item) {
var cart = $scope.cart;
//Get matched item from the cart
var match = getMatchedCartItem(item);
//if more than one match exists just reduce the count
if (match.count > 1) {
match.count -= 1;
return;
}
//Remove the item if current count is 1
cart.splice(cart.indexOf(item), 1);
}
$scope.addItem = function(item) {
//Get matched item from the cart
var match = getMatchedCartItem(item), itemToAdd ;
//if item exists just increase the count
if (match) {
match.count += 1;
return;
}
//Push the new item to the cart
itemToAdd = angular.copy(item);
itemToAdd.count = 1;
$scope.cart.push(itemToAdd);
}
function getMatchedCartItem(item) {
/*array.find - Find the shim for it in the demo*/
return $scope.cart.find(function(itm) {
return itm.id === item.id
});
}
Demo
angular.module('app', []).controller('ctrl', function($scope, items) {
$scope.items = items;
$scope.cart = [];
$scope.deleteItem = function(item) {
var cart = $scope.cart;
var match = getMatchedCartItem(item);
if (match.count > 1) {
match.count -= 1;
return;
}
cart.splice(cart.indexOf(item), 1);
}
$scope.addItem = function(item) {
var match = getMatchedCartItem(item);
if (match) {
match.count += 1;
return;
}
var itemToAdd = angular.copy(item);
itemToAdd.count = 1;
$scope.cart.push(itemToAdd);
}
function getMatchedCartItem(item) {
return $scope.cart.find(function(itm) {
return itm.id === item.id
});
}
}).factory("items", function() {
var items = {};
items.data = [{
id: 1,
title: "Item 1",
image: "img/item01.jpg"
}, {
id: 2,
title: "Item 2",
image: "img/item02.jpg"
}, {
id: 3,
title: "Item 3",
image: "img/item03.jpg"
}, {
id: 4,
title: "Item 4",
image: "img/item04.jpg"
}];
return items;
});
if (!Array.prototype.find) {
Array.prototype.find = function(predicate) {
if (this == null) {
throw new TypeError('Array.prototype.find called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return value;
}
}
return undefined;
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<ul>
<li ng-repeat="item in items.data" id="item{{item.id}}">
{{item.title}}
<img ng-src="{{ item.image }}" />
<button ng-click="addItem(item)">Add Me</button>
</li>
</ul>
<p>Cart:</p>
<ul>
<li ng-repeat="item in cart">
{{item.title}} | Count: {{item.count}}
<a ng-click="deleteItem(item)" class="delete-item">X</a>
</li>
</ul>
</div>
I am using Array.prototype.find, you would need to add the shim (as mentioned in the demo) to be able to make it work for non supported browsers.

Categories

Resources