ng-model not updating inside Modal - angularjs

ng-model which i am assigning is controller can be seen inside modal.But when i am updating the data inside the modal,the $scope variable is not updating.
Also dropdown is not working whose value i have defined in my controller.
Do i need to make changes in directive.
<div ng-controller="MainCtrl" class="container">
<h1>Modal example</h1>
<button ng-click="toggleModal()" class="btn btn-default">Open modal</button>
<modal title="Login form" visible="showModal">
<div>
<select ng-model="client" ng-change="changeClient()" ng-options="item in clientList">
<label for="email">Email address</label>
<input type="text" ng-model="email" id="email" placeholder="Enter email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" placeholder="Password" />
</div>
<button type="submit" ng-click="buttonClicked()" class="btn btn-default">Submit</button>
</modal>
</div>
CONTROLLER CODE
var mymodal = angular.module('mymodal', []);
mymodal.controller('MainCtrl', function ($scope) {
$scope.email="hello#abc.com";
$scope.showModal = false;
$scope.toggleModal = function(){
$scope.showModal = !$scope.showModal;
};
$scope.buttonClicked=function(){
alert("hello1");
alert($scope.email);
alert($scope.client);
}
$scope.clientList=["300","600","900"]
$scope.client=$scope.clientList[0];
$scope.changeClient = function() {
selectedValue=$scope.client;
alert(selectedValue);
};
});
mymodal.directive('modal', function () {
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>' +
'<h4 class="modal-title">{{ title }}</h4>' +
'</div>' +
'<div class="modal-body" ng-transclude></div>' +
'</div>' +
'</div>' +
'</div>',
restrict: 'E',
transclude: true,
replace:true,
scope:true,
link: function postLink(scope, element, attrs) {
scope.title = attrs.title;
scope.$watch(attrs.visible, function(value){
if(value == true)
$(element).modal('show');
else
$(element).modal('hide');
});
$(element).on('shown.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
Have a Look-JsFiddle Link

you should use:
$parent.email
<input type="text" ng-model="$parent.email" id="email" placeholder="Enter email" />
fiddle

As huan feng said, you can use '$parent' because directive has it's own isolated scope. For your 'select' the simplest solution is to use something like that:
<select ng-model="$parent.client" ng-change="changeClient()" ng-options="item for item in clientList">
But, it could be better to use your model in a little bit different way. Create your 'clientInfo' object with email and clien as properties.
JS:
.controller('MainCtrl', function ($scope) {
$scope.clientInfo = {};
$scope.clientInfo.email="hello#abc.com";
$scope.showModal = false;
$scope.toggleModal = function(){
$scope.showModal = !$scope.showModal;
};
$scope.buttonClicked=function(){
alert("hello1");
alert($scope.clientInfo.email);
alert($scope.clientInfo.client);
}
$scope.clientList=["300","600","900"]
$scope.clientInfo.client = $scope.clientList[0];
$scope.changeClient = function() {
selectedValue=$scope.clientInfo.client;
alert(selectedValue);
};
});
And HTML:
<div ng-controller="MainCtrl" class="container">
<h1>Modal example</h1>
<button ng-click="toggleModal()" class="btn btn-default">Open modal</button>
<modal title="Login form" visible="showModal">
<div>
<select ng-model="clientInfo.client" ng-change="changeClient()" ng-options="item for item in clientList">
<label for="email">Email address</label>
<input type="text" ng-model="clientInfo.email" id="email" placeholder="Enter email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" placeholder="Password" />
</div>
<button type="submit" ng-click="buttonClicked()" class="btn btn-default">Submit</button>
</modal>
</div>

Related

external template (templateURL) in Angular directive is not working

I'm trying to create an accordion on button click using AngularJS directive. I have external template for creating accordion. But I couldn't get it working. Here is the code:
Directive:
(function() {
'use strict';
angular.module('accountApp')
.directive('addSubsite', addSubsite);
function addSubsite ($compile, $templateRequest){
var ddo = {
restrict: 'A',
link: function(scope, element) {
element.bind("click", function(e){
$templateRequest("addSubsiteTemplate.html").then(function(html){
var template = angular.element(html);
$element.append(template);
$compile(template)(scope);
$element.find(".add-subsites").append(template);
});
});
}
};
return ddo;
}
})();
index.html
<button add-subsite type="button" class="btn btn-primary pull-right margin10-b"id="aid-addSubSitebtn">Add Sub-Site</button>
<accordion>
<accordion-group>
<div class="accordion-heading header">
<a class="accordion-toggle" id="primary__site__address" data-toggle="collapse" href="#primary__site">
<h4><span class="pull-left"><i class="icon-minus"></i></span>Business Name (Primary Site)</h4></a>
</div>
<div class="form-group">
<label for="exampleInputName2">Name</label>
<input type="text" class="form-control" id="exampleInputName2" placeholder="Jane Doe">
</div>
<div class="form-group">
<label for="exampleInputEmail2">Email</label>
<input type="email" class="form-control" id="exampleInputEmail2" placeholder="jane.doe#example.com">
</div>
<button type="submit" class="btn btn-default">Send invitation</button>
</accordion-group>
</accordion>
Template.html
<accordion>
<accordion-group>
<div class="accordion-heading header">
<a class="accordion-toggle"data-toggle="collapse" href="#subsite__site">
<h4><span class="pull-left"><i class="icon-minus"></i></span>Business Name (SubSite)</h4></a>
</div>
<div class="form-group">
<label for="exampleInputName2">Name</label>
<input type="text" class="form-control" id="exampleInputName2" placeholder="Jane Doe">
</div>
<div class="form-group">
<label for="exampleInputEmail2">Email</label>
<input type="email" class="form-control" id="exampleInputEmail2" placeholder="jane.doe#example.com">
</div>
<button type="submit" class="btn btn-default">Send invitation</button>
</accordion-group>
</accordion>
I changed my approach Here is the sample https://jsfiddle.net/2u7aLg5c/
angular.module('testApp',[])
.controller('TestController', function(){
const vm = this;
vm.inputs=[{}];
vm.myInput = [];
vm.add = function(){
vm.inputs.push({})
}
})

AngularJS not working in modal popup

I have my code but it seems like the angularjs codes are not working. I dont know whats the problem though I already did these things:
<html ng-app="exampleApp">
these too
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="angular/angular.min.js"></script>
<script src="css/bootstrap.min.js"></script>
<script src="css/jquery.min.js"></script>
also these
var mymodal = angular.module('mymodal', []);
mymodal.controller('MainCtrl', function ($scope) {
$scope.showModal = false;
$scope.toggleModal = function(){
$scope.showModal = !$scope.showModal;
};
});
mymodal.directive('modal', function () {
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>' +
'<h4 class="modal-title">{{ title }}</h4>' +
'</div>' +
'<div class="modal-body" ng-transclude></div>' +
'</div>' +
'</div>' +
'</div>',
restrict: 'E',
transclude: true,
replace:true,
scope:true,
link: function postLink(scope, element, attrs) {
scope.title = attrs.title;
scope.$watch(attrs.visible, function(value){
if(value == true)
$(element).modal('show');
else
$(element).modal('hide');
});
$(element).on('shown.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
and
<modal title="Login form" visible="showModal">
<form role="form">
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" placeholder="Enter email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" />
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</modal>
and finally these:
<div class="col-md-offset-1 col-md-10 col-sm-12 text_right" ng-controller="MainCtrl">
<button ng-click="toggleModal()" class="btn btn-default">SAVE</button>
</div>
<script>
var mymodal = angular.module('mymodal', []);
mymodal.controller('MainCtrl', function ($scope) {
$scope.showModal = false;
$scope.toggleModal = function(){
$scope.showModal = !$scope.showModal;
};
});
mymodal.directive('modal', function () {
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>' +
'<h4 class="modal-title">{{ title }}</h4>' +
'</div>' +
'<div class="modal-body" ng-transclude></div>' +
'</div>' +
'</div>' +
'</div>',
restrict: 'E',
transclude: true,
replace:true,
scope:true,
link: function postLink(scope, element, attrs) {
scope.title = attrs.title;
scope.$watch(attrs.visible, function(value){
if(value == true)
$(element).modal('show');
else
$(element).modal('hide');
});
$(element).on('shown.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
<modal title="Login form" visible="showModal">
<form role="form">
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" placeholder="Enter email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" />
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</modal>
</script>
and i don't know what seems to be the problem please help
Change the line
var mymodal = angular.module('mymodal', []);
to
var mymodal = angular.module('exampleApp', []);

angular FormController validation

I have this html form:
<div class="modal-body">
<form name="addAdminForm">
<div class="form-group addPopupLabel">
<div class="container-fluid-full" id="email3">
<input placeholder="Email" type="text" ng-model="model.email" required />
</div>
<div class="container-fluid-full">
<input placeholder="Password (at last 6 characters)" type="password" ng-model="model.password1" id="pw1" name="pw1" required />
</div>
<div class="container-fluid-full">
<input placeholder="Confirm password" type="password" ng-model="model.password2" id="pw2" name="pw2" required password-compare="pw1" />
</div>
<div class="container-fluid-full">
<label>Admin</label>
<input type="radio" class="form-control" name="role" ng-model="model.role" ng-value="userRoles.admin">
</div>
<div class="container-fluid-full">
<label>CS</label>
<input type="radio" class="form-control" name="role" ng-model="model.role" ng-value="userRoles.cs">
</div>
<div>
<span class="errormessage" style="color:red">{{errormessage}}</span>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="addAdminForm.$invalid" ng-click="createForm.$invalid || ok()">Submit</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
The problem: button stay on disable mode while one of the fields is on focus.
How can i solve it by FormController?
The addAdminForm is scoped within the form. So one option is to move the buttons within the form, or move the form element so that it wraps the buttons. I would prefer this since it is dead simple and most times doable.
If it is not possible for some reason, you can make a directive to export the $invalid flag of a form to a variable of the outer scope. A simple implementation would be:
app.directive('bindValidity', ['$parse', function($parse) {
return {
restrict: 'A',
scope: false,
controller: ['$scope', '$attrs', function($scope, $attrs) {
var assign = $parse($attrs.bindValidity).assign;
if (!angular.isFunction(assign)) {
throw new Error('the expression of bindValidity is not settable: ' + $attrs.bindValidity);
}
this.setFormController = function(formCtrl) {
if (!formCtrl) {
throw new Error('bindValidity requires one of <form> or ng-form');
}
$scope.$watch(
function () {
return formCtrl.$invalid;
},
function (newval) {
assign($scope, newval);
}
);
};
}],
require: ['?form', '?ngForm', 'bindValidity'],
link: function (scope, elem, attrs, ctrls) {
var formCtrl, bindValidity;
formCtrl = ctrls[0] || ctrls[1];
bindValidity = ctrls[2];
bindValidity.setFormController(formCtrl);
}
};
}]);
Use it as:
<div class="modal-body">
<form name="addAdminForm" bind-validity="some.variable">
...
</form>
<div class="modal-footer">
<button ... ng-disabled="some.variable" ng-click="some.variable || ok()">Submit</button>

Angular js scope between directive and controllers

I have to show user login page in pop up and have to validate user name and password with the server by using angular js. I create one app model file, and one controller, service and one directive. My code looks like bellow,
app.js
angular.module('mint', ['ngAnimate', 'toastr']);
mycontroller.js
angular.module('mint').controller(
'headercontroller',
[
'$scope',
'headerservice',
'toastr',
function($scope, headerservice, toastr) {
$scope.showModal = false;
$scope.toggleModal = function() {
$scope.showModal = !$scope.showModal;
};
$scope.userSignin = function(){
$scope.userloginbtn = false;
if($scope.signin_form.$valid){ //Error on this line signin_form is undefine. using $valid for undefine
var record = {};
angular.extend(record, $scope.signinForm);
console.log(record);
}else {
$scope.signin_form.submitted = false;
$scope.userloginbtn = true;
}
};
} ]);
my directive.js file is
angular
.module('mint')
.directive(
'modal',
function() {
return {
template : '<div class="modal fade">'
+ '<div class="modal-dialog">'
+ '<div class="modal-content">'
+ '<div class="modal-header">'
+ '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'
+ '<h4 class="modal-title"><span><i class="fa fa-user"></i> {{ title }}</span></h4>'
+ '</div>'
+ '<div class="modal-body" ng-transclude></div>'
+ '</div>' + '</div>' + '</div>',
restrict : 'E',
transclude : true,
replace : true,
scope : true,
link : function postLink(scope, element, attrs) {
scope.title = attrs.title;
scope.$watch(attrs.visible, function(value) {
if (value == true)
$(element).modal('show');
else
$(element).modal('hide');
});
$(element).on('shown.bs.modal', function() {
scope.$apply(function() {
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function() {
scope.$apply(function() {
scope.$parent[attrs.visible] = false;
});
});
}
};
});
My html file looks like
<!DOCTYPE html>
<html lang="en" ng-app="mintmygold">
<body>
<div class="container-fluid ban_bg"
ng-controller="headercontroller">
<div class="but_bg">
<button type="button" class="btn btn-default btn_sin" ng-click="toggleModal()">
<span><i class="fa fa-key"></i> Sign In</span>
</button>
</div>
<modal title="Login" visible="showModal">
<form role="form" name="signin_form" class="signup_form" novalidate
ng-model="signin_form">
<div class="form-group">
<p class="infoMsg" ng-model="signinform_info">Please fill in your login credentials:</p>
</div>
<div class="form-group">
<label for="email">Email address</label>
<input ng-model="signinForm.userEmail" name="userEmail" type="email" class="form-control" id="email" placeholder="Enter email" required />
<div
ng-show="signin_form.$submitted || signin_form.userEmail.$touched">
<span ng-show="signin_form.userEmail.$error.required">Enter your
email.</span> <span ng-show="signin_form.userEmail.$error.email">This
is not a valid email.</span>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input ng-model="signinForm.userPassword" name="userPassword" type="password" class="form-control" id="password" placeholder="Password" required />
<div
ng-show="signin_form.$submitted || signin_form.userPassword.$touched">
<span ng-show="signin_form.userPassword.$error.required">Enter your
password.</span>
</div>
</div>
<button ng-disabled="signin_form.$invalid || !userloginbtn" ng-model="signin" ng-click="userSignin()" type="submit" class="btn btn-primary">Submit</button>
</form>
</modal>
</div></body></html>
Now i can show the popup when click on sign in button. When i submit the form i couldn't get the values of email and password values from the pop up form in controller. what is my mistake of using the scope. Please any one help me.
With a quick overlook, it seems a silly mistake. Change your lines
From
angular.module('mint', ['ngAnimate', 'toastr']);
To
angular.module('mintmygold', ['ngAnimate', 'toastr']);
You are using scope: true which means your directive is creating a child scope and inheriting the properties from its parent.
Therefore any property you define in the directive scope does not exists on you controller scope.
Changing form name=signin_form
for form name=$parent.signin_form or scope: false should fix the problem
I didn't test this though. And it's not a good solution.
I would probably create a service that launches the pop-up and returns a promise that gets resolved/rejected accordingly.
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, modal) {
$scope.launch = function(){
modal.show().then(function(user){
console.log(user)
}, function(err){
console.log(err)
});
}
});
app.factory('modal', ["$document", "$compile", "$rootScope", "$templateCache", "$timeout", "$q",
function ($document, $compile, $rootScope, $templateCache, $timeout, $q) {
var $body = $document.find('body');
return {
show: function(){
var defer = $q.defer(),
child = $rootScope.$new();
child.user = {};
child.close = function(){
defer.reject('canceled');
tpl.remove();
}
child.submit = function(){
defer.resolve(child.user);
tpl.remove();
}
var tpl = angular.element($templateCache.get('modal.html'));
$compile(tpl)(child);
$body.append(tpl);
return defer.promise;
}
};
}]);
index.html
<script type="text/ng-template" id="modal.html">
<div class="modal in" style="position: static; display: block">
<div class="modal-dialog">
<form ng-submit="submit()" class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
Email: <input ng-model="user.email"></input><br>
Password: <input ng-model="user.password"></input>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="close()">Close</button>
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</form>
</div>
</div>
</script>
<button type="button" ng-click="launch()" class="btn btn-primary">Show modal</button>
Plunker
This is just a proof of concept. I think is enough to get you started. I'd strongly recommend to checkout UI Bootstrap and the way the implement their modal

angularfire using $loaded how to access data in a directive

This post is a follow up of
this
(the goal is set img to visibily and set the src)
html
<form class="form-horizontal" role="form" name="form" data-ng-submit="add()">
<div class="form-group">
<input type="text" name="title" tabindex="1" class="form-control" placeholder="{{ 'items.form.title' | translate }}" data-ng-model="item.title" required="required" data-ng-minlength="3" data-ng-maxlength="25" user-feedback />
</div>
<div class="form-group">
<input type="text" name="ingredients" tabindex="2" class="form-control" placeholder="{{ 'items.form.ingredients' | translate }}" data-ng-model="item.ingredients" required="required" ng-pattern="/^\w(\s*,?\s*\w)*$/" user-feedback />
</div>
<div class="form-group">
<input type="text" name="price" tabindex="3" class="form-control" placeholder="{{ 'items.form.price' | translate }}" data-ng-model="item.price" required="required" data-smart-float user-feedback />
</div>
<div class="form-group">
<button type="button" tabindex="4" class="btn btn-default btn-lg" item="item" data-uploader>{{ 'items.form.upload' | translate }}</button>
<input type="text" name="url" style="display:none;" required="required" data-ng-model="item.url" />
</div>
<div class="form-group form-no-required clearfix">
<div class="pull-right">
<button type="submit" tabindex="5" class="btn btn-primary" data-ng-disabled="form.$invalid">{{ 'items.form.submit' | translate }}</button>
</div>
</div>
</form>
js
app.controller('ItemsUpdateController', function ($scope, item, Items, $state) {
item.$loaded().then(function(data) {
$scope.item = data;
});
$scope.add = function() {console.log($scope.item);
/* Items.update(item.$id,$scope.item).then(function () {
$state.transitionTo('items');
});*/
}
});
app.directive('uploader', function() {
return {
restrict: 'A',
scope:{
item: '='
},
link: function(scope, element, attrs) {
if (window.File && window.FileReader && window.FileList && window.Blob) {
var fileElem = angular.element('<input type="file" style="display:none;">');
var imgElem = angular.element('<img src="" width="50" style="margin-left:10px;visibility:hidden;">');
element.after(fileElem);
element.after(imgElem);console.log(scope.item); //This give me undefined
/*if(scope.item.url){
imgElem.css('visibility','visible');
imgElem[0].src = scope.item.url;
}*/
fileElem.on('change',function(e){
e.stopPropagation();
var files = e.target.files;
var reader = new FileReader();
reader.onloadend = function () {
var url = reader.result;
imgElem.css('visibility','visible');
imgElem[0].src = url;
scope.$apply(function () {
scope.item.url = url;
});
}
reader.readAsDataURL(files[0]);
});
element.on('click', function(e) {
e.stopPropagation();
fileElem[0].click();
});
element.on('$destroy',function(){
element.off('click');
});
fileElem.on('$destroy',function(){
fileElem.off('change');
});
}
},
};
});
Why console.log(scope.item); give me undefined
but I can see the right values fill the form ?
and how can I get the value ?
(btw I've tried also with $timeout or $apply but both doesn't work)
I've also tried with
scope.$watch('item', function(newVal, oldVal){
console.log(newVal, oldVal);
}, true);
but I've got
[Exception... "Illegal operation on WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)"
and I don't really understand why
console.log(scope.item);// Object { $$conf={...}, $id="-J_C-q-6bIW9PBZzqpAg"
console.log(angular.equals({}, scope.item));// but this is true !
Ugly ends up
//controller
$scope.item = item;
$scope.item.$loaded().then(function(data) {
$scope.item = data;
});
//directive
if(scope.item.$id){
scope.item.$loaded().then(function(data) {
imgElem.css('visibility','visible');
imgElem[0].src = data.url;
});
if anyone have got a better solution is welcome :)
}

Resources