Angularjs directive isolated scope properties undefined - angularjs

I am trying to integrate a jQuery control (http://amsul.ca/pickadate.js/) into my angular app using a directive, however within my directive I have an isolated scope but the object type properties are always undefined.
Here is a plunker demonstrating the problem - the minDate and maxDate properties are undefined in the directive scope.
http://plnkr.co/edit/yeYxWy?p=preview
var app = angular.module('plunker', []);
app.controller('default', function($scope) {
$scope.minDate = new Date();
$scope.minDate.addDays(-5);
$scope.maxDate = new Date();
$scope.maxDate.addDays(5);
$scope.format = 'mm/dd/yyyy';
$scope.date = new Date();
$scope.date.addDays(-2);
$scope.onGetDate = function(){
alert($scope.date);
};
});
app.directive('amsulPickadate', function(){
return {
restrict: 'E',
template: '<input id="datepicker" class="form-control" type="text" ng-model="ngModel" value="ngModel">',
scope: {
ngModel: '=',
minDate: '=',
maxDate: '=',
format: '#'
},
link: function(scope){
var pkr = $('#datepicker').pickadate({
select: scope.ngModel,
minDate: scope.minDate,
maxDate: scope.maxDate,
format: scope.format,
container: '#pickadateContainer'
});
}
};
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bootstrap#3.3.1" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<link data-require="pickadate.js#*" data-semver="3.3.0" rel="stylesheet" href="https://rawgithub.com/amsul/pickadate.js/cab638a5cbf6d7b959096ed346d9216370cfb543/lib/themes/default.css" />
<link data-require="pickadate.js#*" data-semver="3.3.0" rel="stylesheet" href="https://rawgithub.com/amsul/pickadate.js/cab638a5cbf6d7b959096ed346d9216370cfb543/lib/themes/default.date.css" />
<link data-require="pickadate.js#*" data-semver="3.3.0" rel="stylesheet" href="https://rawgithub.com/amsul/pickadate.js/cab638a5cbf6d7b959096ed346d9216370cfb543/lib/themes/default.time.css" />
</head>
<body ng-controller="default">
<div style="margin: 100px;">
<amsul-pickadate ng-model="date"
minDate="minDate"
maxDate="maxDate"
format="{{format}}"></amsul-pickadate>
<div id="pickadateContainer"></div>
</div>
<div>
<button class="btn btn-primary" ng-click="onGetDate()">Get Date!</button>
</div>
<script data-require="jquery#2.1.3" data-semver="2.1.3" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script data-require="datejs#*" data-semver="0.1.0" src="//cdnjs.cloudflare.com/ajax/libs/datejs/1.0/date.min.js"></script>
<script data-require="bootstrap#3.3.1" data-semver="3.3.1" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script data-require="pickadate.js#*" data-semver="3.3.0" src="https://rawgithub.com/amsul/pickadate.js/cab638a5cbf6d7b959096ed346d9216370cfb543/lib/picker.js"></script>
<script data-require="pickadate.js#*" data-semver="3.3.0" src="https://rawgithub.com/amsul/pickadate.js/cab638a5cbf6d7b959096ed346d9216370cfb543/lib/picker.date.js"></script>
<script data-require="pickadate.js#*" data-semver="3.3.0" src="https://rawgithub.com/amsul/pickadate.js/cab638a5cbf6d7b959096ed346d9216370cfb543/lib/picker.time.js"></script>
<script data-require="angular.js#1.3.10" data-semver="1.3.10" src="https://code.angularjs.org/1.3.10/angular.js"></script>
<script src="app.js"></script>
<script src="amsulPickadate.js"></script>
</body>
</html>
Anyone have suggestions as to why this is happening?
Thanks

Angular automatically camel-case normalizes the element attributes to match against a directive name and scope properties.
When your scope variable are minDate and maxDate, the attribute names should be respectively min-date and max-date
<amsul-pickadate ng-model="date"
min-date="minDate"
max-date="maxDate"
format="{{format}}"></amsul-pickadate>

Related

Angular ng-confirm-click doesn't work

Could you please explain why my ng-confirm-click doesn't work?
<div ng-controller="MainCtrl" ng-init="show=true;">
<p >Hello {{name}}!</p>
<button ng-show="show" confirmed-click="changes();show=false;" ng-confirm-click="Confirm change?">change</button>
</div>
I need to hide the button.
Here the example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-app = "plunker">
<div ng-controller="MainCtrl" ng-init="show=true;">
<p >Hello {{name}}!</p>
<button ng-show="show" confirmed-click="changes();show=false;" ng-confirm-click="Confirm change?">change</button>
</div>
</body>
</html>
Try this working code,
Inside html:
<div ng-confirm-click="Are you sure to delete this product ?" confirmed-click="deletePost(data.postId)"> <span class="glyphicon glyphicon-trash"></span></div>
In app.js file, put the below code(without any change):
app.directive('ngConfirmClick', [
function(){
return {
link: function (scope, element, attr) {
var msg = attr.ngConfirmClick || "Are you sure?";
var clickAction = attr.confirmedClick;
element.bind('click',function (event) {
if ( window.confirm(msg) ) {
scope.$eval(clickAction)
}
});
}
};
}])
Use scope.$apply instead of scope.$eval and remove unnecessary scope.$apply from controller.
From documentation:
This use of $eval: scope.$eval() seems to be deprecated in favor of scope.$apply to execute a function that uses and modifies the scope, and update the view later.
Plunker

disable specific date dynamically in datepicker

Using AngularJs, I want to dynamically disable particular date of a Datepicker. Here what I have did.
var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('MainCtrl', function($scope, $q) {
$scope.date1 = new Date();
$scope.date2 = new Date();
$scope.date2.setDate($scope.date2.getDate() - 1);
var currentDay = new Date();
$scope.isDateDisabled = function(date, mode) {
/*console.log("date=="+date.getTime());
console.log("currentdate"+$scope.date2.getTime());*/
if (date.getDate() === $scope.date2.getDate()) {
return true;
} else {
return false;
}
};
});
/* Put your css in here */
.padTop {
padding-top: 20px;
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container padTop">
<div>
<div style="display:inline-block; min-height:290px;">
<datepicker ng-model="date1" min-date="minDate" show-weeks="true" date-disabled="isDateDisabled(date,mode)" class="well well-sm"></datepicker>
</div>
<div style="display:inline-block; min-height:290px;">
<datepicker ng-model="date2" min-date="minDate" show-weeks="true" class="well well-sm"></datepicker>
</div>
</div>
<p class="padTop">date1:</p>
<pre>
{{ date1 | date : 'dd/MM/yyyy' }}
{{ date2 | date : 'dd/MM/yyyy' }}
</pre>
</div>
</body>
</html>
It was disabled the date in 1st datepicker, which was selected in second datepicker. But If I change the date in 2nd datepicker It wont be reflected(i.e It wont be disabled in 1st datepicker). Anyway to handle this case?
AFAIK there is no clean way to do this, but the datepicker refreshes when you change your minDate attribute. So if you add this in your controller, it will work...
$scope.$watch("date2", function (newValue, oldValue) {
$scope.minDate= new Date();
$timeout(function () {
$scope.minDate = null;
}, 0);
});

How to get directive's scope value to the controller in angularjs

I have the directive that find the elements height and need to have the same value to the controller from the directive.
I tried the below mentioned code and i could not find the solution, am facing some issues.
Could anyone help me on this?
HTML
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#*" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="controller.js"></script>
</head>
<body ng-app="myModule">
<div myDirective style="height: 300px;" ng-controller="myheight">
{{numvalue()}}
</div>
</body>
</html>
script.js for directive
angular.module('myModule', [])
.directive('myDirective', function($timeout) {
return {
restrict: 'A',
link: function(scope, element) {
scope.height = element.prop('offsetHeight');
scope.width = element.prop('offsetWidth');
}
};
})
;
contoller.js for controller
angular.module('myModule', []).controller("myheight", function($scope){
$scope.numvalue = function(){
$scope.divHeight = $scope.height;
return $scope.divHeight;
}
});
You don't need $scope.numvalue();
Your directive looks fine. Just add it to the html and change code to following.
<div ng-app="myModule">
<div style="height: 300px;" my-directive ng-controller="myHeight">
Getting height {{height}}
</div>
</div>
JSFiddle
--EDIT--
Check the updated fiddle
JSFiddle
just expose a varible of controller to the directive. after compilation process of the directive you can access the scope variable divHeight in your controller.
angular.module('myModule', [])
.directive('myDirective', function($timeout) {
return {
restrict: 'A',
scope:{
divHeight: '='
},
link: function(scope, element) {
scope.divHeight = element.prop('offsetHeight');
scope.width = element.prop('offsetWidth');
}
};
});
HTML
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#*" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="controller.js"></script>
</head>
<body ng-app="myModule">
<div myDirective div-Height="divHeight" style="height: 300px;" ng-controller="myheight">
{{numvalue()}}
</div>
</body>
</html>

How to capture ng-model with the ng-bind?

I'm not able to make the ng-bind="data1" capture the input ng-model="data1" from the widget. By clicking and choosing a date, ng-bind is not capturing the chosen date.
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="http://tarruda.github.com/bootstrap-datetimepicker/assets/css/bootstrap-datetimepicker.min.css">
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.2.27/angular.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://tarruda.github.com/bootstrap-datetimepicker/assets/js/bootstrap-datetimepicker.min.js"></script>
<script type="text/javascript" src="http://tarruda.github.com/bootstrap-datetimepicker/assets/js/bootstrap-datetimepicker.pt-BR.js"></script>
<script type="text/javascript">
var Module = angular.module('myapp', []);
myApp.directive('myapp', function datetimepicker() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
element.datetimepicker({
minView: 2,
autoclose: true,
language: 'pt',
format: 'dd/mm/yyyy',
showMeridian: true,
startView: 2
})
.find('input')
.addClass("form-control");
}
};
});
</script>
</head>
<body ng-app="myapp">
<div id="datetimepicker" class="input-append date" ng-model="data1">
<input ng-model="data1" type="text" datetimepicker></input>
<p ng-bind="data1">
<span class="add-on">
<i data-time-icon="icon-time" data-date-icon="icon-calendar"></i>
</span>
</div>
</body>
</html>
You should not give the same name myapp to your module and your directive.
Nowhere in your html you are using the directive.
Also, a <div> cannot have a ng-model directive, so this line is wrong:
<div id="datetimepicker" class="input-append date" ng-model="data1">
Your problem is that you need to initialize data1 in your controller:
function($scope) {
// Initialization
$scope.data1 = '';
}

How can I move this block of text using a custom Angular directive?

I am trying to move a block of text up or down when arrows are pressed. I am having troubles getting my directive to change its CSS values when the buttons are pressed.
Here is my HTML:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.22/angular.js" data-semver="1.2.22"></script>
<script src="app.js"></script>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script src="subtitle.js"></script>
</head>
<body ng-controller="MainCtrl">
<h1>Move Text up or down</h1>
<subtitle class="sub" pos="position">This will move when buttons are pressed</subtitle>
<br>
Position={{position}}
<br>
<br>
<p style="color:red">Click buttons to move text up or down</p>
<i class="fa fa-chevron-up" ng-click="inc()"></i>
<i class="fa fa-chevron-down" ng-click="dec()"></i>
</body>
</html>
Here is my directive:
angular.module('mSystem')
.directive('subtitle', function () {
"use strict";
var
scope = {
pos: "="
},
restrict = 'AE',
link = function($scope, $element, $attrs){
$scope.$watch('pos', function () {
console.log("position is: "+$scope.pos);
$element.css('{top:'+$scope.pos+'px;position:relative;!important}');
$attrs.style="top:'+$scope.pos+'px;position:relative;!important'";
});
};
return {
scope: scope,
link: link,
restrict: restrict
};
});
and here is my app:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.position=20;
$scope.inc=function(){
$scope.position+=1;
}
$scope.dec=function(){
console.log('subtracted');
$scope.position-=1;
}
});
I have created an angular.js plunker here: http://plnkr.co/o99x2Z
The syntax for changing the CSS is a bit different. Try this:
$element.css('top', $scope.pos + 'px');
Updated plunker
You are passing a string to the $element.css(), use an Object instead:
$element.css({ top: $scope.pos+'px', position: 'relative;!important' });
Plunker

Resources