won't remove automatically after it deleted from localstorage - angularjs

First, here's the code
controller.js
.controller('FavoritesController', ['$scope', 'dishes', 'favorites', 'favoriteFactory', 'baseURL', '$ionicListDelegate', '$ionicPopup', '$ionicLoading', '$timeout', '$localStorage', function ($scope, dishes, favorites, favoriteFactory, baseURL, $ionicListDelegate, $ionicPopup, $ionicLoading, $timeout, $localStorage) {
$scope.baseURL = baseURL;
$scope.shouldShowDelete = false;
$scope.favorites = favorites;
$scope.dishes = dishes;
console.log($scope.dishes, $scope.favorites);
$scope.toggleDelete = function () {
$scope.shouldShowDelete = !$scope.shouldShowDelete;
console.log($scope.shouldShowDelete);
}
$scope.deleteFavorite = function (index) {
var confirmPopup = $ionicPopup.confirm({
title: 'Confirm Delete',
template: 'Are you sure you want to delete this item?'
});
confirmPopup.then(function (res) {
if (res) {
console.log('Ok to delete');
favoriteFactory.deleteFromFavorites(index);
var old_favorite = JSON.parse($localStorage.get('favorites'));
var leng = Object.keys(old_favorite).length;
for (var i = 0; i < leng; i++) {
if (Object.keys(old_favorite)[i] == index) {
console.log("Deleted from localstorage! " + Object.keys(old_favorite)[i]);
old_favorite.splice(old_favorite.indexOf(index), 1);
$localStorage.storeObject('favorites', old_favorite);
}
}
} else {
console.log('Canceled delete');
}
});
$scope.shouldShowDelete = false;
}
}])
services.js
.factory('favoriteFactory', ['$resource', 'baseURL', function ($resource, baseURL) {
var favFac = {};
var favorites = [];
favFac.addToFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index)
return;
}
favorites.push({id: index});
};
favFac.deleteFromFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index) {
favorites.splice(i, 1);
console.log("Deleted !" + index);
}
}
}
favFac.getFavorites = function () {
return favorites;
};
return favFac;
}])
favorites.html
<ion-view view-title="My Favorites">
<ion-nav-buttons side="secondary">
<div class="buttons">
<button class="button button-icon icon ion-ios-minus-outline"
ng-click="toggleDelete()"></button>
</div>
</ion-nav-buttons>
<ion-content>
<ion-list show-delete="shouldShowDelete">
<ion-item ng-repeat="dish in dishes | favoriteFilter:favorites" href="#/app/menu/{{dish.id}}" class="item-thumbnail-left" on-swipe-left="deleteFavorite(dish.id)">
<img ng-src="{{baseURL+dish.image}}" on-swipe-left="deleteFavorite(dish.id)">
<h2>{{dish.name}}
<span style="font-size:75%">{{dish.price | currency}}</span>
<span class="badge badge-assertive">{{dish.label}}</span></h2>
<p>{{dish.description}}</p>
<ion-delete-button class="ion-minus-circled"
ng-click="deleteFavorite(dish.id)">
</ion-delete-button>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
app.js
.state('app.favorites', {
url: '/favorites',
views: {
'mainContent': {
templateUrl: 'templates/favorites.html',
controller:'FavoritesController',
resolve: {
dishes: ['menuFactory', function(menuFactory){
return menuFactory.query();
}],
favorites: ['favoriteFactory', function(favoriteFactory) {
return favoriteFactory.getFavorites();
}]
}
}
}
})
So, after I attempt to use the deleteFavorite Function from the controller.js and the index inside the localstorage was success deleted, the data on the favorites.html couldn't updated, it couldn't deleted from the favorties.html immediately.
I need to refresh my browser first to show the up-to-date list based on the localstorage.
I hope that I can show the up-to-date data based on the localstorage data without refresh the page.
Did I make something wrong on here?
Thank you in advance!

Related

Scope from controller does not pass to directive

I have a html like this :
<div id="create-group" ng-controller="groupCreateController">
<div id="container">
<h1>Create group</h1>
<div class="row">
<div class="col-md-4"><input placeholder="Group Name.." ng-model="group.name"></div>
<div class="col-md-8">
<label>Group Description : </label>
<textarea ng-model="group.description"> </textarea>
</div>
</div>
<br/>
<div class="row">
<div class="col-sm-6">
<usermgr-permission-list group="group"></usermgr-permission-list>
<button type="button" class="btn btn-md btn-primary" ng-click="btnSave_click($event)">SAVE</button>
</div>
<div class="col-sm-6">
<usermgr-user-list group="group"></usermgr-user-list>
</div>
</div>
</div>
</div>
My controller is :
(function (module) {
'use strict';
module.controller('groupCreateController', function ($scope, $rootScope, $routeParams, $location, userGroupService, $mdDialog) {
$scope.group = [];
$scope.init = function () {
if ($routeParams.hasOwnProperty('id')) {
//edit mode
// $scope.trans.heading = 'Edit Release';
// $scope.trans.saveBtn = 'Save';
var id = parseInt($routeParams.id);
getUserGroup(id);
} else {
$scope.group[0].id = 0;
$scope.group[0].permissions = [];
$scope.assignedPermissions = [];
$scope.enrolledUsers = [];
$scope.group[0].users = [];
$scope.group[0].name = '';
$scope.group[0].description = '';
}
};
function getUserGroup(id) {
userGroupService.getbyid(id).then(function (info) {
if (info !== undefined && info.id === id) {
$scope.group[0].id = info.id;
$scope.group[0].name = info.name;
$scope.group[0].description = info.description;
console.log($scope.group);
// $rootScope.$broadcast('rCube-user-mgt-users-list', info.id);
// $rootScope.$broadcast('rCube-user-mgt-permissions-list', info.id);
}
else {
}
}).catch(function (exception) {
console.error(exception);
});
}
$scope.init();
});
})(angular.module('r-cube-user-mgt.user-group'));
I have two custom directives in the first block of code for user permissions and users. The group scope that i pass with the directive does not contain the values i put in the getUserGroup(id) function. The group name and group description shows up so the scope.group in the controller is filled, however thats not the case once i pass it to my directives. here is the directives code as well :
permissions list :
(function (module) {
'use strict';
module.directive('usermgrPermissionList', function () {
return {
restrict: 'E',
scope:{
group: '='
},
controller: function ($scope, permissionService) {
$scope.updatedPermissions=[];
console.log($scope.group); //it doesnt have the values from the controller ..
if (!$scope.group.hasOwnProperty('permissions')) {
$scope.group.permissions = [];
}
function getData() {
console.log("inside getDAta for permission list" + $scope.group.id;
permissionService.getPermissionsFiltered($scope.group.id).then(function (info) {
if (info && info.length > 0) {
console.log(info);
$scope.group.permissions = info.map(function (a, index, array) {
return {
id: a.id,
name: a.name,
description: a.description,
assigned: a.assigned
};
});
}
}).catch(function (exception) {
console.error(exception);
});
} //end of getData()
$scope.init = function () {
getData();
};
$scope.init();
},
templateUrl: 'r-cube-user-mgt/permission/list/list.tpl.html'
};
});
})(angular.module('r-cube-user-mgt.permission'));
can anyone help?
you cannot assign property to an array like this $scope.group.id = 0;
either make $scope.group object
$scope.group = {};
or add properties to an index
$scope.group = [];
$scope.init = function () {
if ($routeParams.hasOwnProperty('id')) {
//edit mode
// $scope.trans.heading = 'Edit Release';
// $scope.trans.saveBtn = 'Save';
var id = parseInt($routeParams.id);
getUserGroup(id);
} else {
$scope.group[0].id = 0;
$scope.group[0].permissions = [];
$scope.assignedPermissions = [];
$scope.enrolledUsers = [];
$scope.group[0].users = [];
$scope.group[0].name = '';
$scope.group[0].description = '';
}
};
So I solved the issue by adding broadcast to send the id when the directive loads. This worked!
in the Group controller i add broadcast and send the group.id
function getUserGroup(id) {
userGroupService.getbyid(id).then(function (info) {
if (info !== undefined && info.id === id) {
$scope.group.id = info.id;
$scope.group.name = info.name;
$scope.group.description = info.description;
console.log($scope.group);
$rootScope.$broadcast(rCubeTopics.userMgtPermissionLoadData, $scope.group.id);
}
}).catch(function (exception) {
console.error(exception);
});
}
and in the permission directive get that broadcast :
$scope.$on(rCubeTopics.userMgtPermissionLoadData, function (event, id) {
console.log($scope.group.id);
getData();
});

Passing data in master detail view in Ionic using this (NOT Scope)?

UPDATE
The service seem to be fetching data but when the data is sent to controller, it is undefined. Adding the service.js file for reference as well
service.js
.service('VideosModel', function ($http, Backand) {
var service = this,
baseUrl = '/1/objects/',
objectName = 'videos/';
function getUrl() {
return Backand.getApiUrl() + baseUrl + objectName;
}
function getUrlForId(id) {
return getUrl() + id;
}
service.all = function () {
console.log($http.get(getUrl()));
return $http.get(getUrl());
};
service.fetch = function (id) {
console.log('Inside s');
console.log($http.get(getUrlForId(id)));
return $http.get(getUrlForId(id));
};
service.create = function (object) {
return $http.post(getUrl(), object);
};
service.update = function (id, object) {
return $http.put(getUrlForId(id), object);
};
service.delete = function (id) {
return $http.delete(getUrlForId(id));
};
})
Pic
I am trying to implement the master-detail view on one of the tabs in my app using this instead of scope (example using scope here). But my details view is not getting the data/ it is saying undefined for detailsCtrl. I believe I'm making a mistake in my controller or app.js but I don't really have an idea about how to fix it.
master.html
<ion-view view-title="Videos">
<div ng-if="!vm.isCreating && !vm.isEditing">
<ion-content class="padding has-header">
<!-- LIST -->
<div class="row gallery">
<div class="list card col col-25" ng-repeat="object in vm.data"
ng-class="{'active':vm.isCurrent(object.id)}">
<a class="cardclick" href="#/details/{{object.id}}">
<div class="item item-image">
<img ng-src="{{object.img}}"/>
</div>
<div class="item item-icon-left assertive">
<i class="icon ion-play"></i>
<p> Watch</p>
<h2> {{object.title}} </h2>
</div>
</a>
</div>
</div>
</ion-content>
</div>
details view or videoplayer.html
<ion-view title="Now Playing" hide-nav-bar="true">
<div class="modal transparent fullscreen-player">
<video src="{{object.src}}" class="centerme" controls="controls" autoplay></video>
</div>
app.js
$stateProvider
// setup an abstract state for the tabs directive
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl as login'
})
.state('forgotpassword', {
url: '/forgot-password',
templateUrl: 'templates/forgot-password.html',
})
.state('tab', {
url: '/tabs',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.videos', {
url: '/videos',
views: {
'tab-videos': {
templateUrl: 'templates/tab-videos.html',
controller: 'VideosCtrl as vm'
}
}
})
.state('tab.games', {
url: '/games',
views: {
'tab-games': {
templateUrl: 'templates/tab-games.html'
}
}
})
.state('tab.help', {
url: '/help',
views: {
'tab-help': {
templateUrl: 'templates/tab-help.html'
}
}
})
.state('details', {
url: "/details/:id",
templateUrl: 'templates/videoplayer.html',
controller: 'detailsCtrl as vm'
});
$urlRouterProvider.otherwise('/login');
$httpProvider.interceptors.push('APIInterceptor');
})
controller
.controller('VideosCtrl', function (VideosModel, $rootScope) {
var vm = this;
function goToBackand() {
window.location = 'http://docs.backand.com';
}
function getAll() {
vm.data=[];
VideosModel.all()
.then(function (result) {
vm.data = result.data.data;
console.log(vm.data);
});
}
function initCreateForm() {
vm.newObject = {name: '', description: ''};
}
function setEdited(object) {
vm.edited = angular.copy(object);
vm.isEditing = true;
}
function isCurrent(id) {
return vm.edited !== null && vm.edited.id === id;
}
function cancelEditing() {
vm.edited = null;
vm.isEditing = false;
}
function cancelCreate() {
initCreateForm();
vm.isCreating = false;
}
function clearData(){
vm.data = null;
}
function create(object) {
VideosModel.create(object)
.then(function (result) {
cancelCreate();
getAll();
});
}
function update(object) {
VideosModel.update(object.id, object)
.then(function (result) {
cancelEditing();
getAll();
});
}
function deleteObject(id) {
VideosModel.delete(id)
.then(function (result) {
cancelEditing();
getAll();
});
}
vm.edited = null;
vm.isEditing = false;
vm.isCreating = false;
vm.getAll = getAll;
vm.create = create;
vm.update = update;
vm.delete = deleteObject;
vm.setEdited = setEdited;
vm.isCurrent = isCurrent;
vm.cancelEditing = cancelEditing;
vm.cancelCreate = cancelCreate;
vm.goToBackand = goToBackand;
vm.isAuthorized = false;
$rootScope.$on('authorized', function () {
vm.isAuthorized = true;
getAll();
});
$rootScope.$on('logout', function () {
clearData();
});
if(!vm.isAuthorized){
$rootScope.$broadcast('logout');
}
initCreateForm();
getAll();
})
.controller('detailsCtrl',function($stateParams,VideosModel){
var vm = this;
var videoId = $stateParams.id;
function getforId(id) {
vm.data=[];
VideosModel.fetch(id)
.then(function (result) {
vm.data = result.data.data;
console.log(vm.data);
});
}
getforId(videoId);
});
How do pass the data using this?
In order to use controllerAs syntax (bind your scope properties to 'this' in the controller) you need to give your controller an alias in the html.
<div ng-controller="detailsCtrl as vm">
By default, your html is going to reference $scope on your controller unless you give it an alias.
https://docs.angularjs.org/api/ng/directive/ngController

$digest already in progress when i use ionicplatform.ready with camera functionality

This is my controller, i am trying to capture image with a button in page 1 and store it locally, and display image1 in page 1, then if i click the button again to take the pic of image2. Image2 should be displayed in page1 and image1 should be viewed in page2
.controller('LeadDetailController', [
'$scope',
'$cordovaDevice',
'$cordovaFile',
'$ionicPlatform',
'ImageService', 'FileService',
function( $scope,
$cordovaDevice,
$cordovaFile,
$ionicPlatform,
ImageService, FileService) {
// image capture code
$ionicPlatform.ready(function() {
console.log('ionic is ready');
$scope.images = FileService.images();
$scope.$apply();
});
$scope.urlForImage = function(imageName) {
var trueOrigin = cordova.file.dataDirectory + imageName;
return trueOrigin;
}
$scope.addImage = function(type) {
ImageService.handleMediaDialog(type).then(function() {
$scope.$apply();
});
}
at the initial stage itself i am getting this error
Error: [$rootScope:inprog] $digest already in progress
page1 with buttons
// here camera function is called to open the camera and take pic
<ion-option-button ng-click="addImage()"class="icon ion-android-camera"></ion-option-button>
//here the pic taken in camera should be displayed
<ion-option-button>
<img src="">
</ion-option-button>
//here moveing to the next page2
<ion-option-button ng-click="Page2()" class="icon ion-ios-grid-view"></ion-option-button>
page2 html
<ion-view>
<ion-nav-bar class="bar-positive">
<ion-nav-title class="title">Grid View</ion-nav-title>
</ion-nav-bar>
<ion-content class="has-header">
<img ng-repeat="image in images" ng-src="{{image.src}}" ng-click="showImages($index)" style="height:50%; width:50%; padding:2px ">
</ion-content>
</ion-view>
page2 controller
.controller('gridController', function($scope, $ionicBackdrop, $ionicModal, $ionicSlideBoxDelegate, $ionicScrollDelegate) {
//here the images are stored inside the array
$scope.images = [{ }];
services
.factory('FileService', function() {
var images;
var IMAGE_STORAGE_KEY = 'images';
function getImages() {
var img = window.localStorage.getItem(IMAGE_STORAGE_KEY);
if (img) {
images = JSON.parse(img);
} else {
images = [];
}
return images;
};
function addImage(img) {
images.push(img);
window.localStorage.setItem(IMAGE_STORAGE_KEY, JSON.stringify(images));
};
return {
storeImage: addImage,
images: getImages
}
})
.factory('ImageService', function($cordovaCamera, FileService, $q, $cordovaFile) {
function makeid() {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < 5; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
function optionsForType(type) {
var source;
/* switch (type) {
case 0:
source = Camera.PictureSourceType.CAMERA;
break;
case 1:
source = Camera.PictureSourceType.PHOTOLIBRARY;
break;
}*/
return {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: source,
allowEdit: false,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false
};
}
function saveMedia(type) {
return $q(function(resolve, reject) {
var options = optionsForType(type);
$cordovaCamera.getPicture(options).then(function(imageUrl) {
var name = imageUrl.substr(imageUrl.lastIndexOf('/') + 1);
var namePath = imageUrl.substr(0, imageUrl.lastIndexOf('/') + 1);
var newName = makeid() + name;
$cordovaFile.copyFile(namePath, name, cordova.file.dataDirectory, newName)
.then(function(info) {
FileService.storeImage(newName);
resolve();
}, function(e) {
reject();
});
});
})
}
return {
handleMediaDialog: saveMedia
}
});
could someone help me to fix this issue and to help me with page2 to imageviewing
As stated by #Ila the problem is likely due to $scope.$apply().
So if you can't predict if it has to be used then insert in an if statement as follows:
if(!$scope.$$phase) {
// no digest in progress...
$scope.$apply();
}
However this is not a good practice: prefer to use $scope.$apply() only when really needed (). See Angular docs
I agree with vb-platform. But what you can also do is wrapping your code into a $timeout so angularjs would handle the $apply for you ($timeout):
$ionicPlatform.ready(function() {
console.log('ionic is ready');
$timeout(function setImages() {
$scope.images = FileService.images();
});
});

Ionic list, how to update a specific item?

I am developing an ios app with angularjs and ionic.
I don't know how to get a specific item in a list to be updated ?
Here is my view :
mesReservations.html
<ion-view cache-view="false" view-title="Mes reservations">
<ion-pane>
<ion-content class="padding">
<ion-list>
<ion-item ng-repeat="reservation in listeReservations" class="item item-button-right">
{{reservation.nomLoisir}}
<p>{{reservation.dateReservation}} |{{reservation.heureReservation}} | {{reservation.nbrpersonne}} pers</p>
<p>{{reservation.etatResa}}</p>
<div class="buttons">
<button class="button button-small" ng-click="annulerReservation(reservation.idReservation)">
<i class="icon ion-close"></i>
</button>
</div>
</ion-item>
</ion-list>
<ion-infinite-scroll ng-if="!theEnd" on-infinite="loadMore()" distance="50%"></ion-infinite-scroll>
</ion-content>
</ion-pane>
</ion-view>
my controller : mesReservetionsController.js
(function () {
'use strict';
angular
.module('starter')
.controller('MesReservationsController', MesReservationsController);
MesReservationsController.$inject = ['ReservationService', '$scope', '$state'];
function MesReservationsController (ReservationService, $scope, $state) {
$scope.listeReservations = [];
$scope.theEnd = false;
var page = 0;
$scope.enable= true;
//chargerReservations();
$scope.loadMore = function () {
page++;
ReservationService.listReservation(page)
.then(function (result) {
if(result.params.reservation.length > 0){
angular.forEach(result.params.reservation, function (value, key) {
$scope.listeReservations.push(value);
})
}
else {
$scope.theEnd = true;
}
})
.finally(function () {
$scope.$broadcast("scroll.infiniteScrollComplete");
});
}
/*$scope.confirmerReservation = function (idReservation) {
ReservationService.confirmerReservation(idReservation).then(function (res) {
if(res.statut==="1"){
chargerReservations();
alert(res.message);
}
});
};*/
$scope.partagerReservation = function (idReservation) {
alert("That's to share your reservation");
}
$scope.showMap = function () {
alert("That shall show map");
}
$scope.changerReservation = function (idReservation) {
debugger
$state.go('detailReservation', {idReservation: idReservation});
}
$scope.detailLoisir = function () {
alert("that shall show detail");
}
$scope.annulerReservation = function (idReservation) {
debugger
$scope.enable= false;
ReservationService.annulerReservation(idReservation).then(function (res) {
if(res.statut==="1"){
alert(res.message);
}
});
};
function chargerReservations (page) {
debugger
ReservationService.listReservation(page).then(function (res) {
if(res.statut==="1"){
$scope.$apply(function () {
$scope.listeReservations = res.params.reservation;
})
}
});
}
}
})();
What I need is to update {{reservation.etatResa}} when ReservationService.annulerReservation() is called without having to reload the list from server?
Pass the entire object to your method instead of just the id:
ng-click="annulerReservation(reservation)"
Then you can simply modify it as you want (for example when the ReservationService.annulerReservation call has succeeded):
reservation.etatResa = 'Whatever';
Don't forget to change so you pass the id to the service (if that is what it needs):
ReservationService.annulerReservation(reservation.idReservation).then( ... )

AngularUI router issue "TypeError: Cannot read property 'name' of undefined"

I have a set of DIV's that contain A's and use AngularUI to load Angular templates within a ui-view DIV. I'm implementing a set of tabs that switch between the view templates based on which one a user clicks. I have several of these within the application and all work as designed. However, on one of my pages I keep getting a "TypeError: Cannot read property 'name' of undefined" that blows up in the angular-ui-router isMatch() call in the $StateRefActiveDirective($state, $stateParams, $interpolate) function on the line 'return $state.includes(state.name) && matchesParams();' because state is not defined. I've stepped through the calls to this code and it processes all of the ui-srefs in my markup successfully. Then after those are processed it gags.
The only real difference between other pages with these tabs on them is that I have the other pages with no other markup on them except the tabs and their ui-views. On this one I have 2 bootstrap columns, a col-md-5 and col-md-7. The col-md-5 contains a table of objects. When the user clicks on one of the rows the col-md-7 is shown, the $state is changed to one of its tabs and the data for the object is loaded for the tab by its controller.
On the other pages the tabs are always displayed and clicking them takes you to different ui-views the same as the my problem child. One real difference between them is a directive I wrote to 'disable' the links based on a Boolean. The uiSrefIf directive is at the bottom of the JavaScript listing. The idea is that when the File tab is shown the other tabs are visible but disabled.
Here is the JavaScript and markup:
angular.module('meritApp.screens.importUsers', [
'ui.router', 'ngSanitize', 'ui.select', 'ui.bootstrap', 'meritApp.global.services.profile',
'meritApp.global.services.common', 'angularFileUpload', 'meritApp.global.services.managedFiles'
])
.config(function($stateProvider) {
$stateProvider
.state('importUsers', {
url: "/admin/importUsers",
templateUrl: "app/screens/admin/importUsers/importUsers.html?v=" + APP_VERSION
});
$stateProvider
.state('importUsers.file', {
url: "/file",
templateUrl: "app/screens/admin/importUsers/file.html?v=" + APP_VERSION
});
$stateProvider
.state('importUsers.inserted', {
url: "/inserted",
templateUrl: "app/screens/admin/importUsers/inserted.html?v=" + APP_VERSION
});
$stateProvider
.state('importUsers.insertError', {
url: "/insertError",
templateUrl: "app/screens/admin/importUsers/insertError.html?v=" + APP_VERSION
});
$stateProvider
.state('importUsers.skipped', {
url: "/skipped",
templateUrl: "app/screens/admin/importUsers/skipped.html?v=" + APP_VERSION
});
$stateProvider
.state('importUsers.updated', {
url: "/updated",
templateUrl: "app/screens/admin/importUsers/updated.html?v=" + APP_VERSION
});
})
.controller('importUsersController', [
'$scope', '$state', '$log', '$rootScope', '$filter', 'appConfig', '$http', 'roleSvc',
function($scope, $state, $log, $rootScope, $filter, appConfig, $http, roleSvc) {
$rootScope.$broadcast("SET_BREADCRUMB", []);
$scope.itemsPerPage = 10;
$scope.currentPage = 1;
$rootScope.importing = false;
$rootScope.roleChanged = function(user, role) {
// todo - set the user's role
};
$scope.newImport = function() {
$rootScope.importing = true;
$rootScope.savedLocation = $rootScope.selectedLocation;
$rootScope.selectedLocation = null;
};
$rootScope.defaultRole = {
name: "Associate"
};
roleSvc.listAllActive(0, 40).then(
function(response) {
$rootScope.roles = $filter('orderBy')(response.data.results, "name");
angular.forEach($rootScope.roles, function(role) {
if (role.name == "Associate") {
$rootScope.defaultRole = role;
}
});
},
function(err) {
console.log("roleSvc.listAllActive Error: " + err.status + " " + err.statusText);
});
var init = function() {
$scope.loading = true;
$scope.locations = [];
var skip = ($scope.currentPage - 1) * $scope.itemsPerPage;
var userImportQueryPath = "queries/Merit.Components.UserImport.Queries/UserImportQueries";
$http.get(appConfig.urlRoot + userImportQueryPath + "/GetImportSummaries/results").then(
function(response) {
$scope.totalItems = response.data.results.length;
angular.forEach(response.data.results, function(location) {
if (skip-- <= 0 && $scope.locations.length < $scope.itemsPerPage) {
$scope.locations.push(location);
}
});
$scope.loading = false;
}, function(err) {
alert("GetImportList Error: " + err.status + " - " + err.statusText);
});
$http.get(appConfig.urlRoot + userImportQueryPath + "/GetAuditRecords/results").then(
function(response) {
$rootScope.importData = [];
angular.forEach(response.data.results, function(record) {
record["isInvited"] = false;
record["selectedRole"] = $rootScope.defaultRole;
record.errorText = JSON.parse(record.errorText);
$rootScope.importData.push(record);
});
$scope.users = _.sortBy($rootScope.importData, 'employeeId');
}, function(err) {
alert("GetImportList Error: " + err.status + " - " + err.statusText);
});
};
init();
$scope.refresh = function() {
init();
};
$scope.viewImports = function(location) {
$rootScope.selectedLocation = location;
$state.go('importUsers.inserted', {}, {
reload: true
});
};
$rootScope.closeView = function() {
$rootScope.importing = false;
if ($rootScope.savedLocation) {
$rootScope.selectedLocation = $rootScope.savedLocation;
$rootScope.savedLocation = null;
} else {
$rootScope.selectedLocation = null;
}
};
$scope.inviteUsers = function() {
angular.forEach($scope.users, function(userArray) {
if (userArray) {
angular.forEach(userArray, function(user) {
if (user.isInvited) {
// todo - send email to invited user
console.log("Sending email to " + user.name);
user.isInvited = false;
}
});
}
});
};
}
])
.controller('iuInsertedController', [
'$scope', '$state', '$log', '$rootScope',
function($scope, $state, $log, $rootScope) {
$rootScope.$broadcast("SET_BREADCRUMB", []);
$scope.itemsPerPage = 10;
$scope.selectedTab = "Inserted";
$scope.currentPage = 1;
$scope.inviteCount = 0;
var init = function() {
$scope.users = [];
$scope.totalItems = 0;
if (!$rootScope.selectedLocation) return;
var skip = ($scope.currentPage - 1) * $scope.itemsPerPage;
angular.forEach($rootScope.importData, function(user) {
if (user.isInserted && !user.hasErrors && user.locationCode == $rootScope.selectedLocation.code && user.timestampUtc == $rootScope.selectedLocation.timeStampUtc) {
if (skip-- <= 0 && $scope.users.length < $scope.itemsPerPage)
$scope.users.push(user);
$scope.totalItems++;
}
});
};
init();
$scope.refresh = function() {
init();
};
$scope.invite = function(user) {
$scope.inviteCount = (user.isInvited ? $scope.inviteCount + 1 : $scope.inviteCount - 1);
};
$scope.inviteUsers = function() {
alert("todo - send email to invited users");
angular.forEach($scope.users, function(user) {
if (user.isInvited) {
// todo - send email to invited user
console.log("Sending email to " + user.name);
user.isInvited = false;
}
});
};
}
])
.controller('iuInsertErrorController', [
'$scope', '$state', '$log', '$rootScope',
function($scope, $state, $log, $rootScope) {
$rootScope.$broadcast("SET_BREADCRUMB", []);
$scope.itemsPerPage = 10;
$scope.currentPage = 1;
$scope.selectedTab = "Inserted with Errors";
var importData = $rootScope.importData;
var init = function() {
$scope.users = [];
$scope.totalItems = 0;
if (!$rootScope.selectedLocation) return;
var skip = ($scope.currentPage - 1) * $scope.itemsPerPage;
angular.forEach(importData, function(user) {
if (user.isInserted && user.hasErrors && user.locationCode == $rootScope.selectedLocation.code && user.timestampUtc == $rootScope.selectedLocation.timeStampUtc) {
if (skip-- <= 0 && $scope.users.length < $scope.itemsPerPage)
$scope.users.push(user);
$scope.totalItems++;
}
});
};
init();
$scope.refresh = function() {
init();
};
$scope.inviteUsers = function() {
angular.forEach($scope.users, function(userArray) {
if (userArray) {
angular.forEach(userArray, function(user) {
if (user.isInvited) {
// todo - send email to invited user
console.log("Sending email to " + user.name);
user.isInvited = false;
}
});
}
});
};
}
])
.controller('iuUpdatedController', [
'$scope', '$state', '$log', '$rootScope',
function($scope, $state, $log, $rootScope) {
$rootScope.$broadcast("SET_BREADCRUMB", []);
$scope.itemsPerPage = 10;
$scope.currentPage = 1;
$scope.selectedTab = "Updated";
var init = function() {
$scope.users = [];
$scope.totalItems = 0;
if (!$rootScope.selectedLocation) return;
var skip = ($scope.currentPage - 1) * $scope.itemsPerPage;
angular.forEach($rootScope.importData, function(user) {
if (user.isUpdated && user.locationCode == $rootScope.selectedLocation.code && user.timestampUtc == $rootScope.selectedLocation.timeStampUtc) {
if (skip-- <= 0 && $scope.users.length < $scope.itemsPerPage)
$scope.users.push(user);
$scope.totalItems++;
}
});
};
init();
$scope.refresh = function() {
init();
};
$scope.inviteUsers = function() {
angular.forEach($scope.users, function(userArray) {
if (userArray) {
angular.forEach(userArray, function(user) {
if (user.isInvited) {
// todo - send email to invited user
console.log("Sending email to " + user.name);
user.isInvited = false;
}
});
}
});
};
}
])
.controller('iuSkippedController', [
'$scope', '$state', '$log', '$rootScope',
function($scope, $state, $log, $rootScope) {
$rootScope.$broadcast("SET_BREADCRUMB", []);
$scope.itemsPerPage = 10;
$scope.currentPage = 1;
$scope.selectedTab = "Skipped";
var init = function() {
$scope.users = [];
$scope.totalItems = 0;
if (!$rootScope.selectedLocation) return;
var skip = ($scope.currentPage - 1) * $scope.itemsPerPage;
angular.forEach($rootScope.importData, function(user) {
if (user.wasSkipped && user.locationCode == $rootScope.selectedLocation.code && user.timestampUtc == $rootScope.selectedLocation.timeStampUtc) {
if (skip-- <= 0 && $scope.users.length < $scope.itemsPerPage)
$scope.users.push(user);
$scope.totalItems++;
}
});
};
init();
$scope.refresh = function() {
init();
};
$scope.inviteUsers = function() {
angular.forEach($scope.users, function(userArray) {
if (userArray) {
angular.forEach(userArray, function(user) {
if (user.isInvited) {
// todo - send email to invited user
console.log("Sending email to " + user.name);
user.isInvited = false;
}
});
}
});
};
}
])
.controller('iuFileController', [
'$scope', '$state', '$log', '$rootScope', 'managedFileSvc', 'commandSvc', 'appConfig', '$http', 'modalMsgSvc',
function($scope, $state, $log, $rootScope, managedFileSvc, commandSvc, appConfig, $http, modalMsgSvc) {
$rootScope.$broadcast("SET_BREADCRUMB", []);
$scope.locations = mockExtraLocations;
$scope.importLocation = undefined;
$scope.importFile = undefined;
$scope.buttonText = "Browse...";
var locationsQueryPath = "queries/Merit.Components.Locations.Queries/LocationQueries";
$http.get(appConfig.urlRoot + locationsQueryPath + "/FindAllActive/results?skip=" + 0 + "&pageSize=" + 20).then(
function(response) {
$scope.locations = response.data.results;
}, function(err) {
console.log("LocationQueries.FindAllActive Error: " + err.status + " - " + err.statusText);
});
$scope.doImport = function() {
managedFileSvc.uploadFile($scope.importFile, function(evt) {
console.log(evt);
$scope.uploadProgress = evt;
}, function(response) {
console.log('upload response :: File ID: ', response[0].QueryReferences[0].QueryParameter);
var command = {
ImportFileId: response[0].QueryReferences[0].QueryParameter,
LocationCode: $scope.importLocation.code,
LocationName: $scope.importLocation.name
};
modalMsgSvc.showLoading("Importing...");
commandSvc.publish('Merit.Components.User.Commands', 'ImportHumanicUsers', command)
.then(function(record) {
modalMsgSvc.hideLoading();
console.log("ImportHumanicUsers Published: " + record.status);
$scope.importFile = undefined;
$rootScope.closeView();
$state.go("importUsers", {}, {
reload: true
});
}, function(err) {
modalMsgSvc.hideLoading();
if (err.errors)
console.log("ImportHumanicUsers ERROR: " + err.errors[0]);
else if (err.errorHeadline)
console.log("ImportHumanicUsers ERROR: " + err.errorHeadline);
else
console.log("ImportHumanicUsers ERROR: unknown");
// TODO?
});
});
};
$scope.fileSelected = function(files) {
// even though ng-multiple is false, we still get an array
if (files != null) {
$scope.importFile = files[0];
}
};
$scope.cancelImport = function() {
$scope.importFile = undefined;
$rootScope.closeView();
if ($rootScope.selectedLocation)
$state.go("importUsers.inserted");
};
}
])
.directive('uiSrefIf', function($compile) {
return {
scope: {
val: '#uiSrefVal',
if : '=uiSrefIf'
},
link: function($scope, $element, $attrs) {
$element.removeAttr('ui-sref-if');
$compile($element)($scope);
$scope.$watch('if', function(bool) {
if (bool) {
$element.attr('ui-sref', $scope.val);
} else {
$element.removeAttr('ui-sref');
$element.removeAttr('href');
}
$compile($element)($scope);
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="importUsersController">
<div class="row">
<div class="col-md-5">
<div class="table importLocationsCol">
<div class="row headerRow titleBar">
<div class="col-md-9"><i class="icon-users"></i>Import Users</div>
<div class="col-md-3 importNewBtnDiv">
<div class="btn btn-cancel importNewButton" ng-click="newImport()" ui-sref-opts="{reload: true}">
<a ui-sref="importUsers.file" style="text-decoration: none !important; color: #585858;">New</a>
</div>
</div>
</div>
<div class="row">
<h4>Past Imports</h4>
</div>
<div class="row">
<table class="table table-striped deptTable importTable">
<thead>
<tr>
<th class="importNameCol">Location</th>
<th class="importCountsCol">Update / New / Skip</th>
<th class="importDateCol">Imported</th>
</tr>
</thead>
<tbody>
<tr ng-show="loading && locations && locations.length == 0">
<td colspan="3">
<br />
<br />
<img class="spinner" src="content/images/ajax-loader.gif" alt="Loading..." />
</td>
</tr>
<tr ng-hide="true">
<td>
<!-- trick angular into making the next row white -->
</td>
</tr>
<tr ng-repeat=" location in locations" ng-class="{selected: location.code == selectedLocation.code}" ng-show="locations && locations.length > 0" ng-click="viewImports(location)">
<td class="importNameCol">{{location.name}} - {{location.city}}, {{location.state}}</td>
<td class="importCountsCol">{{location.updated}} / {{location.inserted}} / {{location.skipped}}</td>
<td class="importDateCol">{{location.timeStampUtc | date:'MM/dd/yyyy'}}</td>
</tr>
<tr ng-hide="loading || (locations && locations.length > 0)">
<td colspan="3" class="text-center">No Imports Found.</td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<div class="col-md-12 paginationRow">
<pagination total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" max-size="5" ng-show="totalItems > itemsPerPage || true" direction-links="false" boundary-links="false" rotate="false" ng-change="refresh()" class="pagination-sm pull-right"></pagination>
</div>
</div>
</div>
</div>
<div class="col-md-7">
<div class="table importViewCol" ng-show="selectedLocation != null || importing">
<div class="row headerRow titleBar">
<div class="col-md-9">
<i class="icon-users"></i><span ng-show="importing">New</span><span ng-hide="importing">View</span> Import
</div>
<div class="col-md-3 text-right" ng-click="closeView()"><i class="icon-close"></i>
</div>
</div>
<div class="editWorkOrder" style="padding-bottom: 0; border: 0;">
<div class="tabBox">
<div class="tabStrip">
<div class="tab" ng-show="importing" ui-sref-opts="{reload: true}" ui-sref-active="thisTab">
<a ui-sref="importUsers.file">File</a>
</div>
<div class="tab" ui-sref-opts="{reload: true}" ui-sref-active="thisTab" ng-disabled="importing">
<a ui-sref-if="!importing" ui-sref-val="importUsers.inserted">Inserted</a>
</div>
<div class="tab" ui-sref-opts="{reload: true}" ui-sref-active="thisTab" ng-disabled="importing">
<a ui-sref-if="!importing" ui-sref="importUsers.insertError">Inserted with Errors</a>
</div>
<div class="tab" ui-sref-opts="{reload: true}" ui-sref-active="thisTab" ng-disabled="importing">
<a ui-sref-if="!importing" ui-sref="importUsers.updated">Updated</a>
</div>
<div class="tab" ui-sref-opts="{reload: true}" ui-sref-active="thisTab" ng-disabled="importing">
<a ui-sref-if="!importing" ui-sref="importUsers.skipped">Skipped</a>
</div>
</div>
</div>
</div>
<div class="importUsersDisplay" ui-view></div>
</div>
</div>
</div>
</div>
Because we use so many service calls I haven't tried to get this working in Plunker. It's not a show stopper since the page behaves as expected. It is an annoyance that I'd like to understand and eliminate. Also, my QA folks can then stop complaining to me about it :)
Thanks, Mike

Resources