I'm trying to use a form with validation into a ui-bootstrap modal and the modal as a cancel button that just dismisses the view when clicked. The cancel is not working if there is validation errors. if I click again on the button then the modal closes. What am I possibly doing wrong?
http://plnkr.co/edit/loFUvJRfuycxd3qQwMgM?p=preview
angular.module('myApp', ['ui.bootstrap']);
angular.module('myApp').controller('TestCTRL', function ($scope,modalService) {
$scope.login = function () {
var modalOptions = {
closeButtonText: 'Cancel',
submitForm : function(form) {
if(form.$valid) {
console.log('Loggin in');
}
}
};
modalService.showModal({}, modalOptions).then(function (result) {
console.log('completed');
});
};
});
angular.module('myApp').service('modalService', function ($modal) {
var modalDefaults = {
backdrop: true,
keyboard: true,
modalFade: true,
templateUrl: 'login.html'
};
var modalOptions = {
closeButtonText: 'Close',
actionButtonText: 'OK',
headerText: 'Proceed?',
bodyText: 'Perform this action?'
};
this.showModal = function (customModalDefaults, customModalOptions) {
if (!customModalDefaults) customModalDefaults = {};
customModalDefaults.backdrop = 'static';
return this.show(customModalDefaults, customModalOptions);
};
this.show = function (customModalDefaults, customModalOptions) {
//Create temp objects to work with since we're in a singleton service
var tempModalDefaults = {};
var tempModalOptions = {};
//Map angular-ui modal custom defaults to modal defaults defined in service
angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);
//Map modal.html $scope custom properties to defaults defined in service
angular.extend(tempModalOptions, modalOptions, customModalOptions);
if (!tempModalDefaults.controller) {
tempModalDefaults.controller = function ($scope, $modalInstance) {
$scope.modalOptions = tempModalOptions;
$scope.modalOptions.ok = function (result) {
$modalInstance.close(result);
};
$scope.modalOptions.close = function (result) {
$modalInstance.dismiss('cancel');
};
}
}
return $modal.open(tempModalDefaults).result;
};
});
<!DOCTYPE html>
<html>
<head >
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="ui-bootstrap.js"></script>
<meta charset="utf-8">
<title>test</title>
</head>
<body ng-app="myApp">
<div ng-controller="TestCTRL">
<button type="button" ng-click="login()">Login</button>
</div>
<script src="app.js"></script>
</body>
</html>
<div class="container">
<div class="row">
<div class="col-sm-6 col-md-4 col-md-offset-4">
<div class="account-wall">
<h1 class="text-center login-title">Login</h1>
<form name="loginForm" ng-submit="modalOptions.submitForm(loginForm)" class="form-signin" novalidate>
<div class="form-group">
<label for="email" class="control-label">Email</label>
<input id="email" type="email" name="email" placeholder="Email"
class="form-control" ng-model="user.email" required autofocus>
<div ng-messages="loginForm.email.$error" ng-if="loginForm.$submitted || loginForm.email.$touched" class="errors">
<div ng-message="required">Value required</div>
<div ng-message="email">Valid email required</div>
</div>
</div>
<div class="form-group">
<label for="password" class="control-label">Password</label>
<input id="password" type="password" name="password" placeholder="Password"
class="form-control" ng-model="user.password" required>
<div ng-messages="loginForm.password.$error" ng-if="loginForm.$submitted || loginForm.email.$touched" class="errors">
<div ng-message="required">password is required</div>
</div>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">
Login
</button>
<button class="btn btn-lg btn-primary btn-block" type="button" ng-click="modalOptions.close()">
{{modalOptions.closeButtonText}}
</button>
</form>
</div>
</div>
</div>
</div>
Thanks so much for your help.
I resolved it by setting the form to pristine before closing the modal, in the cancel action function
function _cancel()
{
$scope.newForm.$setPristine();
$modalInstance.close();
}
Related
I am working on dynamic form with ng-repeat. I am using oi-select for loading my location. I am loading this form inside modal popup. Regarding get my location values i am calling one api function on click of my modal open button. On success of this api call i was calling ng-init method. As per my requirement i should make this api call on click of modal open button. If i am clicking that button at first time, by default my first location value is not loaded inside select-box. Because my ng-init function called before my api call. Other than first time its working fine. Only first time it was not loaded that location[0] value defaultly . My question is how to delay this ng-init function?. Is there any other way to resolve this issue. Here i attached my plunker link .Please help me out from this issue. https://plnkr.co/edit/xDVetaZIzpFdKLS9ihU6?p=preview
html code
<body class="container row">
<div ng-app="myApp">
<div ng-controller="myCtrl">
<a class="btn btn-primary" data-toggle="modal" href='#modal-id' ng-click="getLocation()">Trigger modal</a>
<div class="modal fade" id="modal-id">
<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">Modal title</h4>
</div>
<div class="modal-body">
<form role="form" name='userForm' novalidate>
<div class="container">
<div class="row" ng-repeat="user in users">
<div class="form-group">
<div class="col-md-3">
<label>ID</label>
<input ng-model="user.id" id="user.id" name="user.id" placeholder="Enter bugid" type="text" required readonly disabled>
</div>
<div class="col-md-3">
<label>Comments</label>
<textarea ng-model="user.comment" id="textarea1" rows="1" required></textarea>
</div>
<div class="col-md-3 ">
<label>Location</label>
<oi-select ng-model="user.location" multiple oi-options="v for v in locations" ng-init='initLocation(user, locations)' name="select2" required>
</oi-select>
</div>
</div>
</div>
</div>
<div class="buttonContainer text-center btn-container">
<br>
<button ng-disabled="userForm.$invalid" type="button" id="adduser" ng-click="adduser()">Add user</button>
<button type="button" class="btn button--default btn--small pull-center">Close</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</div>
</div>
js code
var app = angular.module('myApp', ['ngResource', 'oi.select']);
app.factory('commonService', function($http, $q) {
return {
preFCSManualReleases: function() {
var deferred = $q.defer();
var url = "data.json";
$http.get(url, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
data: ''
}).then(function(data) {
deferred.resolve(data.data);
});
return deferred.promise;
}
}
});
app.controller('myCtrl', function($scope, commonService) {
$scope.getLocation = function() {
$scope.ids = [1, 2];
commonService.preFCSManualReleases().then(function(data) {
$scope.locations = data;
console.log('$scope.location[0]==============>', $scope.locations[0])
$scope.initLocation = (user, locations) => {
if (!user.location.length) {
user.location.push(locations[0]);
}
}
});
$scope.users = $scope.ids.map(function(id) {
return {
id: id,
comment: "",
location: []
};
});
}
$scope.adduser = function() {
var data = $scope.users.map(function(user) {
return {
"userid": user.id,
"manualcomment": user.comment,
"location": user.location
}
});
console.log("data", data)
}
});
You can put a condition on the oi-select parent:
<div class="col-md-3" ng-if="locationsLoaded">
<label>Location</label>
<oi-select ng-model="user.location" multiple oi-options="v for v in locations" ng-init='initLocation(user, locations)' name="select2" required>
</oi-select>
</div>
You can then control the $scope.locationsLoaded in your controller:
$scope.getLocation = function() {
$scope.locationsLoaded = false;
commonService.preFCSManualReleases().then(function(data) {
$scope.locations = data;
console.log('$scope.location[0]==============>', $scope.locations[0])
$scope.initLocation = (user, locations) => {
if (!user.location.length) {
user.location.push(locations[0]);
}
}
$scope.locationsLoaded = true; // we now have the required data
});
}
The ng-if will compile the element once locationsLoaded is true and when the ng-init is triggered, you are sure that there is data.
I have done Todo Application.
There are 3 function:
1. View
2. Add Todo
3. Delete Todo
I try to add the updateTodo function but it doesn't work.
Please help to check the code.
Please see my code as following:
Todo Application HTML Page
index.html
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<title>Angular Todo Application</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="styles/bootstrap/css/bootstrap.min.css">
<script src="js/angular/angular.min.js"></script>
<script src="js/app.js"></script>
<script src="js/services/TodoService.js"></script>
<script src="js/dependencies/sails.io.js"></script>
</head>
<body>
<div class="container" ng-controller="TodoCtrl">
<div class="jumbotron">
<h1 align="center">Todo Application</h1>
<br>
<div id="todo-form" class="row">
<div class="col-sm-8 col-sm-offset-2 text-center">
<form>
<div class="form-group">
<input type="text" class="form-control input-lg text-center" placeholder="Add Todo!" ng-model="formData.value"><br>
<button type="submit" class="btn btn-primary btn-lg" ng-click="addTodo()">Add Todo</button>
</div>
</form>
</div>
</div>
</div>
<div id="todo-list" class="row">
<div class="col-sm-4 col-sm-offset-4">
<div class="checkbox" ng-repeat="todo in todos">
<form class="form-inline">
<input type="checkbox" ng-click="removeTodo(todo)">
<input type="text" class="form-control input-sm" ng-model="todo.value">
<button type="submit" class="btn btn-primary btn-sm" ng-click="updateTodo()">Update Todo</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
app.js
'use strict';
var todoApp = angular.module('todoApp',[]);
todoApp.controller('TodoCtrl', ['$scope', '$rootScope', 'TodoService',
function($scope, $rootScope, TodoService) {
$scope.formData = {};
$scope.todos = [];
TodoService.getTodos().then(function(response) {
$scope.todos = response;
})
$scope.addTodo = function() {
TodoService.addTodo($scope.formData).then(function(response) {
$scope.todos.push(response)
$scope.formData = {};
})
}
$scope.removeTodo = function(todo) {
TodoService.removeTodo(todo).then(function(response) {
$scope.todos.splice($scope.todos.indexOf(todo), 1)
})
}
$scope.editTodo = function(todo) {
TodoService.editTodo(todo).then(function(response) {
$scope.todos.splice(i$scope.todos.indexOf(todo), 1, response)
})
}
}])
TodoService.js
todoApp.service('TodoService', function($http, $q) {
return {
'getTodos': function() {
var defer = $q.defer();
$http.get('/todo').success(function(resp){
defer.resolve(resp);
}).error( function(err) {
defer.reject(err);
});
return defer.promise;
},
'addTodo': function(todo) {
var defer = $q.defer();
$http.post('/todo', todo).success(function(resp){
defer.resolve(resp);
}).error( function(err) {
defer.reject(err);
});
return defer.promise;
},
'removeTodo': function(todo) {
var defer = $q.defer();
$http.delete('/todo/'+todo.id, todo).success(function(resp){
defer.resolve(resp);
}).error( function(err) {
defer.reject(err);
});
return defer.promise;
},
'updateTodo': function(todo) {
var defer = $q.defer();
$http.put('/todo/'+todo.id, todo).success(function(resp){
defer.resolve(resp);
}).error( function(err) {
defer.reject(err);
});
return defer.promise;
}
}
})
I don't see updateTodo() function in app.js which is called in the line
<button type="submit" class="btn btn-primary btn-sm" ng-click="updateTodo()">Update Todo</button>
I think you should change updateTodo() to editTodo() in HTML
I have a form inside a bootstrap modal.But I can't able to get the values of form on controller side with scope variable.
https://plnkr.co/edit/FjKXUpoBDdvQqomI97ml?p=preview
My original code has another problem also. when I click on submit button it will refresh the whole page and submit function is not executing.
My form:
<div class="modal-body">
<form class="form-horizontal" name="contact" ng-submit="contactForm()">
<div class="form-group">
<label class="col-lg-3 control-label">Name* :</label>
<div class="col-lg-8">
<input class="form-control" type="text" id="name" name="_name" ng-model="_name" > </div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Email* :</label>
<div class="col-lg-8">
<input class="form-control" type="email" id="email" name="_email" ng-model="_email" required> </div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Mobile* :</label>
<div class="col-lg-8 row">
<div class="col-lg-4">
<input type="text" class="form-control" ng-model="_cc" placeholder="+91" name="_cc"> </div>
<div class="col-lg-8">
<input class="form-control" type="text" ng-model="_mobile" maxlength="10" ng-pattern="/^[0-9]{5,10}$/" id="mobile" name="_mobile"></div>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Message :</label>
<div class="col-lg-8">
<textarea class="form-control" rows="2" name="_condition" ng-model="_condition"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-7 col-lg-5">
<button type="submit" class="btn btn-primary" id="contactSubmit" >Submit</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div></div>
</form>
</div>
Controller:
$scope.contactForm = function(){
console.log($scope._condition,$scope._name,$scope._email,$scope._cc,$scope._mobile);
};
You are opening the modal using plain jQuery approach which is not going to work in Angular, because opened modal is not connected to Angular application, so it doesn't know that modal has to be handled, HTML parsed, etc.
Instead you should use directives properly, or in case of modal dialog you can simply use existent ones, like Angular UI project, which brings ready Bootstrap directives for Angular. In your case you need $modal service and inject the $http service to have your data posted.
Here is the working plunker using angular-ui bootstrap.
PLUNKER:https://plnkr.co/edit/rjtHJl0udyE0PTMQJn6p?p=preview
<html ng-app="plunker">
<head>
<script src="https://code.angularjs.org/1.2.18/angular.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="script.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<form ng-submit="submit()">
<div class="modal-body">
<label>Email address:</label>
<input type="email" ng-model="user.email" />
<label>Password</label>
<input type="password" ng-model="user.password" />
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<input type="submit" class="btn primary-btn" value="Submit" />
</div>
</form>
</script>
<button class="btn" ng-click="open()">Open Modal</button>
</div>
</body>
</html>
JS:
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log,$http) {
$scope.user = {
email: '',
password: null,
};
$scope.open = function () {
$modal.open({
templateUrl: 'myModalContent.html', // loads the template
backdrop: true, // setting backdrop allows us to close the modal window on clicking outside the modal window
windowClass: 'modal', // windowClass - additional CSS class(es) to be added to a modal window template
controller: function ($scope, $modalInstance, $log, user) {
$scope.user = user;
$scope.submit = function () {
$log.log('Submiting user info.'); // kinda console logs this statement
$log.log(user);
$http({
method: 'POST',
url: 'https://mytesturl.com/apihit',
headers: {
"Content-type": undefined
}
, data: user
}).then(function (response) {
console.log(response);
$modalInstance.dismiss('cancel');
}, function (response) {
console.log('i am in error');
$modalInstance.dismiss('cancel');
});
//$modalInstance.dismiss('cancel'); // dismiss(reason) - a method that can be used to dismiss a modal, passing a reason
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
},
resolve: {
user: function () {
return $scope.user;
}
}
});//end of modal.open
}; // end of scope.open function
};
I have a "search" where the user input a value and i want to send this value in the service because i want that another controller can have access. But for the moment i can't do it, if someone can help me it would be very usfull i using Angular js.
And the js
var app = angular.module('MainApp', [])
app.factory('Search', function($rootScope, $http){
var search = '';
function setSearch(bus){
search = bus;
}
function getSearch(){
return search;
}
return{
setSearch : setSearch,
getSearch: getSearch
};
//return myFactory;
/*
$scope.Search = function() {
return {
getDoctor: function () {
return $http.get('api/doctor' + $scope.search.searchText).then(function (response) {
orders = response.data;
$rootScope.$broadcast('handleSharedOrders', orders);
return orders;
})
}
};
}*/
});
app.controller('mainController', function ($scope, $http, Search) {
$scope.loadList = function() {
location.href = "doctors";
};
$scope.search.searchText = Search.getSearch();
$scope.Search = function(bus) {
console.log(bus);
Search.setSearch(bus);
}
$scope.doctors = {};
$http.get('/api/doctor').success(function (data) {
$scope.doctors = data;
})
.error(function (data) {
console.log('Error: ' + data);
});
/*
$http.get('/api/doctor/' + specialty).success(function (data) {
$scope.doctorsSpecialty = data;
})
.error(function (data) {
console.log('Error: ' + data);
});
*/
});
<!DOCTYPE html>
<html ng-app="MainApp">
<head lang="en">
<meta charset="UTF-8">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<!-- Cargamos app -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="../Controllers/core.js"></script>
<title></title>
</head>
<body ng-controller="mainController">
<div align="center">
<img src="../img/logo.jpg" >
</div>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default" >
<div class="panel-heading" >
<h3 class="panel-title">Search Doctors</h3>
</div>
<div class="panel-body" >
<form role="form" >
<fieldset>
<div class="form-group" name="myForm" >
<input ng-model="search.searchText" type="text" class="form-control" placeholder="Search..." align="center">
</div>
<button class="btn btn-default" type="button" align="center" ng-click="Search(searchText)">
<b align="center">Search</b>
</button>
<!-- Change this to a button or input when using this as a form -->
</fieldset>
</form>
</div>
</div>
<div class="panel-heading" STYLE="background-color: #a7b5ce">
<h3 class="panel-title">List of Doctors</h3>
</div>
<div class="panel-body" >
<form role="form">
<fieldset>
<div class="form-group" name="myForm" >
<button class="btn btn-default" type="button" align="center" href=doctors ng-click="loadList()">
<b>List of Doctors</b>
</button>
</div>
<!-- Change this to a button or input when using this as a form -->
</fieldset>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
thank you for helping me
Here you have defined search.searchText:
<input ng-model="search.searchText" type="text" class="form-control" placeholder="Search..." align="center">
And here you are trying to pass just searchText (which is undefined):
<button class="btn btn-default" type="button" align="center" ng-click="Search(searchText)">
<b align="center">Search</b>
</button>
You need to either change your ng-model on your <input> to be 'search' or change the ng-click on your <button> to 'Search(search.searchText)'. If you choose to do the latter you may also want to explicitly create the search object in your controller.
I think you were doing it well, but your code has a few errors. First, you are not declaring the object search in your scope but you are assigning the property searchText to it. So you should do something like that:
$scope.search = {
searchText: ''
};
Then, in the view when you click search you are passing searchText but it should be search.searchText.
Have a look at this: https://jsfiddle.net/jruizx/54xcmgqp/
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