I'm new to AngularJS and using UI Bootstrap in a project. I want to mark an I've read the T&Cs checkbox as checked once the modal (containing the T&Cs text) is closed (but not when the modal is dismissed).
I've adapted the general example at https://angular-ui.github.io/bootstrap/ but having issues updating the scope / view with the value of $scope.accept_terms.
I have the modal opening / closing fine, but the checkbox always remains unchecked.
HTML:
<form>
<div class="checkbox">
<input type="checkbox" id="user_details_termsConditions"
name="user_details[termsConditions]"
required="required" ng-checked="accept_terms" />
<label for="user_details_termsConditions" >I agree to the terms and conditions</label>
</div>
</form>
JS:
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($uibModal, $log, $document, $scope) {
var $ctrl = this;
$ctrl.animationsEnabled = true;
$ctrl.open = function (size, parentSelector) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector('.container ' + parentSelector)) : undefined;
var modalInstance = $uibModal.open({
animation: $ctrl.animationsEnabled,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
controllerAs: '$ctrl',
size: size,
appendTo: parentElem
});
modalInstance.result.then(function (result) {
$scope.accept_terms = result;
$log.info('accept_terms = ' + $scope.accept_terms);
// prints accept_terms = 1
}, function () {
});
};
});
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($uibModalInstance) {
var $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close(true);
};
});
Can anyone point me in the right direction?
Turns out this was a simple matter of using ng-model on the checkbox instead of ng-checked:
Controller:
modalInstance.result.then(function (result) {
$scope.accept_terms = true;
}, function () {
});
Markup:
<input type="checkbox" id="user_details_termsConditions"
name="user_details[termsConditions]" required="required"
ng-model="accept_terms" value="1" />
Related
I have this problem in my app, when I use slice to remove the user from the list. However, it does not remove from the list. I am getting the user with a API url call. But for some reason, it does not remove the user from the list. Please, have a look at my code. If, you guys want the full code, I have put it in my github. I hope we both can solve this. Thank you in advance.
Here is my code:
<div ng-controller="MyCtrl">
<div ng-repeat="person in userInfo.lawyers | filter : {id: lawyerId}">
<a class="back" href="#/lawyer">Back</a>
<button type="button" class="edit" ng-show="inactive" ng-click="inactive = !inactive">
Edit
</button>
<button type="submit" class="submit" ng-show="!inactive" ng-click="inactive = !inactive">Save</button>
<a class="delete" ng-click="confirmClick(); confirmedAction(person);" confirm-click>Confirm</a>
<div class="people-view">
<h2 class="name">{{person.firstName}}</h2>
<h2 class="name">{{person.lastName}}</h2>
<span class="title">{{person.email}}</span>
<span class="date">{{person.website}} </span>
</div>
<div class="list-view">
<form>
<fieldset ng-disabled="inactive">
<legend>Basic Info</legend>
<b>First Name:</b>
<input type="text" ng-model="person.firstName">
<br>
<b>Last Name:</b>
<input type="text" ng-model="person.lastName">
<br>
<b>Email:</b>
<input type="email" ng-model="person.email">
<br>
<b>Website:</b>
<input type="text" ng-model="person.website">
<br>
</fieldset>
</form>
</div>
</div>
</div>
App.js
var app = angular.module("Portal", ['ngRoute', 'ui.bootstrap' ]);
app.controller('MyCtrl', function($scope, $window) {
$scope.inactive = true;
$scope.confirmedAction = function (lawyer) {
$scope.$apply(function () {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
console.log($scope.userInfo.lawyers);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$window.location.href = '#/lawyer';
});
};
});
app.directive('confirmClick', ['$q', 'dialogModal', function($q, dialogModal) {
return {
link: function (scope, element, attrs) {
// ngClick won't wait for our modal confirmation window to resolve,
// so we will grab the other values in the ngClick attribute, which
// will continue after the modal resolves.
// modify the confirmClick() action so we don't perform it again
// looks for either confirmClick() or confirmClick('are you sure?')
var ngClick = attrs.ngClick.replace('confirmClick()', 'true')
.replace('confirmClick(', 'confirmClick(true,');
// setup a confirmation action on the scope
scope.confirmClick = function(msg) {
// if the msg was set to true, then return it (this is a workaround to make our dialog work)
if (msg===true) {
return true;
}
// msg can be passed directly to confirmClick('Are you sure you want to confirm?')
// in ng-click
// or through the confirm-click attribute on the
// <a confirm-click="Are you sure you want to confirm?"></a>
msg = msg || attrs.confirmClick || 'Are you sure you want to confirm?';
// open a dialog modal, and then continue ngClick actions if it's confirmed
dialogModal(msg).result.then(function() {
scope.$eval(ngClick);
});
// return false to stop the current ng-click flow and wait for our modal answer
return false;
};
}
}
}])
/*
Modal confirmation dialog window with the UI Bootstrap Modal service.
This is a basic modal that can display a message with yes or no buttons.
It returns a promise that is resolved or rejected based on yes/no clicks.
The following settings can be passed:
message the message to pass to the modal body
title (optional) title for modal window
okButton text for YES button. set false to not include button
cancelButton text for NO button. ste false to not include button
*/
.service('dialogModal', ['$modal', function($modal) {
return function (message, title, okButton, cancelButton) {
// setup default values for buttons
// if a button value is set to false, then that button won't be included
cancelButton = cancelButton===false ? false : (cancelButton || 'No');
okButton = okButton ===false ? false : (okButton || 'Yes');
// setup the Controller to watch the click
var ModalInstanceCtrl = function ($scope, $modalInstance, settings) {
// add settings to scope
angular.extend($scope, settings);
// yes button clicked
$scope.ok = function () {
// alert("Lawyer is confirmed");
$modalInstance.close(true);
};
// no button clicked
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
// open modal and return the instance (which will resolve the promise on ok/cancel clicks)
var modalInstance = $modal.open({
template: '<div class="dialog-modal"> \
<div class="modal-header" ng-show="modalTitle"> \
<h3 class="modal-title">{{modalTitle}}</h3> \
</div> \
<div class="modal-body">{{modalBody}}</div> \
<div class="modal-footer"> \
<button class="btn btn-primary" ng-click="ok()" ng-show="okButton">{{okButton}}</button> \
<button class="btn btn-warning" ng-click="cancel()" ng-show="cancelButton">{{cancelButton}}</button> \
</div> \
</div>',
controller: ModalInstanceCtrl,
resolve: {
settings: function() {
return {
modalTitle: title,
modalBody: message,
okButton: okButton,
cancelButton: cancelButton
};
}
}
});
// return the modal instance
return modalInstance;
}
}])
app.config(function ($routeProvider) {
$routeProvider
.when("/lawyer", {
controller: "HomeController",
templateUrl: "partials/home.html"
})
.when("/lawyer/:id", {
controller: "LawyerController",
templateUrl: "partials/about.html"
})
.otherwise({
redirectTo: '/lawyer'
});
});
But the element is getting deleted from list right?
If yes then, Try this :
$scope.confirmedAction = function (lawyer) {
$scope.$apply(function () {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
console.log($scope.userInfo.lawyers);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$window.location.href = '#/lawyer';
});
});
Or
$scope.confirmedAction = function (lawyer) {
$timeout(function () {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
console.log($scope.userInfo.lawyers);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$state.go($state.current, {}, {reload: true});
// $window.location.href = '#/lawyer';
},1100);
});
The problem is that you don't get the index from IndexOf when you using it on an array of objects like you do. Read more about the IndexOf here.
Instead, use map and then use IndexOf on that
Try it like this:
$scope.confirmedAction = function (lawyer) {
var index = $scope.userInfo.lawyers.map(function(e) { return e.id; }).indexOf(lawyer.id);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$window.location.href = '#/lawyer';
};
And also, the controller changes will by default be detected by the digest loop of angular so no need to use $scope.$apply.
Also, simplifyed your plunker with the basic get array list and remove function. Use that to build your way forvered
https://plnkr.co/edit/w6NuVLcqzc5Rjs7L6Cox?p=preview
index.html
<div ng-app="phoneApp">
<div ng-controller="ctrl as AppCtrl">
<div phone dial="ctrl.callHome('called home!')"></div>
</div>
</div>
app.js :
var app = angular.module('phoneApp', []);
app.controller("AppCtrl", function ($scope) {
var ctrl = this;
ctrl.callHome = function (message) {
alert(message);
};
});
app.directive("phone", function () {
return {
scope: {},
bindToController : {
dial: "&"
},
controller : controller,
controllerAs : 'controllerVM',
templateUrl : 'node.html'
};
function controller(){
controllerVM.onClick = function(){
controllerVM.dial();
}
}
});
node.html :
<button ng-click="controllerVM.onClick()">Button</button>
when i click on Button of phone directive, it should call the function callHome of AppCtrl, but it is not getting called.
When i removes controllerAs from every where and calls the directive dial function from template directly, it is working properly
So please help me what am i missing?
Thanks in advance :)
Your code has 2 problems. In your HTML, you are using 'ctrl as AppCtrl' which is wrong. You should use 'AppCtrl as ctrl'. The second problem is within phone controller, you have not defined controllerVM. You should define it like 'var controllerVM = this;' I have inserted a working snippet below.
var app = angular.module('phoneApp', []);
app.controller("AppCtrl", function ($scope) {
var ctrl = this;
ctrl.callHome = function (message) {
alert(message);
};
});
app.directive("phone", function () {
return {
scope: {},
bindToController : {
dial: "&?"
},
controller : controller,
controllerAs : 'controllerVM',
template : '<button ng-click="controllerVM.onClick()">Button</button>'
};
function controller(){
var controllerVM = this;
controllerVM.onClick = function(){
controllerVM.dial();
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="phoneApp">
<div ng-controller="AppCtrl as ctrl">
<div phone dial="ctrl.callHome('called home!')"></div>
</div>
</div>
I'm looking for a way in angular to tab through hidden inputs. So I have multiple input forms but when not on focus I want them to just display the text. I'm looking for the ability to once I've selected an input to tab through the other inputs even though they are currently hidden.
Any suggestions?
Use Angular directives to make your inputs into inline editors. When the page loads you'll be in display mode (i.e. the display div will be shown and the editor div will be hidden), then on clicking, the mode switches to Edit mode and the visibility is reversed.
Here's a quick snippet of what a DatePicker control would look like when wrapped in such a directive. Using Angular 1 and Bootstrap 3 (follows John Papa's Angular Style Guide):
HTML Template (inlineDatePicker.html):
<div class="inline-edit">
<div ng-if="!vm.inEditMode" data-ng-click="vm.enableEditMode()">
<input type="hidden" data-ng-model="vm.dateModel" data-ng-required="vm.dateRequired" /><span>{{vm.dateModel}}</span> <span class="glyphicon glyphicon-calendar"></span>
</div>
<div ng-if="vm.inEditMode">
<div class="well well-sm" style="position: absolute; z-index: 10">
<datepicker data-ng-model="vm.dateModel" data-show-weeks="false"></datepicker>
<button type="button" class="btn btn-sm btn-info" ng-click="vm.today()">Today</button>
<button type="button" class="btn btn-sm btn-danger" ng-click="vm.cancel()">Cancel</button>
</div>
</div>
</div>
And the underlying directive (inlineDatePicker.directive.js):
(function () {
'use strict';
angular.module('myApp.inlineEdit')
.directive('inlineDatePicker', inlineDatePicker);
function inlineDatePicker() {
'use strict';
inlineDatePickerController.$inject = ['$scope', '$timeout'];
return {
restrict: 'A',
replace: true,
transclude: false,
templateUrl: '/App/inlineEdit/date/inlineDatePicker.html',
scope: {
dateModel: '=',
dateRequired: '#',
dateChanged: '&'
},
controller: inlineDatePickerController,
controllerAs: 'vm',
};
function inlineDatePickerController($scope, $timeout) {
/* jshint validthis:true */
var vm = this;
vm.inEditMode = false;
vm.dateModel = $scope.dateModel;
vm.dateRequired = $scope.$eval($scope.dateRequired);
vm.enableEditMode = enableEditMode;
vm.cancel = cancel;
vm.today = today;
function enableEditMode() {
vm.inEditMode = true;
}
function cancel() {
vm.inEditMode = false;
}
function today() {
vm.dateModel = new Date();
}
$scope.$watch('vm.dateModel', function (curr, orig) {
$scope.dateModel = vm.dateModel;
if (curr != orig && vm.inEditMode) {
$timeout($scope.dateChanged, 0);
}
vm.inEditMode = false;
});
$scope.$watch('dateModel', function () {
vm.dateModel = $scope.dateModel;
});
}
}
})();
I have this code:
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function() {
var vm = this;
vm.unit = '';
vm.unitForm = "unitForm";
vm.unitInput = "unitInput";
vm.amount = '';
vm.amountForm = "amountForm";
vm.amountInput = "amountInput";
vm.errorText = "Error";
vm.pattern = new RegExp("^[0-9]*$");
vm.calculate = calculate;
function calculate(first, second){
var firstFloat = parseFloat(first.replace(",","."));
var secondFloat = parseFloat(second.replace(",","."));
var total = (firstFloat * secondFloat).toFixed(2);
console.log('calculating', firstFloat, secondFloat, total)
return total.toString().replace(".",",");
}
});
app.directive('textInput', function textInput() {
return {
restrict: 'E',
templateUrl: 'text-input.html',
scope: {
myClass: "#",
value: '=?value',
formName: '=',
inputName: '=',
pattern: '=',
errorText: '=',
change: "&"
}
};
});
text-input.html
<form name="formName">
<input type="text"
name="inputName"
ng-model="value"
ng-class="myClass"
ng-pattern="pattern"
ng-trim="false"
ng-change="change()"
/>
<div data-ng-show="formName.inputName.$error.pattern">
{{errorText}}
</div>
</form>
index.html
<text-input my-class="input"
form-name="vm.unitForm"
input-name="vm.unitInput"
pattern="vm.pattern"
error-text="vm.errorText"
value="vm.unit"
change="vm.total = vm.calculate(vm.amount, vm.unit)"
></text-input>
<br>
<text-input my-class="input"
form-name="vm.amountForm"
input-name="vm.amountInput"
pattern="vm.pattern"
error-text="vm.errorText"
value="vm.amount"
change="vm.total = vm.calculate(vm.amount, vm.unit)"
></text-input>
vm.unit: {{vm.unit}}
<br>
vm.amount: {{vm.amount}}
<br><br>
Just jusing *:{{vm.unit*vm.amount}}
<br>
Change:
{{vm.total}}
Link to plnkr: http://plnkr.co/edit/DOc0v7o7arS6PhYOHaK0?p=preview
As can be seen, I have a directive that binds a variable to a function.
For some reason I can't figure out, the whole thing lags.
To see what's wrong do this: Enter a value in the top box, i.e 2. Enter a value in the second box, i.e 3.
The models lag in input. To see a change from the function, you need to enter another value. But the function now uses the values before your last input!
So, I am thoroughly confused here. What's going on and why won't this work?
i am having a problem with ng-model .When i am adding tag from suggestion list its not updating model value until i am not deleting tags and adding again.In my project its working fine but for plunker only its happening.Please check this out and help me..
thank you..
Here is my html:-
<tags-input ng-model="tags2" display-property="tagName" on-tag-added="getTags()" id="target">
<auto-complete source="loadTags($query)" min-length="2"></auto-complete>
</tags-input>
<p>{{tags2}}</p>
Here is my js:-
var app = angular.module('myApp', ['ngTagsInput', 'ui.bootstrap']);
app.controller(
'myController',
function($scope, $http) {
$scope.tagsValues =[];
$scope.loadTags = function(query) {
return $http.get('tags.json');
};
$scope.getTags = function() {
$scope.tagsValues = $scope.tags2.map(function(tag) {
return tag.tagId;
});
alert(" Tag id is :"+ $scope.tagsValues);
};
});
Here is my plunker:-
http://plnkr.co/edit/6Mr2qk2S2RvGJLevf2UI?p=preview
All you have to do to make this work, is define and initialize the variable $scope.tags2 first:
var app = angular.module('myApp', ['ngTagsInput', 'ui.bootstrap']);
app.controller(
'myController',
function($scope, $http) {
$scope.tagsValues = '';
$scope.tags2 = [];
$scope.loadTags = function(query) {
return $http.get('tags.json');
};
$scope.getTags = function() {
$scope.tagsValues = $scope.tags2.map(function(tag) {
return tag.tagId;
});
alert(" Tag id is :"+ $scope.tagsValues);
};
});
See my plunker: http://plnkr.co/edit/Y3f8kLBnexOXg5gwmldL?p=preview