This is my code. i am using $localStorage for pushing an object into array. when i clicking the button the object is pushed properly and splicing the same same object again click on the same button. $localStorage.tableArray assign to the $scope.Storage for dropdown list. Drop down list coming good when the button action done.
My problem is the $scope.$storage having two items. if i refresh the page dropdown list not came.
if i pushing or splicing action performed on the buttons drop down list coming good.
please help how to get $scope.$storage items into the dropdown list when refreshing the page.
I Create a plunker regarding this. check once
HTML:
<body ng-controller="MainCtrl">
<a class="btn {{table.btnClass}} btn-success" ng-repeat="table in tablelist" ng-click="getTable(table)" style="padding-left:1px">{{table.tablename}}</a>
<select ng-options="table.tablename as table.tablename for table in $storage" ng-model="table.tablename"><option value="">---select table---</option></select>
JS:
var app = angular.module('plunker', ["ngStorage"]);
app.controller('MainCtrl', function ($scope,$localStorage,$filter) {
$scope.tablelist = [{ "tablename": "t1" }, { "tablename": "t2" },{ "tablename": "t3" },{ "tablename": "t4" }]
if ($localStorage.tableArray === undefined) {
$localStorage.tableArray = []
}
if ($localStorage.tableslist === undefined) {
$localStorage.tableslist = []
}
angular.forEach($scope.tablelist, function (list, $index) {
var found = $filter('filter')($localStorage.tableArray, { tablename: list.tablename }, true);
if (found.length) {
$scope.tablelist[$index].btnClass = found[0].btnClass;
}
});
$scope.getTable = function (table) {
table.btnClass = table.btnClass == "btn-danger" ? "btn-success" : "btn-danger"
var exists = false;
angular.forEach($localStorage.tableArray, function (list, $index) {
if ((list.tablename == table.tablename)) {
console.log(list.tablename)
console.log(table.tablename)
exists = true;
$localStorage.tableArray.splice($index, 1)
$localStorage.tableslist.splice($index, 1)
$scope.$storage= $localStorage.tableArray;
console.log( $scope.$storage)
return false
}
});
if (!exists) {
$localStorage.tableslist.push(table)
$localStorage.tableArray = $localStorage.tableslist;
$scope.$storage = $localStorage.tableArray
console.log($localStorage.tableArray)
table.color = "red"
}
}
});
https://plnkr.co/edit/0RpAGVR5ZpVFMvmmxipu?p=preview
As per my understanding you want your dropdown list to be initialized on refresh with the stored value from your localstorage.
Adding below line in controller works for me:
$scope.$storage = $localStorage.tableArray
Check plnkr
Related
I followed this below link :
https://codepen.io/templarian/pen/VLKZLB
But here when clicking More Option, I have to get the dynamic populated Names like
var Obj = [{name:"1st Item",taste:"sweet"},{name:"2nd item",taste:"spicy"}];
Replace of "Alert Cost" and "Alert Player Gold".
I tried but I am failed to get in dynamic looping.
You can do like this.... Add this code inside the function inside demo controller.
$scope.arr = [];
for(let x of [{name:"1st Item",taste:"sweet"},{name:"2nd item",taste:"spicy"}]) {
let newArr = [];
newArr.push(x.name);
newArr.push(function ($itemScope) {
alert($itemScope.item.cost);
});
$scope.arr.push(newArr);
}
And then replace the old array of Alert Cost" and "Alert Player Gold" with $scope.arr.
$scope.menuOptions = [
['Buy', function ($itemScope) {
$scope.player.gold -= $itemScope.item.cost;
}],
null,
['Sell', function ($itemScope) {
$scope.player.gold += $itemScope.item.cost;
}, function ($itemScope) {
return $itemScope.item.name.match(/Iron/) == null;
}],
null,
['More...', $scope.arr]
];
Voila, you good to go.
Here is working codepen example. Working example https://codepen.io/anon/pen/jGBJMY?editors=1010
I'm working with list of checkboxes and I have next logic behavior for it:
if all items selected, checkbox "select all" is checked
if one of all selected items has been unchecked, checkbox "select all" is unchecked as well
This logic is clear. Depends of what item is checked I extract its id to an additional array and then using this array for request that to get data.
For pushing everything works fine, but for slicing the logic is strange. So I can slice the array until first item is checked, however I unchecked the first item, pushed and sliced items no more related with checkboxes.
I have reproduced plunker with it, so I appreciate if anybody could help me to find what I'm missing.
$scope.modelClass = {
selectedAll: false
};
$scope.selectAllClass = function (array) {
angular.forEach(array, function (item) {
item.selected = $scope.modelClass.selectedAll;
$scope.param =''
});
};
$scope.checkIfAllClassSelected = function (array) {
$scope.modelClass.selectedAll = array.every(function (item) {
return item.selected == true
});
$scope.checked = array.filter(function (item) {
return item.selected == true
}).length;
angular.forEach(array, function (obj) {
if(obj.selected == true){
requestClass(obj)
}
});
};
var selectedClass = [];
var requestClass = function (obj) {
selectedClass.push(obj);
angular.forEach(selectedClass, function (val) {
if (val.selected != true) {
selectedClass.splice(selectedClass.indexOf(val.id), 1);
}
else {
selectedClass = selectedClass.filter(function (elem, index, self) {
return index == self.indexOf(elem);
})
}
});
$scope.param = _.map(selectedClass, 'id')
};
$scope.classes = [
{"id":4,"name":"Achievement","selected":false},
{"id":13,"name":"Information","selected":false},
{"id":6,"name":"Issue","selected":false},
{"id":5,"name":"Message","selected":false},
{"id":9,"name":"Request","selected":false}
]
The logic looks good for me, not sure what's wrong here. I've took the first solution from this post (it looks like you are using the second one) and slightly modified it for your needs.
$scope.model = {
selectedClass : []
}
$scope.isSelectAll = function(){
$scope.model.selectedClass = [];
if($scope.master){
$scope.master = true;
for(var i=0;i<$scope.classes.length;i++){
$scope.model.selectedClass.push($scope.classes[i].id);
}
}
else{
$scope.master = false;
}
angular.forEach($scope.classes, function (item) {
item.selected = $scope.master;
});
$scope.param = $scope.model.selectedClass
}
$scope.isChecked = function() {
var id = this.item.id;
if(this.item.selected){
$scope.model.selectedClass.push(id);
if($scope.model.selectedClass.length == $scope.classes.length ){$scope.master = true;
}
} else {
$scope.master = false;
var index = $scope.model.selectedClass.indexOf(id);
$scope.model.selectedClass.splice(index, 1);
}
$scope.param = $scope.model.selectedClass
}
$scope.classes = [
{"id":4,"name":"Achievement","selected":false},
{"id":13,"name":"Information","selected":false},
{"id":6,"name":"Issue","selected":false},
{"id":5,"name":"Message","selected":false},
{"id":9,"name":"Request","selected":false}
]
html
<div ng-class="{'selected': master, 'default': !master}">
<div>
<input type="checkbox" ng-model="master" ng-change="isSelectAll()" > Select all
</div>
</div>
<div ng-repeat="item in classes | orderBy : 'id'" ng-class="{'selected': item.selected, 'default': !item.selected}">
<div >
<input type="checkbox" ng-model="item.selected" ng-change="isChecked()">
{{ item.name }}
</div>
</div>
this is fixed plunker
I already have forward and back buttons paging through data items in a array within a json file:
Controller:
dishControllers.controller('DrinkcardsController', ['$scope','$http','$routeParams', function($scope, $http, $routeParams) {
$http.get('js/all.json').success(function(data) {
$scope.IsVisible = false;
$scope.ShowHide = function () {
$scope.IsVisible = $scope.IsVisible ? false : true;
}
$scope.dish = data;
$scope.whichItem = $routeParams.itemId;
if ($routeParams.itemId > 0) {
$scope.prevItem = Number($routeParams.itemId)-1;
} else {
$scope.prevItem = $scope.dish.length-1;
}
if ($routeParams.itemId < $scope.dish.length-1) {
$scope.nextItem = Number($routeParams.itemId)+1;
} else {
$scope.nextItem = 0;
}
});
}]);
Html:
<a ng-href="#/sidecards/{{prevItem}}"><div class="lbut">«</div></a>
<a ng-href="#/sidecards/{{nextItem}}"><div class="rbut">»</div></a>
Two sample json entires:
{
"name": "Pecan Pie",
"shortname": "pecan-pie",
"drink":"0",
"dessert":"1",
"contributor": "Mark",
"totalt": "1h 5m",
"ingredients": "1 cup light brown sugar",
"steps": "Preheat oven to 400 degrees.",
},
{
"name": "Godfather",
"shortname": "godfather",
"drink":"1",
"dessert":"0",
"contributor": "Jack",
"totalt": "5m",
"ingredients": "amaretto",
"steps": "mix and drink",
},
Is there any way to have the buttons page through only the items that have a specific value? In other words, the json file has several entries in it, but I only want the forward and back buttons to page through the entries with the value, "drink":"1" and exclude entries with the value, "drink":"0".
Please note the json data has been shortened for clarity. The real app has 8 dish categories, not just drinks and desserts.
Update: #MonVillalon
When I change the code in the controller from this:
$scope.dish = data;
to this:
$scope.dish = data.filter( function( item ){
return item.drink == 1 ;
});
It damages another controller (shown below) and HTML partial (this can be seen at Problem Page Click on Mexican Rice). Any ideas?
dishControllers.controller('DrinksController', ['$scope', '$http', function($scope, $http) {
$http.get('js/all.json').success(function(data) {
$scope.dish = data;
$scope.dishOrder = 'name';
$scope.showDelete = function(itemDrink){
var testDrink = "1";
if(testDrink.indexOf(itemDrink) > -1){
return true;
}
return false;
}
$scope.IsVisible = false;
$scope.ShowHide = function () {
$scope.IsVisible = !$scope.IsVisible;
}
});
}]);
Yes, you have to filter your results to only those things you want for example with Array.filter.
Change the code
from this:
$scope.dish = data;
to this:
$scope.dish = data.filter( function( item ){
return item.drink == 1 ;
});
I am using a number of checkboxes to push their values to an array to be used as arguments for the filtering of a dataset.
The requirement is to:
Show child filters on selection of the parent category.
If parent is unchecked all its children should be unchecked (false) automatically (otherwise they will be hidden and still true)
Display active filters
remove active filter on click (also uncheck their corresponding checkbox programatically).
Clear all filters and uncheck all checkboxes.
My current code is below, however see attached fiddle.
$scope.IsChecked = false;
$scope.ActiveFilters = [];
$scope.clearFilters = function() {
$scope.ActiveFilters = [];
};
$scope.ModifyFilter = function (IsChecked, Filter) {
console.log(IsChecked);
if (IsChecked) {
$scope.ActiveFilters.push(Filter);
}
else {
var indexz = $scope.ActiveFilters.indexOf(Filter);
$scope.ActiveFilters.splice(indexz, 1);
}
};
A fiddle with a semi-working demonstration is here
-- EDIT --
Further explanation: When a checkbox is checked it pushed its value to the array. if I remove this from the array by clicking on its name in the 'Active Filters' section at the bottom of the fiddle then it does not uncheck the checkbox. Neither does clicking on 'Clear Filters'.
The problem is in your html bindings. so please post this code here.
You using for "IsChecked" variable. This is local scope variable created for each iteration of loop. You not change it from your script code.
Updated html:
<body ng-app="DemoApp" ng-controller="DashboardCtrl">
<div ng-repeat="group in Filters">
<input type="checkbox" value="{{group.title}}" ng-model="CheckboxParent" />
{{group.title}}
<div ng-show="CheckboxParent" class="animate-show" ng-repeat="filter in group.filters">
<input type="checkbox" class="filterChild" value="{{filter.name}}" ng-model="filter.checked" ng-change="ModifyFilter(filter.checked,filter)"/>
{{filter.name}}
</div>
</div>
<div>
<h4>Active Filters</h4>
<p class="clear-filters" ng-click="clearFilters()">Clear Filters</p>
<ul ng-repeat="activeFilter in ActiveFilters">
<li ng-model="activeFilter.checked" ng-click="removeFilter(ModifyFilter(activeFilter.checked,activeFilter))">{{activeFilter.name}}</li>
</ul>
</div>
</body>
Updated script:
var app = angular.module("DemoApp", [])
app.controller("DashboardCtrl", function($scope) {
$scope.clearFilters = function() {
angular.forEach($scope.Filters[0].filters, function(filter) {
filter.checked = false;
});
$scope.ActiveFilters = [];
};
$scope.IsChecked = false;
$scope.ActiveFilters = [];
$scope.ModifyFilter = function (IsChecked, Filter) {
console.log(IsChecked);
if (IsChecked) {
$scope.ActiveFilters.push(Filter);
}
else {
var indexz = $scope.ActiveFilters.indexOf(Filter);
$scope.ActiveFilters.splice(indexz, 1);
}
};
$scope.Filters =
[
{
"title": "Equipment",
"filters": [
{ name: "Rope", checked: false },
{ name: "Cables", checked: false },
{ name: "Dowel", checked: false },
{ name: "Ball", checked: false }
]
}
];
});
Look into my solution on js fiddle: JsFiddle
In the following code, whenever you delete an item from the delete link in the list, it will only delete the item from the list, but it will not delete the currently selected item. (The item displaying once you click on it). However, if you click on the delete link next to the currently selected item, it will delete from both places.
To replicate what I'm seeing:
Add a bunch of items by typing in the text box and hitting enter a few times.
Select one of the items from the list.
Click delete next to the item when it displays below.
This is the correct behavior.
Select another item you created earlier.
Now click the delete link next to the item in the list.
The item is removed from the list, but not the currently displayed item.
When I step into the code $scope.currentUser is undefined when I click on the delete link in the list.
Why is this happening?
<html ng-app="myApp">
<head>
<script src="http://code.angularjs.org/1.0.1/angular-1.0.1.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.config(function($routeProvider) {
$routeProvider.when('/User/:id', {
controller: UserCtrl,
template: '<h1>{{currentUser.name}}</h1> <a ng-click="deleteUser(currentUser.id)">delete me</a>'
});
});
app.factory('userSvc', function(){
return new UserService();
});
function UserCtrl($scope, $routeParams, $location, userSvc) {
var currUser = userSvc.getUser($routeParams.id);
$scope.currentUser = currUser;
$scope.users = userSvc.getAllUsers();
$scope.addUser = function () {
var user = {
id: userSvc.nextId(),
name: $scope.addUserName
};
userSvc.addUser(user);
$scope.addUserName = '';
$location.url('/User/' + user.id);
};
$scope.deleteUser = function(id) {
if($scope.currentUser != null && $scope.currentUser.id == id) {
$scope.currentUser = null;
}
userSvc.delete(id);
};
};
function UserService() {
var users = [{id: 1, name: 'Ben' }];
this.delete = function(id) {
for(var i = 0; i < users.length; i++) {
var user = users[i];
if(user.id == id) {
users.splice(i,1);
}
}
};
this.addUser = function(user) {
users.push(user);
};
this.getAllUsers = function() {
return users;
};
this.getUser = function(id) {
for(var i = 0; i < users.length; i++) {
var user = users[i];
if(user.id == id) {
return user;
}
}
};
this.nextId = function() {
var maxId = 0;
for(var i = 0; i < users.length; i++) {
var user = users[i];
maxId = Math.max(maxId, user.id);
};
return maxId + 1;
};
}
</script>
</head>
<body>
<div ng-controller="UserCtrl">
<form ng-submit="addUser()">
<input ng-model="addUserName" type="text"/>
<input type="submit" value="Add"/>
</form>
<ul>
<li ng-repeat="user in users">{{user.name}} <a ng-click="deleteUser(user.id)">delete</a></li>
</ul>
</div>
<div ng-view></div>
</body>
</html>
It turns out that selecting a user from the list actually also created a brand new scope that was seperate from the one used to bind the list.
Thanks to Gloopy's comment above to check out Batarang, I was able to see this happen. If this happens to help you, please +1 his comment.
According to the documentation on Scopes some directives will actually cause a new scope to be created. I'm assuming that clicking a link that is being handled by the $routeProvider also results in the creation of a whole new scope tree, likely because it's creating another instance of that controllor.