Creating a directive and Isolating scopes in angular - javascript

Please view my JSFiddle
I have a fairly wonkey interaction that on a div mouseenter/mouseleave toggles a input checkbox on/off. If said checkbox is set true, it then sets a focus of an adjacent input text field.
I would like to isolate this interaction into a directive that will allow me to duplicate without conflict.
i've color coated the boxes for reference
<body ng-app="ngApp" ng-controller="MainCtrl">
<div class="row">
<div class="span2 box red" leave-edit="uncheckInputBox(false)" enter-edit="checkInputBox(true)">hover</div>
<span class='span8'>
<p>red</p>
<input type="checkbox" ng-model="isChecked">
<input xng-focus='isChecked' ng-model="editingInput">
{{isChecked}}
{{editingInput}}
</span>
</div>
<div class="row">
<div class="span2 box blue" leave-edit="uncheckInputBox(false)" enter-edit="checkInputBox(true)">hover</div>
<span class='span8'>
<p>blue</p>
<input type="checkbox" ng-model="isChecked">
<input xng-focus='isChecked' ng-model="editingInput">
{{isChecked}}
{{editingInput}}
</span>
</div>
</div>
js
var app = angular.module('ngApp', [])
app.controller('MainCtrl', ['$scope', function ($scope) {
'use strict';
$scope.isChecked = false;
$scope.$watch('isChecked', function(newV){
newV && $('#name').focus();
},true);
$scope.checkInputBox = function(val) {
$scope.isChecked = val;
};
$scope.uncheckInputBox = function(val) {
$scope.isChecked = val;
};
}]);
app.directive('xngFocus', function() {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.xngFocus,
function (newValue) {
newValue && element.focus();
},true);
}
};
});
app.directive('leaveEdit', function(){
return function(scope, element, attrs) {
element.bind('mouseleave', function() {
scope.$apply(attrs.leaveEdit);
});
};
});
app.directive('enterEdit', function(){
return function(scope, element, attrs) {
element.bind('mouseenter', function() {
scope.$apply(attrs.enterEdit);
});
};
});
css
.box {
height:50px;
cursor:pointer;
color: #fff;
text-align: center;
}
.red {
background: red;
}
.blue {
background: blue;
}

Strange interaction, but okay. You need to not use the same scope for each directive since you want them to be isolated.
I just did this by creating a scope for a directive that has the shared template.
app.directive('why', function() {
return {
scope: {},
link: function($scope, elt, attrs) {
//setup in here
}, ...
A few other things:
Don't include angular through external resources and in the framework section of fiddle. It runs angular over your dom twice and will behave strangely.
Also there are ng-mouseenter and ng-mouseleave directives in angular so you don't need to implement those.
The updated fiddle is here
Hope this helped!

Related

Problems with calling a function in the HTML file using Angular JS

I am fairly new with AngularJS. I'm trying to do something simple for the moment. I created a table with some text I'll have to search with, a reset button (In my program is called "Pulisci") and some panels I'll have to use later. The problem is that, if I call the function I created for resetting the page, the panels mysteriously stop working. I'm banging my head on this since last week.
HTML
<!DOCTYPE html>
<html ng-app="sbi">
<head>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<style>
table,
td {
border-width: 2px;
border-collapse: collapse;
padding: 15px;
color: #000000;
text-align: center;
}
table.pos_fixed1 {
position: relative;
top: 30px;
left: 10px;
}
</style>
</head>
<body>
<form name="form">
<table summary="" width="10%" class="pos_fixed1" align="center">
<tr>
<td>Code Subinstaller<br><input name="codeSub" type="text" ng-model="codeSub"></td>
<td>Stato<br>
<select>
<option value="1">...</option>
<option value="2">WHITE LIST</option>
<option value="3">GRAY LIST</option>
</select>
</td>
</tr>
<tr>
<td>Nome Sub Installer<input name="nomeSub" type="text" ng-model="nomeSub"></td>
<td>Cognome Sub Installer<input name="cognSub" type="text" ng-model="cognSub"></td>
<td>Codice Fiscale<input name="codFisc" type="text" ng- model="codFisc"> </td>
</tr>
</table><br>
<button class="btn btn-wide btn-default.active.focus" data-ng- click="">Cerca</button>
<button class="btn btn-wide btn-default.active.focus" data-ng- click="reset()">Pulisci</button>
</form><br><br>
<section ng-controller="PanelController as panel">
<ul class="nav nav-pills">
<li ng-class="{ active:panel.isSelected(1) }"> <a href ng- click="panel.selectTab(1)">Description</a></li>
<li ng-class="{ active:panel.isSelected(2) }"> <a href ng- click="panel.selectTab(2)">Specifications</a></li>
<li ng-class="{ active:panel.isSelected(3) }"> <a href ng- click="panel.selectTab(3)">Reviews</a></li>
</ul>
<div class="panel" ng-show="panel.isSelected(1)">
<h4>Description </h4>
<p>wtf</p>
</div>
<div class="panel" ng-show="panel.isSelected(2)">
<h4>Idk</h4>
<p>Idc</p>
</div>
<div class="panel" ng-show="panel.isSelected(3)">
<h4>APPARI</h4>
<p>???</p>
</div>
</section>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="myapp.js"></script>
</body>
</html>
JS
(function() {
var app = angular.module('sbi', []);
app.controller('PanelController', function() {
this.tab = 1;
this.selectTab = function(setTab) {
this.tab = setTab;
};
this.isSelected = function(checkTab) {
return this.tab === checkTab;
};
});
})();
(function($scope) {
var app = angular.module('sbi', []);
function MyCtrl($scope) {
$scope.reset = function() {
$scope.requiredField = '';
};
};
});
How can I make the Reset() and the panels work simultaneously?
You have re-initialized your angular module.
Initializing your angular module
var app = angular.module('sbi', []);
Second argument in angular.module() is for injecting the required dependency for the module. And hence should be done only once.
In your code, you have again initialized your module.
(function () {
//initialization
var app = angular.module('sbi', []);
app.controller('PanelController', function () {
this.tab = 1;
this.selectTab = function (setTab) {
this.tab = setTab;
};
this.isSelected = function (checkTab) {
return this.tab === checkTab;
};
});
})();
(function ($scope) {
//edit in your code
//re-using the already initialized module
var app = angular.module('sbi');
function MyCtrl($scope) {
$scope.reset = function () {
$scope.requiredField = '';
};
};
});
You should not pass the second argument as parameter.
Reusing your angular module
var app = angular.module('sbi');
EDIT :
Try the following code :
(function () {
var app = angular.module('sbi', []);
app.controller('PanelController', ['$scope', function($scope) {
$scope.tab = 1;
$scope.selectTab = function (setTab) {
$scope.tab = setTab;
};
$scope.isSelected = function (checkTab) {
return $scope.tab === checkTab;
};
$scope.reset = function () {
$scope.requiredField = '';
};
}]);
})();
There is something you are clearly missing here: your reset function is attached to... nothing.
The MyCtrl function is never called (from what we've seen), and the $scope variable is not injected the Angular-way. Actually, nothing here is in the Angular way. Let me try to adjust this so you understand what you should aim for.
First of all, as #Akshay mentioned, there is a huge difference between angular.module('something', []) and angular.module('something'), but they already pointed that out in their response.
Then, your MyCtrl hasn't been registered as a controller in Angular. You just defined the function, you were missing these lines:
var app = angular.module('sbi');
function MyCtrl($scope) {
$scope.reset = function () {
$scope.requiredField = '';
};
};
// This controller will be known as 'MyCtrl'
app.controller('MyCtrl', MyCtrl);
This should work. Note that you won't be needing the surrounding (function ($scope) {...}) as it won't be executed correctly.
Then, you will have to tell Angular to use that controller in that specific part of your page:
<!-- Adding the ng-controller directive here -->
<form name="form" ng-controller="MyCtrl">
...
<button class="btn btn-wide btn-default.active.focus" data-ng-click="reset()">Pulisci</button>
</form>
Then, you will be able to handle your requiredField variable as you wish.

Open/close div toggle and click outside div

This post looks like duplicate, but I think is not. Now you can click Show box and show red box, if you want close this box, click outside.
Question: How close this red box on click again Show box text except click outside. And how change css style after click e.g. change font-size Show box after click
var myApplication = angular.module('myApp', []);
myApplication.directive('hideLogin', function($document){
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('click', function(e) {
e.stopPropagation();
});
$document.bind('click', function() {
scope.$apply(attr.hideLogin);
})
}
}
});
myApplication.controller('hideContainer',function ($scope){
$scope.openLogin = function(){
$scope.userLogin = true;
};
$scope.hideLoginContainer = function(){
$scope.userLogin = false;
};
});
body {
position:relative;
}
.loginBox {
z-index:10;
background:red;
width:100px;
height:80px;
padding:10px;
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<body ng-app="myApp" ng-controller="hideContainer">
Show box
<div hide-login="hideLoginContainer()" class="loginBox" ng-show="userLogin" style="display:none;">
</div>
</body>
To be able to hide the box on click on it, use $scope.userLogin = !$scope.userLogin condition.
To change it's css style, e.g. font-size, use ng-class. If userLogin variable is true, it will add fontSize class into it, changing it's font-size.
var myApplication = angular.module('myApp', []);
myApplication.directive('hideLogin', function($document) {
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('click', function(e) {
e.stopPropagation();
});
$document.bind('click', function() {
scope.$apply(attr.hideLogin);
})
}
}
});
myApplication.controller('hideContainer', function($scope) {
$scope.openLogin = function() {
$scope.userLogin = !$scope.userLogin;
};
$scope.hideLoginContainer = function() {
$scope.userLogin = false;
};
});
body {
position: relative;
}
.loginBox {
z-index: 10;
background: red;
width: 100px;
height: 80px;
padding: 10px;
position: absolute;
}
.fontSize {
font-size: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<body ng-app="myApp" ng-controller="hideContainer">
Show box
<div hide-login="hideLoginContainer()" class="loginBox" ng-show="userLogin" style="display:none;">
</div>
</body>
instead of using multiple $scope for achieve something like this you can use a single $scope variable, take look at code snippet.
var myApplication = angular.module('myApp', []);
myApplication.directive('hideLogin', function($document){
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('click', function(e) {
e.stopPropagation();
});
$document.bind('click', function() {
scope.$apply(attr.hideLogin);
})
}
}
});
myApplication.controller('hideContainer',function ($scope){
$scope.userLogin = true;
$scope.hideLoginContainer = function(){
$scope.userLogin = true;
};
});
body
{
position:relative;
}
.loginBox
{
z-index:10;
background:red;
width:100px;
height:80px;
padding:10px;
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<body ng-app="myApp" ng-controller="hideContainer">
Show box
<div hide-login="hideLoginContainer()" class="loginBox" ng-show="!userLogin" style="display:none;">
</div>
</body>
You could rename openLogin() to toggleLogin() and change the function accordingly to
$scope.toggleLogin = function(){
$scope.userLogin != $scope.userLogin;
};
That will toggle the box when you click on the link.
For the CSS part, use ng-class to conditionaly sign a class to the element if userLogin ==true
<div ng-class="{'myConditionalClass':userLogin }"></div>

Controller in Nested views of AngularJS

Iam new to AngularJS and was stuck at the concept of angular nested views with single controller. Gone through some examples here, which didn't help me. Below is the code from a question and I need 2 things here. After clicking on submit:
1.The date selected has to be assigned as input and url has to be constructed based on the date selected and the result from that url has to be displayed in Modal.
2.At the same time a table(present in tab-submit.html) has to displayed in the page(in tab.html) below the submit button from another URL.
Below is the code I have in app.js:
wc.controller('MyController', function ($scope, $modal, $log, $http, $location, $filter) {
var that = this;
var in10Days = new Date();
in10Days.setDate(in10Days.getDate() + 10);
$scope.dates = {
date3: " "
};
this.dates = {
date3: new Date()
};
this.open = {
date3: false
};
// Disable weekend selection
this.disabled = function (date, mode) {
return (mode === 'day' && (new Date().toDateString() == date.toDateString()));
};
this.dateOptions = {
showWeeks: false,
startingDay: 1
};
this.timeOptions = {
readonlyInput: false,
showMeridian: false
};
this.dateModeOptions = {
minMode: 'year',
maxMode: 'year'
};
this.openCalendar = function (e, date) {
that.open[date] = true;
};
$scope.format = 'yyyy-MM-dd%20HH:mm';
debugger;
$scope.open = function () {
var date = $filter("date")($scope.dates.date3, $scope.format);
$http.get(http://myurlPartA+date+"myurlPartB")
.success(function (response) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return response;
}
}
});
});
};
});
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
Here is a plunker:http://plnkr.co/edit/xKbkFGoa3p5y5NAzueut?p=preview. Is it possible to get solution for my question??Hope anyone will help me to understand this.
Thanks in advance!!
Requirements
1. Have a page with two tabs
2. If click the tab1, should load the page with date picker and a submit button
3. After selecting a date picker I will click the submit button
4. Then from a url I should get the data for particular date which I have selected.
5. There will be two api calls, one for modal and one for table
6. Then modal should show up with the data
7. After closing the modal, table should below the submit button
As I understood from your discussion, I think this is what you wanted to do.
Have a page with two tabs
If click the tab1, should load the page with date picker and a submit button
After selecting a date picker I will click the submit button
Then from a url I should get the data for particular date which I have selected.
There will be two api calls, one for modal and one for table
Then modal should show up with the data
After closing the modal, table should below the submit button
I saw few issues in your codes.
Some issues in Directive, the way you use
Getting data from api
How you open and close the modal
How you print data in table
I have a updated, working Plunker here.
Please find the below code changes. In the codes you are getting the codes for Modal. but I dont know how you will bind it. Please change it as you want.
index.html
<!DOCTYPE html>
<html>
<head>
<style>
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: inline-block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
background-color: darkgrey;
}
</style>
<link rel="stylesheet" type="text/css" href="jquery.datetimepicker.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.datetimepicker.full.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<script src="ui-bootstrap-tpls.js"></script>
<script src="datetime-picker.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<script src="application.js"></script>
</head>
<body ng-app="wc">
<ul>
<li><a ui-sref="tab">Tab1</a></li>
<li><a ui-sref="tabs">Tab2</a></li>
</ul>
<div class="container">
<div ui-view></div>
</div>
</body>
</html>
application.js
var wc = angular.module('wc', ['ui.router','ui.bootstrap', 'ui.bootstrap.datetimepicker']);
wc.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/posts');
$stateProvider
.state('tab', {
url: '/tab1',
templateUrl: 'tab.html'
})
.state('tabs', {
url: '/tabs',
templateUrl: 'tabs.html',
});
});
wc.controller('SampleController', function ($scope, $http, $modal) {
$scope.subt_click = function () {
//Selected Date is here use as you want
//$scope.mydate
alert($scope.mydate);
//Modal Data
$http.get("http://jsonplaceholder.typicode.com/posts")
.success( function(response) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalController',
resolve: {
items: function () {
return response;
}
}
});
});
//Table Data
$http.get("http://jsonplaceholder.typicode.com/posts")
.success( function(response) {
$scope.tableData = response;
});
};
});
wc.controller('ModalController', function ($scope, $modalInstance, items) {
$scope.modalData = items;
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
wc.directive('datetimepicker', function () {
return {
require: 'ngModel',
link: function (scope, el, attr, ngModel) {
$(el).datetimepicker({
onSelect: function (dateText) {
scope.$apply(function () {
ngModel.$setViewValue(dateText);
});
}
});
}
};
});
Tab.html
<div class="jumbotron text-top" ng-controller="SampleController">
<h4>Select from below:</h4>
<form class="form-horizontal">
<input datetimepicker="" ng-model="mydate" type="text" readonly-input="true" />
<a class="btn btn-info" ng-click="subt_click()">Submit</a>
</form>
<div class="table-responsive" ng-show="tableData.length > 0">
<table class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr>
<th>ID</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in tableData">
<td>{{x.id}}</td>
<td>{{x.body}}</td>
</tr>
</tbody>
</table>
</div>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>Info</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="x in modalData">
{{ x.id + '-' + x.title}}
</li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
</script>
$stateProvider is best used for navigating to an entirely different page in your app . For modals , dom animations ect .. This should be put in a directive .
Example
wc.directive('modal', function(){
return {
restrict: "A",
template: 'modal.html' // FYI the html for the actual modal popup
link: function(scope,elem,attrs){
$(".modal").show();
}
}
})
for instance ; in your modal.html would contain something like this
<div class="modal" style="display:none;">
</div>
then in your main document
<div modal></div>
//Or you can place this on whatever element you desire to show the modal

Allowing user to type only positive numbers in input box using angularjs

I want to allow the user to enter only positive numbers in the textbox
My code is as follows:
script.js file contents:
angular.module("myfapp", []).controller("HelloController", function($scope) {
$scope.helloTo = {};
$scope.helloTo.title = "AngularJS";
});
angular.module('myApp', []).controller('MainCtrl', function($scope) {
app.directive('validNumber', function() {
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function(val) {
var clean = val.replace(/[^0-9]+/g, '');
if (val !== clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
});
element.bind('keypress', function(event) {
if (event.keyCode === 32) {
event.preventDefault();
}
});
}
};
});
});
angular.html contents as follows:
<html>
<head>
<script src="angular.min.js"></script>
<script src="script.js"></script>
<style>
.entry {
width: 300px;
margin: 10px auto;
text-align: center;
}
</style>
</head>
<body ng-app="myfapp">
<div ng-controller="HelloController" >
<h2 class="entry">Welcome {{ helloTo.title }} to the world of Tutorialspoint!</h2>
</div>
<section ng-app="myApp" ng-controller="MainCtrl">
<h4 class="entry">AngularJS Numeric Value Widget</h4>
<div class="well entry">
<label>Employee Age
<input type="text" ng-model="employee.age" placeholder="Enter an age" valid-number/>
</label>
</div>
</section>
</body>
</html>
Why does it not work?
Can anyone run it and check please!
Change your input type to number, then you can use min directive to specify the minimum number allowed.
<input type="number" ng-model="employee.age" placeholder="Enter an age" min="0"/>
There are a lot of problems with your code.
you've nested ng-app which is not allowed normally, use a single ng-app with multiple ng-controller.
your need to use restrict inside your directive to restrict its usage to one or multiple types (i.e. A=Attribute,E=Element,C=Class), like in this case restrict: "A"
When specifying a controller its generally a good practice to use array with the last element being the controller function and the first ones being all the services factories you are using in string format
#MajidYaghouti's suggestion is good to use ng-change but if you insist on using directives I have done some bit of corrections to your code.
Use some code formatting dude, and name your stuff cautiously and elegantly.
your script.js
angular.module("myfapp", []).controller("HelloController", ["$scope", function($scope) {
$scope.helloTo = {};
$scope.helloTo.title = "AngularJS";
}])
.controller('MainCtrl', ["$scope", function($scope) {
}])
.directive('validNumber', function() {
return {
restrict: "A",
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function(val) {
if (val === null)
return;
var myRegex = /\d+\.(\d{1,2})?/;
var clean = myRegex.exec(val)[0];
if (val != clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
});
element.bind('keypress', function(event) {
if (event.keyCode === 32) {
event.preventDefault();
}
});
}
};
});
and your index.html
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<script src="script.js"></script>
<style>
.entry {
width: 300px;
margin: 10px auto;
text-align: center;
}
</style>
</head>
<body ng-app="myfapp">
<div ng-controller="HelloController" >
<h2 class="entry">Welcome {{ helloTo.title }} to the world of Tutorialspoint!</h2>
</div>
<section ng-controller="MainCtrl">
<h4 class="entry">AngularJS Numeric Value Widget</h4>
<div class="well entry">
<label>Employee Age
<input type="text" ng-model="employee.age" placeholder="Enter an age" valid-number/>
</label>
<div>
{{ employee.age }}
</div>
</div>
</section>
</body>
</html>
updated plunkr

Issue with multiple child HTML elements using Directives in AngularJS

I'm using a template to create a popup menu that will show alerts if there is a new one and it's working till now. But i wanted to add manual alert, that's why i thought to add an input text but Oupss, i can't write on the input field and i don't even know why.The input field is sort of Disabled!!!
My directive is like so :
$scope.tb = { x: 0, y: 0 };
module.directive('myDraggable', function ($document, $interval) {
return {
restrict: 'EA',
replace: true,
//scope : true,
scope: { menu: '=drSrc'},
link: function (scope, element, attr) {
var startX = 0, startY = 0, x = scope.menu.x || 0, y = scope.menu.y || 0, positionX = [], positionY = [], time = [], width, height, moveInterval;
element.draggable({
position: 'relative',
cursor: 'pointer',
top: y + 'px',
left: x + 'px'
});
element.on('mousedown', function (event) {
// Prevent default dragging of selected content
event.preventDefault();
startX = event.pageX - x;
startY = event.pageY - y;
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
$interval.cancel(moveInterval);
});
function mousemove(event) {
y = event.pageY - startY;
x = event.pageX - startX;
//calculate the borders of the document
width = $(document).width() - 350;
height = $(document).height() - 150;
positionX.push(x);
positionY.push(y);
time.push(Date.now());
}
}
}
});
I tried to make scope true but i faced 2 problems, :
I can't move my popup anymore (yes my popup menu is Draggable)
And Also the input text does not show my text i'm typing.
Here's my cache template :
$templateCache.put('control.tpl.html', '<div class="container" my-draggable dr-src="tb"><div><div class="col-sm-1 col-md-1 sidebar"><div class="list-group" ><span href="#" class="list-group-item active" >Manage<input type="text" class="pull-right" placeholder="Type..." /></span><div ng-repeat="Alert in Alerts"><a href="#" ng-click="showLocation(Alert.id)" class="list-group-item" >Alert {{Alert.id}}</span><img src="../images/alert_icon_manage.png" class="pull-right"/> </a></div><span href="#" class="list-group-item active"></span></div></div></div></div>');
I'm new with AngularJS and Directive and I don't know how to solve this but I think it's a problem with Scopes!!
Thank you.
UPDATE :
If I delete scope:{menu:"=drSrc"} That work and i can type what i want but the problem is that my element is no more draggable.
I think it's sth related to scopes. can anyone help please?
scope: true indicates that your directive should inherit its parent's scope, but scope: {menu: '=drSrc'} creates an isolated scope, which remove your template's access to Alerts. When you remove scope: {menu: '=drSrc'}, menu no longer exists, so scope.menu.x fails and your element is no longer draggable.
The simplest fix is to use scope: true and reference scope.drSrc.x, etc. instead of scope.menu.x. With scope: true, you get access to the parent's scope, including drSrc and the Alerts data your template is using.
These writeups are useful in understanding directives and scopes:
Angular's directive docs
Understanding Scopes
What is the difference between '#' and '=' in directive scope
I'm currently working on a project that depends heavily upon Modal Dialogs. Each with their own purpose and dynamic content.
Here's the system I have been working with:
index.html
<!doctype html>
<html ng-app="myApp" ng-controller="MainCtrl">
<head>
<title>Dialogs</title>
<link rel="stylesheet" href="app.css">
</head>
<body>
<button ng-click="openDialog()">Open Dialog</button>
<modal-dialog show="showMe" dialog-controller="WelcomeDialogCtrl" context="welcome"></modal-dialog>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
var app = angular.module('myApp', []);
// The main controller, which will handle index.html
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.showMe = false;
$scope.openDialog = function(){
$scope.showMe = true; // Show the 'welcome' dialog
};
}]);
// The modal dialog directive
app.directive('modalDialog', [function() {
return {
controller: '#', // Bind a controller
name: 'dialogController', // Bind the controller to this attribute name
restrict: 'E',
scope: {
show: '='
},
link: function(scope, element, attrs) {
// Close this dialog (actually ng-hides it)
scope.closeDialog = function() {
scope.show = false;
};
},
templateUrl: function(element, attrs){
// I prefer to load my dialog templates from a separate folder to keep my project tidy
return 'dialogs/' + attrs.context + '.html';
}
};
}]);
// The 'welcome' dialog has its own controller with its own scope
app.controller('WelcomeDialogCtrl', ['$scope', function($scope){
// This can be called by the template that resides within the directive
$scope.exampleFunction = function(text){
console.log('Example function says: ' + text);
};
}]);
welcome.html
<div class="dialog" ng-show="show">
<div class="dialog-overlay"></div>
<div class="dialog-box">
Welcome, be sure to check out this blazin' dialog.
<button ng-click="exampleFunction('Hi!')">Say Hi!</button>
<button ng-click="closeDialog()">Close</button>
</div>
</div>
app.css
body{
background: #eee;
margin: 80px;
}
/*
* Just some fancy schmuck
*/
button{
border-radius: 5px;
background: #272;
color: #fff;
padding: 5px 12px;
border: 0;
}
/*
* The grey, transparent curtain.
*/
.dialog-overlay {
width: 100%;
height: 100%;
position: absolute;
background: #111;
opacity: 0.2;
top: 0;
left: 0;
z-index: 100;
}
/*
* The dialog itself. Horribly centered.
*/
.dialog-box{
background: #fff;
border-radius: 5px;
padding: 10px 20px;
position: absolute;
width: 600px;
height: 300px;
top: 50%;
left: 50%;
margin-left: -300px;
z-index: 110;
}
I also made a Plunker with the same code.

Categories