I'm trying to create a form that will capture input, select and checkbox values and post them to a table. Everything seems to be working fine, with the exception of the checkboxes. What am I doing wrong?
https://jsfiddle.net/mujaji/uvkzmyox/8/
var app = angular.module("myapp", []);
app.controller("ListController", ['$scope', function($scope) {
$scope.jobtypes = ['accountant', 'janitor', 'ceo', 'receptionist'];
$scope.hobbies = [{name: "long walks on the beach", id: "1", isChecked: false},{name: "eating cheese", id: "2", isChecked: false},{name: "writing haikus", id: "3", isChecked: false},{name: "looking for bigfoot", id: "4", isChecked: false},{name: "watching police academy", id: "5", isChecked: false}];
$scope.personalDetails = [
{
'fname':'Muhammed',
'lname':'Shanid',
'jobtype': 'ceo',
'email':'shanid#shanid.com',
'active': true,
'hobbies': [{name: "long walks on the beach", id: "1"},{name: "watching police academy", id: "5"}]
},
{
'fname':'John',
'lname':'Abraham',
'jobtype': 'accountant',
'email':'john#john.com',
'active': true,
'hobbies': [{name: "writing haikus", id: "3"},{name: "looking for bigfoot", id: "4"}]
},
{
'fname':'Roy',
'lname':'Mathew',
'jobtype': 'janitor',
'email':'roy#roy.com',
'active': false,
'hobbies': [{name: "eating cheese", id: "2"}]
}];
$scope.addNew = function(personalDetails){
$scope.personalDetails.push({
'fname': personalDetails.fname,
'lname': personalDetails.lname,
'email': personalDetails.email,
'jobtype': personalDetails.jobtype,
});
$scope.PD = {};
};
$scope.remove = function(){
var newDataList=[];
$scope.selectedAll = false;
angular.forEach($scope.personalDetails, function(selected){
if(!selected.selected){
newDataList.push(selected);
}
});
$scope.personalDetails = newDataList;
};
$scope.checkAll = function () {
if (!$scope.selectedAll) {
$scope.selectedAll = true;
} else {
$scope.selectedAll = false;
}
angular.forEach($scope.personalDetails, function (personalDetails) {
personalDetails.selected = $scope.selectedAll;
});
};
}]);
The problem your facing is caused by the fact that hobbies and their checked state is outside the scope of your addNew(personalDetails) function.
Although not ideal for angular, something like this would work:
$scope.addNew = function(personalDetails) {
//get all checked hobbies
let selectedHobbies = [];
$scope.hobbies.forEach(function(hobby) {
if (hobby.isChecked) selectedHobbies.push(hobby);
});
$scope.personalDetails.push({
'fname': personalDetails.fname,
'lname': personalDetails.lname,
'email': personalDetails.email,
'jobtype': personalDetails.jobtype,
'hobbies': selectedHobbies
});
$scope.PD = {};
};
EDIT
The answer above is really a pure javascript approach to filtering by selected hobbies. A more 'angular' approach would be to break your filter logic out into its own function so that you're not mixing concerns. For example:
Add the 'filterFilter' dependency to your controller:
app.controller("ListController", ['$scope','filterFilter',
function($scope, filterFilter) { ... }
then in your controller, define an array to hold your selected hobbies and add a filter helper to filter by isChecked:
$scope.hobbiesSelection = [];
$scope.selectedHobbies = function selectedHobbies() {
return filterFilter($scope.hobbies, { selected: true });
};
place a watch on the hobbies object to watch for changes to selected hobbies:
$scope.$watch('hobbies|filter:{isChecked: true}', function (hobbies) {
$scope.hobbiesSelection = hobbies;
}, true);
and finally, you can update your addNew() method to simply be:
$scope.addNew = function(personalDetails){
$scope.personalDetails.push({
'fname': personalDetails.fname,
'lname': personalDetails.lname,
'email': personalDetails.email,
'jobtype': personalDetails.jobtype,
'hobbies': $scope.selectedHobbies
});
$scope.PD = {};
};
So while there is a bit more code (and complexity) there for this example, you are separating the logic from the data a bit better. There is working example here: https://jsfiddle.net/mt0tvkwm/
Related
How can i access a method in tableController from my menuController. Here is my code.i want to call addRow() method from select() in menu controller. these controllers are in different modules.Please Help me.
my menu controller
var menuApp = angular.module('menuApp', []);
menuApp.controller('menuController', ['tableService', function ($scope, tableService) {
$scope.menuItem = [
{
id: 1,
title: "new",
navigate:"N",
child: [{
id: 11,
title: "new11",
navigate: "N",
child: [{
id: 12,
title: "new12",
navigate: "Y",
url:"/Home/index"
}]
}]
},
{
id: 2,
title: "new",
child: [{
id: 21,
title: "new21",
child: [{
id: 22,
title: "new22"
}]
}]
}
];
$scope.select = function (data) {
if (data.navigate == "Y") {
alert(data.url);
tableService.add();
}
}
}]);
my table controller
tableApp.controller('tableController', function ($scope, $rootScope, $filter, $uibModal) {
$scope.filteredPeople = [];
$scope.currentPage = 1;
$scope.pageSize = 10;
$scope.people = [{ id: "1", name: "joe",disable:true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe", disable: true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe", disable: true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe", disable: true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe", disable: true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true }];
$scope.addRow = function () {
debugger;
$scope.people.unshift({
id: "",
name: "",
disable:false
});
$scope.getPage();
}
$scope.getPage = function () {
var begin = (($scope.currentPage - 1) * $scope.pageSize);
var end = begin + $scope.pageSize;
$scope.filteredPeople = $filter('filter')($scope.people, {
id: $scope.idFilter,
name: $scope.nameFilter
});
$scope.totalItems = $scope.filteredPeople.length;
$scope.filteredPeople = $scope.filteredPeople.slice(begin, end);
};
$scope.getPage();
$scope.pageChanged = function () {
$scope.getPage();
};
$scope.open = function () {
$scope.id = generateUUID();
};
$scope.dblclick = function (index) {
for (var i = 0; i < $scope.filteredPeople.length; i++) {
$scope.filteredPeople[i].disable = true;
}
return index.disable = false;
}
$scope.rowSelect = function (rowdata) {
alert(rowdata.name);
}
$scope.openInput = function (index) {
debugger;
var modalInstance = $uibModal.open({
templateUrl: '/Home/index',
controller: 'testController',
resolve: {
items: function () {
return index;
},
cat: function () {
return 'Account';
}
}
});
}
});
Example of a service shared between controllers & directives
/**
* store and share data between controllers & directives
*/
angular.module('interfaceApp').service('shareData', function () {
this.datas = [];
this.add = function (data) {
this.datas.push(data);
};
//retourne l'élément correspondant à la clé ( utilise la date comme clé )
this.getElement = function (key) {
......
return ;
};
this.getDatas = function () {
return this.datas;
};
});
/* Controller */
var searchModule = angular.module('searchModule', []);
// inject the service in the controller
.controller('searchCtrl', function ($scope, shareData ) {
shareData.add( ... );
console.log( shareData.getDatas() );
});
A service is a singleton, so all controllers using it acces to the same datas ( when they call shareData.getDatas() )
I need to know how to implement save and restore state in angularui grid without using any buttons. I need to save the state automatically when ever we do any changes in the grid. We have to auto restore the saved state also. Even if we refresh the page the saved state should be restored
Here's what I figured out. I couldn't find a single event for grid state changes, but It does look like they have individual events for almost everything. Here are a few that i'm using. I just set a break point in the onRegisterApi callback and dug through the gridApi object to find the events. http://plnkr.co/edit/LAMZvOkpx6jsD4CWSz04?p=preview
HTML:
<div ui-grid="gridOptions"
ui-grid-selection
ui-grid-resize-columns
ui-grid-auto-resize
ui-grid-move-columns
ui-grid-grouping
ui-grid-save-state>
</div>
JS:
$scope.gridOptions = {
data: [
{ name: 'Jack', title: 'manager', phone: '123456789', location: 'india'},
{ name: 'Suzy', title: 'developer', phone: '465189798', location: 'usa'},
{ name: 'George', title: 'secretary', phone: '82656517', location: 'japan'},
{ name: 'Michael', title: 'analyst', phone: '31321687', location: 'egypt'},
{ name: 'Sara', title: 'consultant', phone: '59595847', location: 'germany'},
{ name: 'Chris', title: 'engineer', phone: '789456123', location: 'russia'},
{ name: 'Elizabeth', title: 'clerk', phone: '963852741', location: 'china'},
{ name: 'Jane', title: 'intern', phone: '147258369', location: 'australia'},
{ name: 'Bill', title: 'accountant', phone: '951487623', location: 'brazil'}
],
columnDefs: [
{ name: 'name' },
{ name: 'title' },
{ name: 'phone' },
{ name: 'location' }
],
enableGridMenu: true,
enableRowSelection: true,
enableRowHeaderSelection: false,
enableColumnResizing: true,
enableColumnReordering: true,
enableFiltering: true,
onRegisterApi: function(gridApi) {
// Keep a reference to the gridApi.
$scope.gridApi = gridApi;
// Setup events so we're notified when grid state changes.
$scope.gridApi.colMovable.on.columnPositionChanged($scope, saveState);
$scope.gridApi.colResizable.on.columnSizeChanged($scope, saveState);
$scope.gridApi.grouping.on.aggregationChanged($scope, saveState);
$scope.gridApi.grouping.on.groupingChanged($scope, saveState);
$scope.gridApi.core.on.columnVisibilityChanged($scope, saveState);
$scope.gridApi.core.on.filterChanged($scope, saveState);
$scope.gridApi.core.on.sortChanged($scope, saveState);
// Restore previously saved state.
restoreState();
}
};
function saveState() {
var state = $scope.gridApi.saveState.save();
localStorageService.set('gridState', state);
}
function restoreState() {
$timeout(function() {
var state = localStorageService.get('gridState');
if (state) $scope.gridApi.saveState.restore($scope, state);
});
}
Here's a service easy to use with localforage
angular.module('starter.controllers')
.factory('SaveStateGridService', function SaveStateGridService($timeout, $state, $rootScope) {
var self = {
stateName: null,
keyLocalStorage: null,
listener: null,
init: function (gridApi) {
self.stateName = $state.$current.name;
self.keyLocalStorage = 'grid-' + self.stateName;
if (self.keyLocalStorage != null) {
// save the state before we leave
self.listerner = $rootScope.$on('$stateChangeStart',
function (event, toState, toParams, fromState, fromParams, options) {
if (fromState.name === self.stateName) {
var item = gridApi.saveState.save();
localforage.setItem(self.keyLocalStorage, item);
}
self.listerner();
}
);
//restore the state when we load if it exists
localforage.getItem(self.keyLocalStorage, function (err, item) {
if (item != null) {
$timeout(function () {
gridApi.saveState.restore(null, item);
}, 1);
}
});
}
}
};
return self;
});
Controller / Component
$scope.gridOptions.onRegisterApi = function (gridApi) {
SaveStateGridService.init(gridApi);
};
Html
<div
ui-grid="gridOptions"
ui-grid-save-state></div>
it's relatively easy to save the state using Angular $cookies
function saveState() {
var state = $scope.gridApi.saveState.save();
$cookies.put('gridState', JSON.stringify(state));
}
Then, to restore:
$scope.restoreState = function() {
$timeout(function() {
var state = JSON.parse($cookies.get('gridState'));
if (state) {
$scope.gridApi.saveState.restore($scope, state);
}
I couldn't find a single event for grid state changes =>
window.onbeforeunload = function(e) {
$scope.saveState();
};
$scope.restoreState();
in case you want to reset the grid
if(localStorage.getItem("justReset")!="1")
$scope.restoreState();
localStorage.setItem("justReset","0")
I have a controller that accesses a resource Tag like so:
$scope.tags = Tag.query();
which resolves to something like this:
$scope.tags = [
{ name: "tag1", label: "Tag1" },
{ name: "tag2", label: "Tag2" },
{ name: "tag3", label: "Tag3" },
{ name: "tag4", label: "Tag4" },
];
For this particular controller, the returned tags should have an additional attribute "active": true, like { name: "tag1", label: "Tag1", active: true }.
How can I iterate over the returned promise once it is resolved to add this boolean?
Use the promise.then() function.
Tag.query().$promise.then(function (results) {
angular.forEach(results, function (result) {
result.active = true;
});
$scope.tags = results
});
see the docs on $q
I think what you need is this:
$scope.tags = Tag.query(function() {
$scope.tags['active'] = true;
});
When the server finishes calling the function that adds the property is executed.
I recommend you read https://docs.angularjs.org/api/ngResource/service/$resource
i cant get and ID from my json api, how can i do that? I am doing like $scope.info.id in my delete function but id doesnt work like that.
Here is my delete function
app.controller('InventoryCtrl', function($scope, $http, Inventory, $location) {
//getting the objects from Inventory
$scope.info = Inventory.query();
$scope.deleteInv = function () {
Inventory.drop({id: $scope.info.id}, function() {
$location.path('/');
});
};
});
here is my factory
app.factory('Inventory', function($resource, $http) {
return $resource('http://localhost/api/v1/inventory/:id', {id: "#id"},
{
drop: {
method: 'DELETE',
params: {id: "#id"}
}
}
);
});
And here is my api
{
meta: {
limit: 20,
next: null,
offset: 0,
previous: null,
total_count: 3
},
objects: [
{
category: {},
count: 1,
created: "2014-02-28T11:54:02.831409",
description: "dasdasdasdsa",
id: 20,
location: "asd",
name: "adas11",
resource_uri: "/api/v1/inventory/20",
status: "sad"
},
{
category: {},
count: 1,
created: "2014-02-28T11:54:03.708003",
description: "dasdasdasdsa",
id: 21,
location: "asd",
name: "adas11",
resource_uri: "/api/v1/inventory/21",
status: "sad"
},
]
}
I don't think you should call "drop" function. Instead you should call the 'delete' function which you specified in your factory.
$scope.deleteInv = function () {
Inventory.delete({id: $scope.info.id}, function() {
$location.path('/');
});
Why is only the one that don't use $resource.get() work? I am using kendo-angular to update. Has this something to do with async? The main variable looks exactly the same so this has to have something to do with $resourse. What am I missing`
This works:
app.controller('SubjectCntrl', ['$scope', 'categoryService', function($scope, categoryService) {
var main = categoryService.getCategories();
var subjects = {
data : [main]
};
$scope.subjects = {
dataSource: subjects
};
}]);
This does not:
app.controller('SubjectCntrl', ['$scope', 'categoryService', 'ApiFactory', function($scope, categoryService, ApiFactory) {
ApiFactory.get(function(categoriesData) {
var main = categoryService.getCategories();
var subjects = {
data : [main]
};
$scope.subjects = {
dataSource: subjects
};
});
}]);
The factory:
app.factory('ApiFactory', ['$resource', function($resource) {
return $resource('http://localhost:8080/rest/forum/categories/1');
}]);
Service:
app.service('categoryService', ['$resource', function($resource){
this.getCategories = function(){
var farmingSubjects = [ {text: "Poteter", spriteCssClass: "subject"}, {text: "Agurk", spriteCssClass: "subject"} ];
var forestSubjects = [ {text: "Tall", spriteCssClass: "subject"}, {text: "Gran", spriteCssClass: "subject"} ];
var animalSubjects = [ {text: "Hundar", spriteCssClass: "subject"}, {text: "Katter", spriteCssClass: "subject"} ];
var farming = { text: "Jordbruk", items: farmingSubjects };
var forest = { text: "Skogshold", items: forestSubjects };
var animals = { text: "Dyrebruk", items: animalSubjects };
var subjects = [farming, forest, animals ];
var main = { text: "Huvudemner", expanded: true, items: subjects};
return main;
};
}]);
Edit: The success function is called without doubt.
ApiFactory.get(function(data){
console.log('success, got data: ', data);
}, function(err){
alert('request failed');
});
I think the second case is not working because you ApiFactory call is failing. The callback you have declared is for success.