How to create directive for this date picker example? - javascript

I am new for angularjs here i created some sample for date-picker, which is working fine. I want to create a directive for this sample.. i tried its working but after selected the date it show format is not define...
for this sample i need a directive.. any of one help me on this...
thanks
var app = angular.module('myapp', ['ng-bootstrap-datepicker']);
app.controller('AppCtrl', function ($scope) {
$scope.datepickerOptions = {
format: 'yyyy-mm-dd',
language: 'en',
autoclose: true,
weekStart: 0
};
$scope.date = '2000-03-12'
});
var appboot = angular.bootstrap(document, ['myapp']);
<link href="https://rawgit.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.css" rel="stylesheet"/>
<link href="http://netdna.bootstrapcdn.com/bootstrap/2.0.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery-2.0.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/2.0.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="https://rawgithub.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.js" charset="utf-8"></script>
<div ng-app="myapp" ng-controller="AppCtrl">
<input id="datepicker" type="text" data-ng-datepicker data-ng-options="datepickerOptions" data-ng-model="date">
<input id="datepickerMirror" type="text" data-ng-model="date">
</div>

If you can use a more modern datepicker (along with its dependencies on a new AngularJS & Bootstrap), below is an example of a very simple directive called my-datepicker, which just takes a date attribute as its model and wraps the uib-datepicker-popup functionality.
angular.module('myApp', ['ui.bootstrap'])
.directive('myDatepicker', function() {
return {
restrict: 'E',
scope: {
date: '='
},
templateUrl: 'partials/my-datepicker.html',
link: function(scope, element, attrs) {
scope.status = {
opened: false
};
scope.open = function(event) {
scope.status.opened = true;
};
}
};
})
.controller('AppCtrl', ['$scope', function ($scope) {
$scope.date = '2000-03-12';
}]);
.input-group {
width: 200px;
}
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.js"></script>
<div ng-app="myApp" ng-controller="AppCtrl">
<script type="text/ng-template" id="partials/my-datepicker.html">
<div class="input-group">
<input class="form-control" type="text" uib-datepicker-popup ng-model="date"
is-open="status.opened">
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)">
<span class="glyphicon glyphicon-calendar"></span>
</button>
</span>
</div>
</script>
<div class="container">
<my-datepicker date="date"></my-datepicker>
</div>
<input id="datepickerMirror" type="text" ng-model="date">
</div>
Note that the date model gets passed into your directive will be used as the ng-model for the actual uib-datepicker-popup; you can confirm this by selecting a date via the directive and seeing that the other input (outside of your directive) gets updated.
You can also move your directive's template (partials/my-datepicker.html) into its own file, rather than embedding it as a text/ng-template.
EDIT #2
As requested, below is an example using the ng-bootstrap-datepicker directive. Note the use of controller: ... instead of link: ... to set the datepickerOptions model; this is to make sure the update to our directive's scope is available when linking occurs (i.e. when the actual ng-bootstrap-datepicker directive is being initialized):
angular.module('myapp', ['ng-bootstrap-datepicker'])
.directive('myDatepicker', function() {
return {
restrict: 'E',
template: '<input type="text" ng-datepicker ng-options="datepickerOptions" ng-model="date">',
scope: {
date: '='
},
controller: function($scope) {
$scope.datepickerOptions = {
format: 'yyyy-mm-dd',
language: 'en',
autoclose: true,
weekStart: 0
};
}
};
})
.controller('AppCtrl', ['$scope', function ($scope) {
$scope.date = '2000-03-12'
}]);
angular.bootstrap(document, ['myapp']);
<link href="https://rawgit.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.css" rel="stylesheet"/>
<link href="http://netdna.bootstrapcdn.com/bootstrap/2.0.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery-2.0.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/2.0.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="https://rawgithub.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.js" charset="utf-8"></script>
<div ng-app="myapp" ng-controller="AppCtrl">
<my-datepicker date="date"></my-datepicker>
<input id="datepickerMirror" type="text" data-ng-model="date">
</div>
The angular-bootstrap-datepicker directive doesn't look to be compatible with the latest AngularJS/Bootstrap versions, so the example above uses the same from the OP's snippet.

Related

Add mdKeyBoard to javascript added element

JSfiddle
I am trying to add mdKeyBoard to dynamically created element, It works for textarea present in DOM, but not for the one which added through javascript.
Tried to $compile also still of no use.
var myApp = angular.module('myApp', ['ngAria', 'ngAnimate', 'ngMaterial', 'material.components.keyboard']);
myApp.controller('MyCtrl', function($scope,$compile) {
setTimeout(function () {
$compile(angular.element(document.getElementById('idTextArea')))($scope);
}, 1000);
});
//JS-library
var textarea = document.createElement('textarea');
textarea.setAttribute('autocapitalize', 'off');
textarea.setAttribute('use-keyboard', 'US International');
textarea.setAttribute('id', 'fabricTextArea');
document.getElementById('myDiv').appendChild(textarea);
<link href="https://cdn.rawgit.com/davidenke/angular-material-keyboard/9365d06c/dist/mdKeyboard.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.4/angular-material.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.4/angular-material.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-aria.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-messages.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-sanitize.js"></script>
<script src="https://cdn.rawgit.com/davidenke/angular-material-keyboard/9365d06c/dist/mdKeyboard.js"></script>
<div id="myDiv" ng-app="myApp" ng-controller="MyCtrl">
<md-input-container>
<textarea type="text" id='text_tool' aria-label='demo'
use-keyboard='US International'
ng-model="WBCtrl.textFieldValue">
</textarea>
</md-input-container>
</div>
The use of setTimeout is a code smell, a symptom of a more fundamental problem. In AngularJS DOM manipulation should be done in directives. Avoid doing DOM manipulation in controllers.
To dynamically add elements in AngularJS use the ng-if directive:
<textarea ng-if="addTextarea" autocapitalize='off'
use-keyboard='US International' ng-model="fabricValue"
id='fabricTextArea' >
</textarea>
In the controller, use $scope.addTextarea=true to have the AngularJS framework dynamically add the element.
The DEMO
The use-keyboard directive needs the ngModelController which is instantiated by the ng-model directive.
var myApp = angular.module('myApp', ['ngAria', 'ngAnimate', 'ngMaterial', 'material.components.keyboard']);
myApp.controller('MyCtrl', function($scope,$compile) {
setTimeout(function () {
$compile(angular.element(document.getElementById('fabricTextArea')))($scope);
}, 1000);
});
//JS-library
var textarea = document.createElement('textarea');
textarea.setAttribute('autocapitalize', 'off');
textarea.setAttribute('use-keyboard', 'US International');
textarea.setAttribute('id', 'fabricTextArea');
textarea.setAttribute('ng-model', 'xxx');
document.getElementById('myDiv').appendChild(textarea);
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Material+Icons">
<link href="//unpkg.com/angular-material-keyboard/dist/mdKeyboard.css" rel="stylesheet"/>
<link href="//unpkg.com/angular-material/angular-material.css" rel="stylesheet"/>
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/angular-material/angular-material.js"></script>
<script src="//unpkg.com/angular-animate/angular-animate.js"></script>
<script src="//unpkg.com/angular-aria/angular-aria.js"></script>
<script src="//unpkg.com/angular-messages/angular-messages.js"></script>
<script src="//unpkg.com/angular-sanitize/angular-sanitize.js"></script>
<script src="//unpkg.com/angular-material-keyboard/dist/mdKeyboard.js"></script>
<div id="myDiv" ng-app="myApp" ng-controller="MyCtrl">
<md-input-container>
<textarea type="text" id='text_tool' aria-label='demo'
use-keyboard='US International'
ng-model="WBCtrl.textFieldValue">
</textarea>
</md-input-container>
</div>

Use a different angular controller for bootstrap modal

I'm calling for the bootstrap modal HTML file from my main HTML file here is an example code of what I'm doing. Link
<div class="container" ng-controller="MainAngularControler"> <!--The main div with the controller in it-->
As it shows can anyone suggest a way to call another Angular controller for bootstrap modal. because the button that calls for the modal to load is in a div which already has an angular controller, this doesn't let the modal to load another different angular controller. The idea behind all these is to make my code more understandable.
When creating the modal instance in your angular controller you need to pass the modal controller like this.
var modalInstance = $uibModal.open({
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
size: "lg",
controller: 'modalController'
});
Have a look at this plunker or the code below.
var app = angular.module('plunker', ["ui.bootstrap"]);
app.controller('MainCtrl', function($scope, $uibModal) {
$scope.name = 'World';
$scope.OpenModal = function(){
var modalInstance = $uibModal.open({
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
size: "lg",
controller: 'modalController'
});
modalInstance.result.then(function (selectedItem) {
//$ctrl.selected = selectedItem;
}, function () {
//$log.info('Modal dismissed at: ' + new Date());
});
};
});
app.controller('modalController', function($scope){
$scope.text = 'I am from modal controller SCOPE';
});
<!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 src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title" id="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body" id="modal-body">
THIS IS A MODAL. {{text}}
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="$ctrl.cancel()">Cancel</button>
</div>
</script>
<a ng-click="OpenModal()">Open Modal</a>
</body>
</html>

Dynamically added element id is null

I'm new to angularJS. When I click a button it will show a dialog, the dialog's html code is:
<img id="imgId" ng-src="{{imgSrc}}">
In controller, when I try to access imgId using JavaScript it showing null. Same with the JQuery.
console.log(document.getElementById('imgId')); // null
Here is my code:
angular.module('BlankApp', ['ngMaterial']).
controller('mainController', function($scope, $mdDialog) {
$scope.showCustomDialog = function(ev) {
$mdDialog.show({
controller: DialogController,
template: '{{hello}}<img id="imgId" ng-src="{{imgSrc}}">',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true
});
function DialogController($scope, $timeout) {
$scope.hello = "Hello World";
$scope.imgSrc = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcScku8D7qo2hWD-eqb_WKTVjMjjiJFLo7uDQQ4RZWRNw9TJ-j7nYg";
$timeout(function() {
console.log(document.getElementById('imgId'));
console.log(angular.element(document.getElementById('imgId')));
});
}
}
});
<html lang="en">
<head>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
</head>
<body ng-app="BlankApp" ng-controller="mainController" ng-cloak>
<md-button ng-click="showCustomDialog($event)" class="md-primary">Show Dialog</md-button>
<!-- Angular Material requires Angular.js Libraries -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>
</body>
</html>
(plunker)
You need to give the dialog a chance to render, before you can get a reference to it.
Wrap the getElementById calls in a $timeout:
$timeout(function(){
console.log(document.getElementById('imgId'));
console.log(angular.element(document.getElementById('imgId')));
});
Keep in mind that you need to include the $timeout in your controller:
function DialogController($scope, $timeout) {
Here's a working example using your plunker's code:
angular.module('BlankApp', ['ngMaterial']).
controller('mainController', function($scope, $mdDialog) {
$scope.showCustomDialog = function(ev) {
$mdDialog.show({
controller: DialogController,
template: '{{hello}}<img id="imgId" ng-src="{{imgSrc}}">',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true
});
function DialogController($scope, $timeout) {
$scope.hello = "Hello World";
$scope.imgSrc = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcScku8D7qo2hWD-eqb_WKTVjMjjiJFLo7uDQQ4RZWRNw9TJ-j7nYg";
$timeout(function() {
console.log(document.getElementById('imgId'));
console.log(angular.element(document.getElementById('imgId')));
});
}
}
});
<html lang="en">
<head>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
</head>
<body ng-app="BlankApp" ng-controller="mainController" ng-cloak>
<md-button ng-click="showCustomDialog($event)" class="md-primary">Show Dialog</md-button>
<!-- Angular Material requires Angular.js Libraries -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>
</body>
</html>

ng-if blocking the directive methods

I have a directive for Opentoke Library but it's not working when I am using the ng-if, the reason of using ng-if is for IOS devices webrtc is not supported so it's showing alert after DOM load.
<div class="opentok" ng-if="!isMobileView">
<open-tok-archive></open-tok-archive>
</div>
click me
<div class="opentok" ng-if="!isMobileView">
<open-toke-screen-share></open-toke-screen-share>
</div>
without ng-if every thing is working fine.
Direcitve
'use strict';
var session, apiKey, publisher, openTokToken, archiveID;
angular.module('app')
.directive('openTokArchiv', [function () {
return {
restrict: 'EA',
templateUrl: 'views/pages/openTokArchive.html',
controller: function (OpenTokService, OTSession, $window, $rootScope, $scope, $routeParams, $cookieStore) {
$scope.myMethod = function (){
console.log("---------not-- working ---------")
}
};
}]);
Use ng-show/ng-hide instead of ng-if.
EDITS
<div class="opentok" ng-if="!isMobileView">
<open-tok-archive></open-tok-archive>
</div>
Have a look at this plunker Demo link
Try this without ng-if #working
<!DOCTYPE html>
<html>
<head>
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="myCtrl" ng-init="variables">
<div class="opentok">
<open-tok-archive></open-tok-archive>
</div>
<button type="button" ng-click="myMethod()">Toggle</button>
</body>
</html>
With ng-if it is not working
<body ng-app="app" ng-controller="myCtrl" ng-init="variables">
<div class="opentok" ng-if="!isMobileView">
<open-tok-archive></open-tok-archive>
</div>
<button type="button" ng-click="myMethod()">Toggle</button>
</body>

how to create a directive with select and button

I have created a directive which should be able to call a function in a controller and use a variable in controller and directive.
I can not figure out how to call the callback.
I can not figure out to enable two way data binding on my directive scope variable.
Here is the plnk: http://plnkr.co/edit/T1bMYUnkPeZmHHd05SCI?p=preview
html
<!DOCTYPE html>
<html data-ng-app="App">
<head>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body data-ng-controller="BodyCtrl">
<h1>{{title}}</h1>
<div class="container">
<div class="dateselector" data-ng-select="select" data-ng-refresh="refresh()"></div>
</div>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.13/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.13/angular-route.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="script.js"></script>
</body>
</html>
html template
<div class="row">
<div class="col-md-3 col-sm-3">
<select class="form-control" ng-model="select" ng-options="p for p in possibilities"></select>
</div>
<div class="col-md-3 col-sm-3">
<button type="button" class="btn btn-default">Refresh</button>
</div>
</div>
javascript
var app = angular.module('App', ['ui.select']);
app.controller('BodyCtrl', ['$scope', function($scope) {
$scope.title = 'Select Directive';
$scope.select = 1;
$scope.refresh = function() {
alert("Refresh in Controller! " + $scope.select);
};
}]);
// Module
angular.module('ui.select', [])
.directive('dateselector', ['$parse', function($parse) {
var link = function ($scope, $element, $attributes) {
$scope.possibilities = [1,2,3,4,5,6];
$element.find('button').bind('click', function() {
alert('Refresh in directive!');
// How to call callback?
$scope.refresh;
});
};
return {
restrict: 'EC',
replace: true,
templateUrl: 'template.html',
scope: {
select: "=",
refresh: "&"
},
link: link
};
}]);
The basic problem is that your directive expects to see and attribute of the form some-name or data-some-name, but you specify one like this: data-ng-some-name.
Additionally, the recommended way to bind a callback to a button's click event is using ngClick.
<!-- In the VIEW -->
<div class="dateselector" data-select="select" data-refresh="refresh()"></div>
<!-- In the TEMPLATE -->
<button ... ng-click="refresh()">Refresh</button>
See, also, this modified demo.

Categories