modalinstance inject view model to update - javascript

I am using Modal popups to list out accounts details (accno and name). once row is selected from list view model variable(vm.vismaDebitAccount) need to update which is dynamic. In actual scenario popup will be open on textbox onclick and once row is selected from popup relevant textbox text should be update with account name. The view model variable(a particular textbox binding) should be able to inject to modalinstance result without hard cord things.
Here is my code.
my problem is why vm.vismaDebitAccount is not getting update? Please help me.
Here is the place on UI binding
<tr ng-repeat="accEntry in vm.vismaAccEntries">
<td>{{accEntry.invoiceNo}}</td>
<td><input type="text" ng-model='accEntry.debitAccNo' required name="field" ng-click="vm.openVismaAccModal('debit')" /></td>
<td><input type="text" ng-model='accEntry.debitVat' required name="field" /></td>
<td><input type="text" ng-model='accEntry.creditAccNo' required name="field" ng-click="vm.openVismaAccModal('credit')"/></td>
<td><input type="text" ng-model='accEntry.creditVat' required name="field" /></td>
<td>{{accEntry.amount}}</td>
<td>{{accEntry.voucherDate}}</td>
<td>{{accEntry.dueDate}}</td>
app.controller('invoiceCodeController', ['$routeParams', 'invoiceService', 'vismaService', '$uibModal', '$log', function ($routeParams, invoiceService, vismaService, $uibModal, $log) {
var vm = this;
var vismaDebitAccount = {
catogory: '',
account: ''
}
var vismaCreditAccount = {
catogory: '',
account: ''
}
vm.openVismaAccModal = function (accountType) {
console.log('hi before')
var modalInstance = $uibModal.open({
templateUrl: 'accountPopup.html',
controller: 'vismaAccController as vm'
});
modalInstance.result.then(function (selectedAccount) {
if (accountType === 'debit') {
vm.vismaAccEntries[0].debitAccNo = selectedAccount.account.No;
}
if (accountType === 'credit') {
vm.vismaAccEntries[0].creditAccNo = selectedAccount.account.No;
}
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
}
}]);
app.controller('vismaAccController', ['vismaService', '$uibModalInstance', function (vismaService, $uibModalInstance) {
var vm = this;
var selectedAcc = {
category: '',
account: ''
};
Init();
function Init() {
getVismaAccData();
}
vm.tabChange = function (e) {
if (e.target.nodeName === 'A') {
e.preventDefault();
}
}
vm.rowSelect = function (index, debitAcc, flag) {
selectedAcc.category = flag;
selectedAcc.account = debitAcc;
}
vm.ok = function () {
$uibModalInstance.close(selectedAcc);
};
vm.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
function getVismaAccData() {
var errors = [];
vismaService.getSuppliers().then(function (data) {
vm.vismaSuppliers = data;
},
function (errorMsg) {
errors.push('<li>' + errorMsg + '</li>');
vm.savedSuccessfully = false;
});
vismaService.getCustomers()
.then(function (data) {
vm.vismaCustomers = data;
},
function (errorMsg) {
errors.push('<li>' + errorMsg + '</li>');
vm.savedSuccessfully = false;
});
vismaService.getGeneralLedger()
.then(function (data) {
vm.vismaGL = data;
},
function (errorMsg) {
errors.push('<li>' + errorMsg + '</li>');
vm.savedSuccessfully = false;
});
if (errors.length > 0) {
vm.message = errors.join(' ');
}
}
}]);

Related

Changed email address will not be forwarded from one to the other in AngularJS

I have a form, where an email address is "saved":
It derives from the following code:
'use strict';
angular.module('app').factory('Emails', function ($window)
{
var DEFAULT = 'change-it#something.com';
var data = $window.eval($window.localStorage.getItem('emailaddress')) || DEFAULT;
var Emails = {};
Emails.get = function ()
{
return data;
};
Emails.set = function (emailaddress)
{
data = emailaddress;
$window.localStorage.setItem('emailaddress', $window.JSON.stringify(data));
};
return Emails;
});
When clicking on the button for the email address a new form opens:
The code for this popup (email-popup.html) is the following:
<p>Email-Adresse eingeben</p>
<form name="emailForm">
<div class="rules__popup">
<input type="email" name="input" ng-model="emailaddress" min="1" maxlength="30"
ng-change="updateEmail" required ng-keypress="positiveInteger($event)" ng-controller="PdfsmtpCtrl">
</div>
</form>
But when changing the email address herein and clicking the "OK-button" on top right, nothing happens. The email address remains the same!
To be complete, here is the code, where all starts and ends:
use strict';
angular.module('app')
.controller('PdfsmtpCtrl', function ($scope, Pdfsmtp, Emails, $ionicPopup, $window)
{
$scope.emailaddress = Emails.get();
$scope.changeEmail = function (emailaddress)
{
//var regex = /^[_a-z0-9]+(\.[_a-z0-9]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/;
var regex = /^(([^<>()\[\]\.,;:\s#\"]+(\.[^<>()\[\]\.,;:\s#\"]+)*)|(\".+\"))#(([^<>()[\]\.,;:\s#\"]+\.)+[^<>()[\]\.,;:\s#\"]{2,})$/i;
var popupScope = $scope.$new();
popupScope.emailForm
{
name: $scope.emailaddress
};
$ionicPopup.prompt
({
cssClass: 'rules__popup',
templateUrl: 'pdfsmtp/email-popup.html',
scope: $scope,
buttons:
[
{
text: 'OK',
type: 'button-balanced',
onTap: function (e)
{
//if (isNaN($scope.emails[email]))
if ($scope.emailaddress === undefined && isNaN($scope.emailaddress))
{
$scope.$emit('toast', 'Keine gültige Email-Adresse!');
e.preventDefault();
$scope.emailaddress = "change-it#something.com";
}
else if (!$scope.emailaddress.match(regex))
{
$scope.$emit('toast', 'Keine gültige Email-Adresse!');
e.preventDefault();
$scope.emailaddress = "change-it#something.com";
}
}
}
]
}).then(function ()
{
if ($window.cordova && $window.cordova.plugins.Keyboard)
{
$window.cordova.plugins.Keyboard.close();
}
});
};
$scope.save = function ()
{
Emails.set($scope.emailaddress);
$scope.emailsModal.hide();
};
What is going wrong here?

Updating ng-show value after Promise returns

I have a problem where I'm trying to ng-show a view using ng-view when the user is logged in. By default the value vm.isLoggedIn is false when the controller initializes and vm.isLoggedIn gets set to true when they are logged in.
But this doesn't update the UI to reflect the changes, the ng-show will still have class="ng-hide", which is put there by AngularJS when you decalred it with ng-show.
How do I get the UI to reflect the changes when vm.isLoggedIn is updated to true on a return of a promise?
Here is the HTML:
<div id="loggedInContainer" ng-show="vm.isLoggedIn">
<div ng-view></div>
</div>
This is my controller where everything is being set:
(function () {
"use strict";
var app = angular.module("productManagement");
var MainCtrl = function ($scope, $timeout, userAccount) {
var vm = this;
vm.isLoggedIn = false;
vm.message = "";
vm.userData = {
userName: "",
email: "",
password: "",
confirmPassword: ""
};
var applyChanges = function () {
$timeout(function () {
$scope.$apply();
});
}
vm.registerUser = function () {
vm.userData.confirmPassword = vm.userData.password;
vm.userData.userName = vm.userData.email;
userAccount.registration.registerUser(vm.userData, function (data) {
vm.confirmPassword = "";
vm.message = "Registration Successful";
vm.login();
}, function (errorResponse) {
vm.isLoggedIn = false;
vm.message = errorResponse.statusText + "\r\n";
if (errorResponse.data.exceptionMessage) {
vm.message += errorResponse.data.exceptionMessage;
}
// Validation Errors
if (errorResponse.data.modelState) {
for (var key in errorResponse.data.modelState) {
vm.message += errorResponse.data.modelState[key] + "\r\n";
}
}
});
}
vm.login = function () {
vm.userData.grant_type = "password";
vm.userData.userName = vm.userData.email;
userAccount.login.loginUser(vm.userData, function (data) {
vm.isLoggedIn = true; // This is where vm.isLoggedIn is set to true
vm.message = "";
vm.password = "";
vm.token = data.access_token;
//$("#loggedInContainer").removeClass("ng-hide"); // Hack used to manually remove the class
}, function (errorResponse) {
vm.password = "";
vm.isLoggedIn = false;
vm.message = errorResponse.statusText + "\r\n";
if (errorResponse.data.exceptionMessage) {
vm.message += errorResponse.data.exceptionMessage;
}
if (errorResponse.data.error) {
vm.message += errorResponse.data.error;
}
});
}
}
app.controller("MainCtrl", ["$scope", "$timeout", "userAccount", MainCtrl]);
})();
This is the service I'm using to Login the user, which uses $resource
(function () {
"use strict";
var app = angular.module("common.services");
var userAccount = function ($resource, $http, appSettings) {
return {
registration: $resource(appSettings.serverPath + "/api/Account/Register", null,
{
"registerUser": { method: "POST" }
}),
login: $resource(appSettings.serverPath + "/Token", null,
{
"loginUser": {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
transformRequest: function (data, headersGetter) {
var str = [];
for (var d in data) {
str.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
}
return str.join("&");
}
}
})
}
}
app.factory("userAccount", ["$resource", "$http", "appSettings", userAccount]);
})();
I've tried to manually use $scope.$apply(), $scope.$digest(), even $timeout(), but none of them are working properly. I either get a $digest is already running error or nothing happens at all.
The only work around I can use is to manually remove the class on the div using jQuery, but that's not the correct way to do it using AngualrJS.

Angular - getting value from directive in the controller

I need to pass a selected value from a directive that I am using in several places. It is a select input field that I need to get a selected value from.
This is how the directive looks like:
angular.module('quiz.directives')
.directive('fancySelect', function($rootScope, $timeout) {
return {
restrict: 'E',
templateUrl: 'templates/directives/fancySelect.html',
scope: {
title: '#',
model: '=',
options: '=',
multiple: '=',
enable: '=',
onChange: '&',
class: '#'
},
link: function(scope) {
scope.showOptions = false;
scope.displayValues = [];
scope.$watch('enable', function(enable) {
if (!enable && scope.showOptions) {
scope.toggleShowOptions(false);
}
});
scope.toggleShowOptions = function(show) {
if (!scope.enable) {
return;
}
if (show === undefined) {
show = !scope.showOptions;
}
if (show) {
$rootScope.$broadcast('fancySelect:hideAll');
}
$timeout(function() {
scope.showOptions = show;
});
};
scope.toggleValue = function(value) {
if (!value) {
return;
}
if (!scope.multiple) {
scope.model = value;
console.log(scope.model);
return;
}
var index = scope.model.indexOf(value);
if (index >= 0) {
scope.model.splice(index, 1);
}
else {
scope.model.push(value);
}
if (scope.onChange) {
scope.onChange();
}
};
scope.getDisplayValues = function() {
if (!scope.options || !scope.model) {
return [];
}
if (!scope.multiple && scope.model) {
return scope.options.filter(function(opt) {
return opt.id == scope.model;
});
}
return scope.options.filter(function(opt) {
return scope.model.indexOf(opt.id) >= 0;
});
};
$rootScope.$on('fancySelect:hideAll', function() {
scope.showOptions = false;
});
}
};
});
When I do console.log(scope.model); I get the selected value, but I am not sure how to get it and use it in my controller?
This is the controller:
angular.module('quiz.controllers')
.controller('ProfileController', function(
$scope,
$state,
$stateParams,
UserService,
$auth,
MessageService,
$ionicLoading,
AppSettings,
$timeout,
AvatarService,
PushService,
$http
) {
$scope.user = UserService.get();
$scope.profilePromise = {};
if ($scope.user.player.avatar == ""){
$scope.user.player.avatar = AvatarService.getRandom();
}
$http.get(AppSettings.apiUrl + '/years')
.then(function(result) {
$scope.years = result.data;
});
$scope.updateUser = function(form) {
if (!form.$valid) {
var message = "Ugyldig data i skjema. Sjekk felter markert med rødt.";
MessageService.alertMessage(message);
return;
}
saveUser($scope.user);
};
$scope.getNextAvatar = function() {
$scope.user.player.avatar = AvatarService.getNext($scope.user.player.avatar);
};
$scope.getPreviousAvatar = function() {
$scope.user.player.avatar = AvatarService.getPrevious($scope.user.player.avatar);
};
var saveUser = function(user) {
$scope.profilePromise = UserService.save(user);
$scope.profilePromise.then(function(result) {
$scope.user = result.data.user;
PushService.init();
PushService.getDeviceId().then(function(id) {
UserService.addDevice(id);
});
if ($stateParams.register) {
$state.go('main.front');
}
}, function(error) {
var message = "Kunne ikke lagre bruker. Melding fra server: " + error.data.message;
MessageService.alertMessage(message);
});
};
});
You already have an onChange binding in the scope, so why don't you use that one?
In your directive:
if (scope.onChange) {
scope.onChange({ $value: scope.model });
}
Then pass a controller function to your directive:
<fancy-select on-change="onChange($value)"></fancy-select>
In your controller:
$scope.onChange = function(val) {
// do something with the value
}

Argument '*' is not a function on AngularJS

Adding ng-controller on view causing Error: [ng:areq] Argument 'ValidationCtrl' is not a function, got undefined. Following are the code snippets:
profile.html
<div class="row" ng-controller="ValidationCtrl">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">First Name</label>
<input type="text" placeholder="Enter your first name" class="form-control" name="firstname" ng-model="user.first_name">
<span class="error text-small block" ng-if="Form.first_name.$dirty && Form.first_name.$invalid">Last Name is required</span>
<span class="success text-small" ng-if="Form.first_name.$valid">Wonderful!</span>
</div>
</div>
</div>
app.js
var myApp = angular.module("MyApp",['ngResource','ngRoute','ui.router','ngMessages','ngResource','cfp.loadingBar','duScroll','ngAnimate','satellizer','pascalprecht.translate','ngCookies','oc.lazyLoad','ui.bootstrap','toastr'])
.config(['$stateProvider', '$urlRouterProvider','$authProvider','$ocLazyLoadProvider','JS_REQUIRES',function($stateProvider, $urlRouterProvider,$authProvider,$ocLazyLoadProvider,jsRequires){
$stateProvider
.state('app.profile', {
url: '/profile',
templateUrl: "views/profile.html",
title: 'Buttons',
resolve: loadSequence('flow','validationCtrl')
});
$ocLazyLoadProvider.config({
debug: false,
events: true,
modules: jsRequires.modules
});
function loadSequence() {
var _args = arguments;
return {
deps: ['$ocLazyLoad', '$q',
function ($ocLL, $q) {
var promise = $q.when(1);
for (var i = 0, len = _args.length; i < len; i++) {
promise = promiseThen(_args[i]);
}
return promise;
function promiseThen(_arg) {
if (typeof _arg == 'function')
return promise.then(_arg);
else
return promise.then(function () {
var nowLoad = requiredData(_arg);
if (!nowLoad)
return $.error('Route resolve: Bad resource name [' + _arg + ']');
return $ocLL.load(nowLoad);
});
}
function requiredData(name) {
if (jsRequires.modules)
for (var m in jsRequires.modules)
if (jsRequires.modules[m].name && jsRequires.modules[m].name === name)
return jsRequires.modules[m];
return jsRequires.scripts && jsRequires.scripts[name];
}
}]
};
}
}]);
validationCtrl.js
'use strict';
/**
* controller for Validation Form example
*/
myApp.controller('ValidationCtrl', ["$scope", "$state", "$timeout", "SweetAlert", function ($scope, $state, $timeout, SweetAlert) {
alert('validation');
$scope.master = $scope.myModel;
$scope.form = {
submit: function (form) {
var firstError = null;
if (form.$invalid) {
var field = null, firstError = null;
for (field in form) {
if (field[0] != '$') {
if (firstError === null && !form[field].$valid) {
firstError = form[field].$name;
}
if (form[field].$pristine) {
form[field].$dirty = true;
}
}
}
angular.element('.ng-invalid[name=' + firstError + ']').focus();
SweetAlert.swal("The form cannot be submitted because it contains validation errors!", "Errors are marked with a red, dashed border!", "error");
return;
} else {
SweetAlert.swal("Good job!", "Your form is ready to be submitted!", "success");
//your code for submit
}
},
reset: function (form) {
$scope.myModel = angular.copy($scope.master);
form.$setPristine(true);
}
};
}]);
and my config.constant.js
myApp.constant('JS_REQUIRES', {
scripts: {
'validationCtrl': ['controllers/validationCtrl.js']
}});
Thanks!

Having issue with angular filter in order to search through list

I am using angular filter in order to search through the list. Searching using filter is working fine but issue is along with i also have a check box('Select All') this check box is also perfoming its action fine but when i search through the list and if i get only two element out of six and then i check my 'Select box' the other four elements in rows also get checked . I want to avoid this situation . My code is below:
Html
<select-all-checkbox checkboxes="editResource.allowedUsersList" all-selected="allSelectedWtUsers" all-clear="noSelectedWtUsers" multiple="multipleWtUsers" ids="selectedWUsersIds"></select-all-checkbox>
<input type='text' ng-model="name" placeholder="search"/>
<div class="col-sm-12" ng-repeat="allowedUser in editResource.allowedUsersList | filter:{firstName:name}"></div>
Directive:
This directive is used to select checkboxes.
directive('selectAllCheckbox', function () {
return {
replace: true,
restrict: 'E',
scope: {
checkboxes: '=',
allselected: '=allSelected',
allclear: '=allClear',
multiple: '=multiple',
ids: '=ids'
},
template: '<input type="checkbox" class="input-checkbox" ng-model="master" ng-change="masterChange()">',
controller: function ($scope, $element) {
$scope.masterChange = function () {
if ($scope.master) {
angular.forEach($scope.checkboxes, function (cb, index) {
cb.isSelected = true;
});
} else {
angular.forEach($scope.checkboxes, function (cb, index) {
cb.isSelected = false;
});
}
};
$scope.$watch('checkboxes', function (newVal,oldVal) {
if(newVal !== oldVal){
var allSet = true,allClear = true,countSelected = 0;
$scope.ids = [];
angular.forEach($scope.checkboxes, function (cb, index) {
if(cb.isSelected){
countSelected ++;
$scope.ids.push(cb.id);
}
if (cb.isSelected) {
allClear = false;
} else {
allSet = false;
}
});
if(countSelected > 1){
$scope.multiple = true
}else{
$scope.multiple = false
}
if ($scope.allselected !== undefined) {
$scope.allselected = allSet;
}
if ($scope.allclear !== undefined) {
$scope.allclear = allClear;
}
$element.prop('indeterminate', false);
if (allSet) {
$scope.master = true;
} else if (allClear) {
$scope.master = false;
} else {
$scope.master = false;
$element.prop('indeterminate', true);
}
}
}, true);
}
};
});
Basically I want if i search my list of items and my item list length is 20 and i am getting 4 items using filter then my list should be of size 4 and if i clear my search box then my item list should again becomes of size 20.
Most important point is if i getting 4 items after pressing some keys into search box and if i delete 1 item and again clear my search box then i should get 19 items of my list.
Hope you understand my issue. Can anyone help me out.
I would do it with a controller (filtering the list in the controller):
http://codepen.io/jlowcs/pen/YPvvMX
HTML:
<div ng-controller="exampleCtrl">
<label><select-all-checkbox checkboxes="filteredList" all-selected="allSelectedWtUsers" all-clear="noSelectedWtUsers" multiple="multipleWtUsers" ids="selectedWUsersIds"></select-all-checkbox>select all</label>
<br>
<input type='text' ng-model="name" placeholder="search"/>
<br>
Filtered:
<div class="col-sm-12" ng-repeat="allowedUser in filteredList">
<input type="checkbox" ng-model="allowedUser.isSelected"> {{allowedUser.firstName}} {{allowedUser.lastName}}
</div>
<br>
All:
<div class="col-sm-12" ng-repeat="allowedUser in editResource.allowedUsersList">
<input type="checkbox" ng-model="allowedUser.isSelected"> {{allowedUser.firstName}} {{allowedUser.lastName}}
</div>
</div>
JS :
angular.module('exampleApp', [])
.controller('exampleCtrl', function ($scope) {
$scope.editResource = {
allowedUsersList: [
{firstName: 'Joe', lastName: 'Smith', isSelected: false},
{firstName: 'John', lastName: 'Parker', isSelected: false},
{firstName: 'Jim', lastName: 'Smith', isSelected: false}
]
};
$scope.$watch('name', function () {
$scope.filteredList = $scope.$eval('editResource.allowedUsersList | filter:{firstName:name}');
})
})
.directive('selectAllCheckbox', function () {
return {
replace: true,
restrict: 'E',
scope: {
checkboxes: '=',
allselected: '=allSelected',
allclear: '=allClear',
multiple: '=multiple',
ids: '=ids'
},
template: '<input type="checkbox" class="input-checkbox" ng-model="master" ng-change="masterChange()">',
controller: function ($scope, $element) {
$scope.masterChange = function () {
if ($scope.master) {
angular.forEach($scope.checkboxes, function (cb, index) {
cb.isSelected = true;
});
} else {
angular.forEach($scope.checkboxes, function (cb, index) {
cb.isSelected = false;
});
}
};
$scope.$watchCollection('checkboxes', function (newVal,oldVal) {
if(newVal !== oldVal){
var allSet = true,allClear = true,countSelected = 0;
$scope.ids = [];
angular.forEach($scope.checkboxes, function (cb, index) {
if(cb.isSelected){
countSelected ++;
$scope.ids.push(cb.id);
}
if (cb.isSelected) {
allClear = false;
} else {
allSet = false;
}
});
if(countSelected > 1){
$scope.multiple = true
}else{
$scope.multiple = false
}
if ($scope.allselected !== undefined) {
$scope.allselected = allSet;
}
if ($scope.allclear !== undefined) {
$scope.allclear = allClear;
}
$element.prop('indeterminate', false);
if (allSet) {
$scope.master = true;
} else if (allClear) {
$scope.master = false;
} else {
$scope.master = false;
$element.prop('indeterminate', true);
}
}
}, true);
}
};
});
angular.bootstrap(document, ['exampleApp']);

Categories