AngularJS - Get Checkbox Value? - javascript

I'm trying to add a function in my JS for a basic ToDo app that I'm working on using Angular Material and I need to know how I can get it to read the value/property of an md-checkbox (whether or not it is ticked).
The reason for this is I'm trying to make an alert appear informing the user that they need to select at least one checkbox if none are currently selected and they click on the Delete button at the bottom.
Anyone know how I could do this?
Codepen: http://codepen.io/anon/pen/QpdpEa.
JS:
var app = angular.module('todoApp', ['ngMaterial']);
function menuController ($scope, $mdDialog) {
var originatorEv;
this.openMenu = function($mdOpenMenu, ev) {
originatorEv = ev;
$mdOpenMenu(ev);
};
};
app.controller('todoController', function($scope, $mdDialog, $mdToast) {
$scope.sortBy = '-addedOn';
$scope.taskList = [
{ name: 'Task 1', completed: false, addedOn: 1488722128000 },
{ name: 'Task 2', completed: false, addedOn: 1488722128000 },
];
$scope.addTask = function() {
if (angular.isUndefined($scope.taskName) || $scope.taskName.length === 0) {
var alert = $mdDialog.alert()
.parent(angular.element(document.querySelector('#popupContainer')))
.clickOutsideToClose(true)
.title('Error')
.textContent('You must enter a task name')
.ok('Close');
$mdDialog.show( alert )
.finally(function() {
alert = undefined;
});
}
else {
$scope.taskList.push({name: $scope.taskName, addedOn: Date.now()});
$scope.taskName = "";
var pinTo = $scope.getToastPosition();
$mdToast.show (
$mdToast.simple()
.textContent('Task Added')
.position(pinTo)
.hideDelay(3000)
)
}
};
$scope.selectAll = function() {
angular.forEach($scope.taskList, function(task) {
task.completed = true;
});
};
$scope.selectNone = function() {
angular.forEach($scope.taskList, function(task) {
task.completed = false;
});
};
$scope.delete = function(ev) {
var confirm = $mdDialog.confirm()
.title ('Are you sure you want to delete the selected tasks?')
.textContent ('Deleted tasks can\'t be recovered.')
.targetEvent (ev)
.ok ('Confirm')
.cancel ('Cancel')
clickOutsideToClose: false;
$mdDialog.show(confirm).then(function() {
var pinTo = $scope.getToastPosition();
$mdToast.show (
$mdToast.simple()
.textContent('Tasks Deleted')
.position(pinTo)
.hideDelay(3000)
)
$scope.status = 'Tasks Deleted';
var i = $scope.taskList.length;
while (i--) {
var task = $scope.taskList[i];
if(task.completed) {
$scope.taskList.splice(i, 1);
}
}
},
function() {
$scope.status = 'Deletion Cancelled';
});
};
function DialogController($scope, $mdDialog) {
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.answer = function(answer) {
$mdDialog.hide(answer);
};
};
var last = {
bottom: false,
top: true,
left: false,
right: true
};
$scope.toastPosition = angular.extend({},last);
$scope.getToastPosition = function() {
sanitizePosition();
return Object.keys($scope.toastPosition)
.filter(function(pos) { return $scope.toastPosition[pos]; })
.join(' ');
};
function sanitizePosition() {
var current = $scope.toastPosition;
if ( current.bottom && last.top ) current.top = false;
if ( current.top && last.bottom ) current.bottom = false;
if ( current.right && last.left ) current.left = false;
if ( current.left && last.right ) current.right = false;
last = angular.extend({},current);
};
});
app.controller('toastController', function($scope, $mdToast) {
$scope.closeToast = function() {
$mdToast.hide();
}
});
HTML:
<md-card-actions layout="row" class="md-padding">
<md-button ng-click="selectAll()" class="md-raised md-primary">Select All</md-button>
<md-button ng-click="selectNone()" class="md-raised md-primary">Select None</md-button>
<md-button ng-click="delete()" class="md-raised md-warn md-hue-2">Delete</md-button>
</md-card-actions>

You can just iterate over the taskList variable and check if at least one element has property completed with true value.
I've added a custom function, binded to the Show button. If you click on it, you will see in the console true if there's at least one checkbox checked or false if none of the checkboxes is checked.
$scope.show = function(){
console.log($scope.taskList.some(v => v.completed))
}
http://codepen.io/anon/pen/BWpWmw?editors=1010

I've made changes to your code that you can see & run here: http://codepen.io/anon/pen/jBymPd?editors=1010
I'm using the $filter service to get the task(s) that have completed member set to true.
If nothing has been checked, then you can show an alert to at-least select one task to delete. If one or more task is checked, then you just delete them.
The new changes in your code are shown below:
app.controller('todoController', function($scope, $mdDialog, $mdToast, $filter) {
$scope.delete = function(ev) {
var completedTasks = $filter('filter')($scope.taskList, { completed: true}, true);
console.log(completedTasks); // array of completed tasks, can be empty.
if (completedTasks.length > 0) {
console.log('show dialog box to confirm');
// your existing code.
var confirm = $mdDialog.confirm()
.title ('Are you sure you want to delete the selected tasks?')
.textContent ('Deleted tasks can\'t be recovered.')
.targetEvent (ev)
.ok ('Confirm')
.cancel ('Cancel')
clickOutsideToClose: false;
$mdDialog.show(confirm).then(function() {
var pinTo = $scope.getToastPosition();
$mdToast.show (
$mdToast.simple()
.textContent('Tasks Deleted')
.position(pinTo)
.hideDelay(3000)
)
$scope.status = 'Tasks Deleted';
var i = $scope.taskList.length;
while (i--) {
var task = $scope.taskList[i];
if(task.completed) {
$scope.taskList.splice(i, 1);
}
}
},
function() {
$scope.status = 'Deletion Cancelled';
});
} else {
alert('please select at-least one task to delete');
console.log('show alert to check at-least one task');
}
};
});

Related

While uncheck the checkbox needs to reload the search item

I'm having the search column with checkbox along with folder names. when I click the checkbox of corresponding folder, it will show their items. As well as when I click on multiple checkbox it will show their corresponding items. But when I uncheck the folder, the corresponding items doesn't remove. So I need the hard reload or refresh when I check or uncheck the checkbox or need to clear the cache for every check or uncheck.
Here is my Code:
Checkbox: Core.component.Checkbox.extend({
click: function () {
var ret=null;
var nav = this.get("controller").get('selectedNavigator');
ret = this._super.apply(this, arguments);
var states=null;
Ember.run.schedule('sync', this, function () {
Ember.run.schedule('render', this, function () {
states = this.get('parentView.itemStates');
var values = Object.keys(states).filter(function (key) {
if(states[key]){
return states[key];}
else{return;}
});
if (values.length === 0) {
Core.Action('core:contentHome', {});
} else {
this.set('parentView.model.values',values);
nav.publish();
}
});
});
return ret;
}
}),
For the Publish:
publish: function () {
var currentResultSet = this.get('resultSet'),
ctl = this.get('controller'),
form = ctl.get('formModel'),
resultSet,
data = form.sleep(2000);
if (Object.keys(data).length === 0) {
Core.view.Menu.create({
anchor: $('*[data-class-name="Core.Tab.Content.Controller.NavigationRefresh"]'),
model: [
Core.model.Menu.Item.create({
label: "Please select something to search.",
icon: 'dialog_warning'
})
]
}).show();
return;
}
resultSet = form.send();
ctl.set('loadState', 'loading');
ctl.set('resultSet', Core.model.BlankResultSet.create({
loadState: 'loading',
tabContext: Ember.get(form, 'resultSet.tabContext')
}));
resultSet.fail(function (err) {
ctl.set('loadState', 'loaded');
console.log(currentResultSet);
ctl.set('resultSet', currentResultSet);
}).always(function () {
ctl.set('loadState', 'loaded');
});
},

Binding data after promise

I have a table that contains a button that activates/deactivates users. When I click that button it makes a API call to change the status of the user. What I am having trouble with is performing a live update with the view after the API call. Currently, the only way I see the text switch is when I refresh the page.
Here is my Admin.html where the text on the button should switch between 'Active' and 'Inactive' when the button is clicked.
<tr ng-repeat="account in $ctrl.account">
<td>{{account.FirstName}}</td>
<td>{{account.LastName}}</td>
<td class="text-center">
<button class="btn btn-sm btn-active-status" ng-class="account.Active === true ? 'btn-info' : 'btn-danger'" ng-bind="account.Active === true ? 'Active' : 'Inactive'" ng-click="$ctrl.UpdateActiveStatus(account.Id, account.Active)"></button>
</td>
</tr>
Here is my AdminController.js
app.component('admin', {
templateUrl: 'Content/app/components/admin/Admin.html',
controller: AdminController,
bindings: {
accounts: '='
}
})
function AdminController(AccountService) {
this.$onInit = function () {
this.account = this.accounts;
}
this.UpdateActiveStatus = function (id, status) {
var data = {
Id: id,
Active: !status
};
AccountService.UpdateActiveStatus(data).then(function (response) {
AccountService.GetAccounts().then(function (data) {
this.account = data;
});
});
};
}
Here is the fix to my problem. Please let me know if there is a better way than this.
function AdminController(AccountService) {
var controller = this;
this.$onInit = function () {
controller.account = this.accounts;
}
this.UpdateActiveStatus = function (id, status) {
var data = {
Id: id,
Active: !status
};
AccountService.UpdateActiveStatus(data).then(function (data) {
for (var i = 0; i < controller.account.length; i++) {
if (controller.account[i].Id === data.Id) {
controller.account[i].Active = data.Active;
}
}
});
};
}

ionic cordova encrypt base64 image

I have this app where I take picture with cordova camera then move it into file-system , save the imgpath for the image into sqlite db and display it, I'm trying to encrypt the imgPath for the image which is saved on ccordova.file.data directory , I tried cordova safe plugin https://github.com/disusered/cordova-safe ,
but I keep getting "Error with cryptographic operation".
Any help would be appreciated
var db = null;
angular.module('starter', ['ionic', 'ngCordova']) 
.run(function($ionicPlatform, $cordovaSQLite) {    
$ionicPlatform.ready(function() {      
try {        
db = $cordovaSQLite.openDB({          
name: "my.db",
          location: 'default'        
});        
$cordovaSQLite.execute(db,"CREATE TABLE IF NOT EXISTS imageTable " + "(id integer primary key, image text)");      
} catch (e) {        
alert(e);      
} finally {       }
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('ImageCtrl', function($scope, $rootScope, $state, $stateParams, $cordovaDevice, $cordovaFile, $ionicActionSheet, $cordovaCamera, $cordovaFile, $cordovaDevice, $ionicPopup, $cordovaActionSheet, $cordovaSQLite, $interval) {
var imagesP = [];
//$scope.images = [];
$scope.showAlert = function(title, msg) {
var alertPopup = $ionicPopup.alert({
title: title,
template: msg
});
};
$scope.loadImage = function() {
var options = {
title: 'Select Receipts Image ',
buttonLabels: ['Gallery', 'Take photo', 'File System'],
addCancelButtonWithLabel: 'Cancel',
androidEnableCancelButton: true,
};
$cordovaActionSheet.show(options).then(function(btnIndex) {
var type = null;
if (btnIndex === 1) {
type = Camera.PictureSourceType.PHOTOLIBRARY;
} else if (btnIndex === 2) {
type = Camera.PictureSourceType.CAMERA;
}
if (type !== null) {
$scope.selectPicture(type);
}
});
}
// Take image with the camera or from library and store it inside the app folder
// Image will not be saved to users Library.
$scope.selectPicture = function(sourceType) {
var options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: sourceType,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
correctOrientation: true,
targetWidth: 800,
targetHeight: 800,
popoverOptions: CameraPopoverOptions, // for IOS and IPAD
saveToPhotoAlbum: false
};
$cordovaCamera.getPicture(options).then(function(imagePath) {
// Grab the file name of the photo in the temporary directory
var currentName = imagePath.replace(/^.*[\\\/]/, '');
// alert(currentName);
//Create a new name for the photo to avoid duplication
var d = new Date(),
n = d.getTime(),
newFileName = n + ".jpg";
//alert(newFileName);
// If you are trying to load image from the gallery on Android we need special treatment!
if ($cordovaDevice.getPlatform() == 'Android' && sourceType === Camera.PictureSourceType.PHOTOLIBRARY) {
window.FilePath.resolveNativePath(imagePath, function(entry) {
window.resolveLocalFileSystemURL(entry, success, fail);
function fail(e) {
console.error('Error: ', e);
}
function success(fileEntry) {
var namePath = fileEntry.nativeURL.substr(0, fileEntry.nativeURL.lastIndexOf('/') + 1);
// Only copy because of access rights
$cordovaFile.copyFile(namePath, fileEntry.name, cordova.file.dataDirectory, newFileName).then(function(success) {
// $scope.image = newFileName;
var imgPath = cordova.file.dataDirectory + newFileName;
$scope.add(imgPath);
$scope.encryptFile(imgPath);
}, function(error) {
$scope.showAlert('Error', error.exception);
});
// alert( fileEntry.nativeURL);
};
});
} else {
var namePath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
// Move the file to permanent storage
$cordovaFile.moveFile(namePath, currentName, cordova.file.dataDirectory, newFileName).then(function(success) {
// $scope.image = newFileName;
//$scope.images.push(newFileName);
var imgPath = cordova.file.dataDirectory + newFileName;
$scope.add(imgPath);
}, function(error) {
$scope.showAlert('Error', error.exception);
});
}
},
function(err) {
// Not always an error, maybe cancel was pressed...
})
};
$scope.add = function(path) {             
if (imagesP != null) {          
$cordovaSQLite.execute(db, "INSERT INTO imageTable (images) VALUES(?)", [path] );        
}        
alert("Inserted.");      
},
function(e) {        
alert(e);      
};
$scope.encryptFile = function(file){
var safe = cordova.plugins.disusered.safe,
key = 'someKeyABC';
function success(encryptedFile) {
console.log('Encrypted file: ' + encryptedFile);
}
function error() {
console.log('Error with cryptographic operation');
}
safe.encrypt(file, key, success, error);
}
  
$scope.ShowAllData = function() {     
$scope.images = [];      
$cordovaSQLite.execute(db,"SELECT images FROM imageTable").then(function(res) {          
if (res.rows.length > 0) {            
for (var i = 0; i < res.rows.length; i++) {              
$scope.images.push({                
id: res.rows.item(i).id,
image: res.rows.item(i).images
              
});            
}          
}        
},         function(error) {          
alert(error);        
}      );
 
} 
       

Delete items synchronously angularjs

I have to delete items in a for loop the moment I close a bootstrap modal.
Currently I am setting a delay of 3 secs on the modal close, so that the delete can happen within those 3secs in the background but this is not very efficient.
What is the best way to ensure that the modal closes only when all the items are deleted successfully? Perhaps by making the delete synchronous ? Or promises?
$scope.idList = [1, 2, 3];
$scope.deleteItems = function(deleteList){
angular.forEach( deleteList, function(item) {
DeleteAPI.remove({itemId: item}, {}, $scope.delSuccess, $scope.delError);
});
}
$scope.close = function(){
var pmodal = $modal.open( {
templateUrl: 'route/pmodal.html',
controller: 'DeleteCtrl'
} );
pmodal.result.then(
function(check) {},
function(check) {
if ( check=='proceed' ) {
$scope.deleteItems( $scope.idList );
$timeout( function() {
$modalInstance.dismiss('cancel');
}, 3000);
}
},
function(check) {}
);
}
You can use $q.all or you can simple count responses as Javascript is not multithread:
pmodal.result.then(
var success = 0;
var failed = 0;
var check = function() {
if (success + failed == deleteList.length) {
if (failed != 0) {
// do smth?
} else {
$modalInstance.dismiss('cancel');
}
}
}
angular.forEach( deleteList, function(item) {
DeleteAPI.remove({itemId: item}, {}, function() {
success++;
check();
}, function() {
failed++;
check();
});
});

display only the elements with checked = true

I have a list of items with the option to checked or unchecked.
<ion-item ng-repeat="sport in sports"
ng-click="toggleSportSelection(sport)">
{{:: sport.name}}
</ion-item>
if those items are unchecked you are unable to see them here
<div ng-show="sport.checked" ng-repeat="sport in sports">
{{sport.name}}
</div>
those items has been saved in a DB every time you unchecked them.
The reason why I am here, is because the default behavior of the items is checked = true so it doesn't matter if they are saved in a DB, if you refresh the page, all the items are set up to checked = true again.
So what can I do in order to avoid that behavior and that the app recognizes once the items are unchecked or checked ?
this is part of the controller
.controller('SportsController', function($scope, SportsFactory,
AuthFactory) {
SportsFactory.getSportChecked(customer).then(function(sportChecked) {
_.each(sports, function(sport) {
var intersectedSports = _.intersection(sport.id, sportChecked),
checkedSportObjects = _.filter(sport, function(sportObj) {
return _.includes(intersectedSports, sportObj);
});
_.each(checkedSportObjects, function(sport) {
$scope.sports.push(sport);
});
});
//here is the part where the default behavior is checked = true
if (sports.length) {
$scope.sports = _.map(sports, function(sport) {
sport.checked = true;
return sport;
});
}
$scope.toggleSportSelection = function(sport) {
var params = {};
params.user = $scope.customer.customer;
params.sport = sport.id;
sport.checked = !sport.checked;
SportsFactory.setSportChecked(params);
};
});
UPDATE
service.js
setSportChecked: function(params) {
var defer = $q.defer();
$http.post(CONSTANT_VARS.BACKEND_URL + '/sports/checked', params)
.success(function(sportChecked) {
LocalForageFactory.remove(CONSTANT_VARS.LOCALFORAGE_SPORTS_CHECKED, params);
defer.resolve(sportChecked);
})
.error(function(err) {
console.log(err);
defer.reject(err);
});
return defer.promise;
},
and the NODEJS part
sportChecked: function(params) {
var Promise = require('bluebird');
return new Promise(function(fullfill, reject) {
console.time('sportChecked_findOne');
SportSelection.findOne({
user: params.user
}).exec(function(err, sportChecked) {
console.timeEnd('sportChecked_findOne');
var newSport;
if (err) {
reject(new Error('Error finding user'));
console.error(err);
}else if (sportChecked) {
newSport = sportChecked.sport || [];
console.log(newSport);
console.time('sportChecked_update');
if (_.includes(sportChecked.sport, params.sport)) {
console.log('Sport already exists');
console.log(sportChecked.sport);
sportChecked.sport = _.pull(newSport, params.sport);
// sportChecked.sport = _.difference(newSport, params.sport);
console.log(sportChecked.sport);
}else {
newSport.push(params.sport);
sportChecked.sport = newSport;
}
SportSelection.update({
user: params.user
},
{
sport: newSport
}).exec(function(err, sportCheckedUpdated) {
console.timeEnd('sportChecked_update');
if (err) {
reject(new Error('Error on sportChecked'));
}else {
fullfill(sportCheckedUpdated);
}
});
if (sportChecked.sport) {
sportChecked.sport.push(params.sport);
console.log('New sport added');
}else {
sportChecked.sport = [params.sport];
}
}else {
console.time('sportChecked_create');
SportSelection.create({
sport: [params.sport],
user: params.user
}).exec(function(err, created) {
console.timeEnd('sportChecked_create');
if (err) {
reject(new Error('Error on sportChecked'));
}else {
fullfill(created);
}
});
}
});
});
},
I am using lodash so I will appreciate if you can assist me with that.
My issue itself is: it doesn't matter if the items are unchecked, once you refresh the page, all the items will be set up to checked = true again.
Someone says that I can use _.difference, but how ? or what can I do? I am here to read your suggestions.
Something like this?
.controller('SportsController', function($scope, SportsFactory) {
// get a list of all sports, with default value false
SportsFactory.getAllSports().then(function(sports){
$scope.sports = sports;
// set all items to unchecked
angular.each($scope.sports, function(sport) {
sport.checked = false;
});
// get a list of checked sports for customer
SportsFactory.getCheckedSports(customer).then(function(checkedSports)
{
// set the sports in your list as checked
angular.each(checkedSports, function(checkedSport){
var sport = _.findWhere($scope.sports, {id: checkedSport.id});
sport.checked = true;
});
});
$scope.toggleSportSelection = function(sport) {
// do your toggle magic here
};
});
In your view use a filter:
<div ng-repeat="sport in sports | filter:{checked:true}">
{{sport.name}}
</div>

Categories

Resources