external template (templateURL) in Angular directive is not working - angularjs

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({})
}
})

Related

AngularJS How to manipulate array of objects if each element is stored inside a stand alone directive?

I've created a custom directive to serve as a template to show some information using ng-repeat. I also need to do some manipulation on the array that being looped. My question is how can I remove or add elements to that array, if each element is inside a separate scope inside a stand-alone directive? Without the use of the directive the task is easy:
<div class="well" ng-repeat="dat in data">
<form novalidate>
<div class="form-group">
<label for="name">name:</label>
<input type="text" class="form-control" id="name" ng-model="dat.name" ng-disabled="enableEdit">
</div>
<div class="form-group">
<label for="balance">balance:</label>
<input type="text" class="form-control" id="balance" ng-model="dat.balance" ng-disabled="enableEdit">
</div>
<div class="form-group">
<label for="fruit">favorite Fruit:</label>
<input type="text" class="form-control" id="fruit" ng-model="dat.favoriteFruit" ng-disabled="enableEdit">
</div>
<div class="form-group">
<label for="greeting">greeting:</label>
<input type="text" class="form-control" id="greeting" ng-model="dat.greeting" ng-disabled="enableEdit">
</div>
<button class="btn btn-danger" ng-click="remove($index)">remove</button>
<button class="btn btn-default" ng-click="enableEdit=!enableEdit">edit</button>
<button class="btn btn-success" ng-click="save(dat,$index);enableEdit=!enableEdit" ng-disabled="enableEdit">save</button>
</form>
</div>
After the refactoring to directive, the task is not so obvious:
<div class="well" ng-repeat="dat in data">
<data-directive user="dat" index="{{$index}}" arr="data"></data-directive>
</div>
The directive template looks as follows:
<form novalidate>
<div class="form-group">
<label for="name">name:</label>
<input type="text" class="form-control" id="name" ng-model="user.name" ng-disabled="enableEdit">
</div>
<div class="form-group">
<label for="balance">balance:</label>
<input type="text" class="form-control" id="balance" ng-model="user.balance" ng-disabled="enableEdit">
</div>
<div class="form-group">
<label for="fruit">favorite Fruit:</label>
<input type="text" class="form-control" id="fruit" ng-model="user.favoriteFruit" ng-disabled="enableEdit">
</div>
<div class="form-group">
<label for="greeting">greeting:</label>
<input type="text" class="form-control" id="greeting" ng-model="user.greeting" ng-disabled="enableEdit">
</div>
<button class="btn btn-danger" ng-click="remove(index)">remove</button>
<button class="btn btn-default" ng-click="enableEdit=!enableEdit">edit</button>
<button class="btn btn-success" ng-click="save(user,$index);enableEdit=!enableEdit" ng-disabled="enableEdit">save</button>
</form>
Directive js:
app.directive("data-directive", ["dataService", function (dataService) {
return {
restrict: 'E',
templateUrl:"directives/dataDirectiveTemplate.html",
scope:{
user: "=",
index: "#",
arr: "="
},
controller: function ($scope) {
$scope.enableEdit = true;
$scope.remove = function (index) {
console.log(arr);
dataService.removeItem(arr, parseInt(index));
};
$scope.save = function (item,index) {
dataService.saveItem(item, index, $scope.data);
};
$scope.changes = function () {
console.log($scope.data);
};
}
}
}]);
I managed to pass the $index variable, but how do I pass the whole data array of objects?
Let's first define an owner for data. It can be the controller whose view is using data-directive or dataService.
Now, owner holds data and all responsibility to manipulate it.
If it is dataService, its method can be called from the directive and data is already available with it.
If it is controller it can pass method using & e.g.:
scope: {
user: "=",
index: "#",
arr: "=",
onRemove: "&",
onSave: "&",
onChange: "&",
},

angularjs form inside bootstrap modal popup

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
};

how to call main controllers function from child directive in angularjs

I am not able to call method adddepartment which is in controller.I am calling this method from myCreateDialog.html.
My second directive in under the first directive. I am able to call departments method which is in controller from myDept directive. but not able to call adddepartment method of controller from myCreateDialog directive.
How do i call this method?
myApp.controller('departmentController', ['$scope', 'departmentService' ,
function ($scope, departmentService) {
$scope.departments = departmentService.departments;
var a, b;
//Add New Department
$scope.adddepartment = function (emps) {
departmentService.adddepartment(depts);
$scope.depts = "";
};
}]);
myApp.directive("myDept", function () {
return {
restrict: "E",
scope:{
department:"="
},
templateUrl: 'Template/Alldepartment.html',
replace: false,
transclude:true,
link: function (scope, element, attrs, controller) {}
};
});
myApp.directive("myCreateDialog", function () {
return {
restrict: "E",
scope:{
adddepartment: "&"
},
templateUrl: 'Template/myCreateDialog.html',
link: function (scope, element, attrs, controller) {
}
};
});
App.js
var myApp = angular.module("myApp", ['ngRoute']);
myApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/Employee', {
templateUrl: 'Template/Employee.html',
controller: 'employeeController'
}).
when('/Department', {
templateUrl: 'Template/Department.html',
controller: 'departmentController'
})
}]);
Department.html
<my-dept department="departments">
<p>This text is coming by transclude</p>
</my-dept>
Alldepartment.html
<div>
<div class='myTransclude' ng-transclude></div>
<button class="btn btn-success" data-toggle="modal" data-target="#crtdept">
<span class="glyphicon glyphicon-plus-sign"></span> Create New Department
</button>
</div><br />
<!--Display department data into table-->
<div class="table-responsive">
<table class="table table-bordered table-striped table-hover ">
<thead>
<tr class="success ">
<th>Id</th>
<th>Name</th>
<th>Technology</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="dept in department">
<td>{{dept.id}}</td>
<td>{{dept.name}}</td>
<td>{{dept.technology}}</td>
<td>
<button class="btn btn-link" title="Edit" data-toggle="modal" data-target="#editemp" ng-click="empedit(employee,employees.indexOf(employee))">
<span class="text-warning glyphicon glyphicon-pencil"></span> Edit 
</button>
<button class="btn btn-link" ng-click="deleteemp(employees.indexOf(employee))">
<span class=" text-danger glyphicon glyphicon-trash "> Delete</span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<!--myCreateDialog directive for showing dialog for creating department-->
<my-create-dialog adddepartment="adddepartment(depts)"></my-create-dialog>
myCreateDialog.html
<div class="modal fade" id="crtdept">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" style="color:red" class=" close" data-dismiss="modal"> ×</button>
<h4 class="modal-title">Create Employee</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" data-toggle="validator" role="form" ng-submit="adddepartment(emps)">
<div class="form-group">
<label class="control-label col-sm-2" for="name">Name:</label>
<div class="col-sm-10 has-success">
<input type="text" class="form-control" placeholder="Enter Your Name" ng-model="emps.empnames" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="email">Email:</label>
<div class="col-sm-10 has-success">
<input type="email" class="form-control" id="email" placeholder="Enter Your email" ng-model="emps.empemails" required>
</div>
</div>
<div class=" form-group">
<label class="control-label col-sm-2">City:</label>
<div class="col-sm-10 has-success">
<input type="text" class="form-control" placeholder="Enter Your City" ng-model="emps.empcitys" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Department:</label>
<div class="col-sm-10 has-success">
<input type="text" class="form-control" placeholder="Enter your Department" ng-model="emps.empdepts" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Technology:</label>
<div class="col-sm-10 has-success">
<input type="text" class="form-control" placeholder="Enter your Technology" ng-model="emps.emptechs" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success"><span class="glyphicon glyphicon glyphicon-ok"></span> Create</button>
</div>
</div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal"> Close</button>
</div>
</div>
</div>
</div>
</div>
You can inject your departmentService into your directive and call it from there
myApp.directive("myCreateDialog", function (departmentService) {
return {
restrict: "E",
templateUrl: 'Template/myCreateDialog.html',
link: function (scope, element, attrs, controller) {
scope.adddepartment = function (emps) {
departmentService.adddepartment(depts);
scope.depts = "";
};
}
};
});

Angular 1.3 data binding not working

I'm running into some problems with Angular 1.3.2
I'm expecting to see the formData object being populated with whatever is being typed in the input fields
I have the following code.
angular.module('formApp', [])
.controller('FormController', function ($scope, $http) {
$scope.formData = {};
$scope.processForm = function () {
};
});
<div class="form-container" ng-app="formApp" ng-controller="FormController">
<div class="container">
<form>
<div id="name-group" class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="Bruce Wayne" ng-model="formData.name">
<span class="help-block"></span>
</div>
<div id="superhero-group" class="form-group">
<label>Superhero Alias</label>
<input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader"
ng-model="formData.superheroAlias">
<span class="help-block"></span>
</div>
<button type="submit" class="btn btn-success btn-lg btn-block">
<span class="glyphicon glyphicon-flash"></span> Submit!
</button>
</form>
<pre>
{{ formData }}
</pre>
</div>
</div>
you have a typo in your ngcontroller syntax. it should be ng-controller
<div class="form-container" ng-app="formApp" ng-controller="FormController">
Copied your code and it is working, see below:
angular.module('formApp', [])
.controller('FormController', function ($scope, $http) {
$scope.formData = {};
$scope.processForm = function () {
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="form-container" ng-app="formApp" ng-controller="FormController">
<div class="container">
<form>
<div id="name-group" class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="Bruce Wayne" ng-model="formData.name">
<span class="help-block"></span>
</div>
<div id="superhero-group" class="form-group">
<label>Superhero Alias</label>
<input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader"
ng-model="formData.superheroAlias">
<span class="help-block"></span>
</div>
<button type="submit" class="btn btn-success btn-lg btn-block">
<span class="glyphicon glyphicon-flash"></span> Submit!
</button>
</form>
<pre>
{{ formData }}
</pre>
</div>
</div>

Why an undefined is not a function with Angular directive to close Bootstrap modal

As a newbie to Angularjs I copied a directive from here: Closing Twitter Bootstrap Modal From Angular Controller, to be able to close a bootstrap modal from a controller, and in my implementation I'm getting an undefined is not a function error. (http://jsfiddle.net/jlamont/7f6dH/6/)
Here's the html
<div ng:app="app">
<div>
<ul><li>Login</li></ul>
<div id='loginModal' class='modal fade' myModal ng-controller="LoginDialogController" tabindex="-2" role="dialog" aria-labelledby="loginModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" ng-click="cancel()">x</button>
<h3>Login MyApp</h3>
</div>
<div class="modal-body">
<form name="login_form">
<alert ng-repeat="alert in alerts" type="danger" close="closeAlert($index)">{{alert.msg}}</alert>
<p><input type="text" class="span3" ng-model="login.user_email" placeholder="Email" required></p>
<p><input type="password" class="span3" ng-model='login.password' placeholder="Password" required></p>
<p><button type="submit" class="btn btn-primary" ng-click="ok()">Sign in</button>
Forgot Password?
</p>
</form>
</div>
<div class="modal-footer">
My.com?
Register
</div>
</div>
</div>
</div>
</div>
</div>
Here's the js
angular.module("app", []).directive('myModal', function() {
return {
restrict: 'A',
scope:{},
link: function(scope, element, attr) {
scope.dismiss = function() {
element.modal('hide');
};
}
}
});
function LoginDialogController($scope){
$scope.ok = function(){
$scope.dismiss();
};
}

Resources