angularJS hide bootstrap datepicker on icon click - javascript

in my app i try to use bootstrap datepicker
but i have one trouble: how to hide it on icon and some other field (if i will need) when it's is displayed?
my view:
<div class="input-group date custom">
<input type="text" id="date" data-ng-model="article.Date" name="date" class="form-control" required/><span class="input-group-addon"><i class="date-ico"></i></span>
</div>
and directive (it's declaration is on modal window):
.directive('dateClick', function ($window) {
return {
restrict: 'EA',
link: function (scope, element, attrs) {
var dateIcon = element.find('.date-icon');
dateIcon.bind('click', function () {
var datepckr = angular.element(document).find('.datepicker');
if (typeof datepckr[0] !== 'undefined'){
console.log('hide');
var datepckrMenu = angular.element(document).find('.datepicker.dropdown-menu');
datepckrMenu.datepicker('hide');
}
});
}
}
});
how could i hide my datepicker in the best way?
also i see that it didn't hide if i click in textAngular's editor...

you can try it me be it's help...
Live Demo
github Link
<div>
<div data-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>
</div>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/2.0.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://rawgit.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.css">
<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>
Js Script
app = angular.module 'myapp', ['ng-bootstrap-datepicker']
AppCtrl = ($scope)->
$scope.datepickerOptions =
format: 'yyyy-mm-dd'
language: 'fr'
autoclose: true
weekStart: 0
$scope.date = '2000-03-12'
app.controller 'AppCtrl', AppCtrl
angular.bootstrap document, ['myapp']

Related

(Angular + Bootstrap) How to stop two datepickers from being opened by the same button

I have a web page that needs two datepickers, start date and end date. The problem is, whenever I click on the glyph to open the date selector, both date picker opens at the same time.
Here is my Template, Directive, Controller and how it's being used. Any help would be much appreciated.
Template:
<div class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="dd/MM/yyyy" ng-model="start_date" is-open="popup.opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
Directive:
'use strict';
/*global angular*/
angular.module("myApp")
.directive("datepicker", function(){
return{
templateUrl: 'templates/datePicker.html',
controller: 'newDateCtrl',
replace: true
};
});
Controller
/*global angular*/
angular.module("myApp").controller("newDateCtrl", function($scope) {
$scope.popup = {
opened: false
};
$scope.open = function() {
$scope.popup.opened = true;
};
$scope.dateOptions = {
formatYear: 'yy',
maxDate: new Date(2020, 5, 22),
minDate: new Date(),
startingDay: 1
};
})
index.html, as part of a form like this:
....
<div class="form-group">
<label class="control-label col-sm-2">
Start Date
</label>
<div class="col-sm-10">
<datepicker></datepicker>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">
End Date
</label>
<div class="col-sm-10">
<datepicker></datepicker>
</div>
</div>
....
Two things:
- when declaring your directive, use an isolate scope.
i.e.
.directive('...', function() {
return {
.... // your existing stuff
scope: {} // this gives each directive instance isolated scope
}
});
I think also 'datepicker' is the name of the bootstrap directive already, so if you're wrapping it you should consider giving it a different name.

Angular UI datepicker validated as false when empty

I'm using the JqueryUI datepicker(1.0.0) directive with Angular 1.4.9 to display a date of birth. This field is not required and should not be validated unless it's filled.
Once the page loads, the field is validated as true(As expected). And once the user selects a date, it's again valid. But if we were to manually erase the field, the field becomes invalid.
<input ui-date="dateOptions" name="dateOfBirth" ng-model="dob"/>
ng-model can be set to the same value before and after, but the value remains invalid.
I've created a JSFiddle that replicates the problem here.
https://jsfiddle.net/nipuna777/ctsmuv80/
As said #nipuna777, it looks like a bug in the datepicker.
We can fix it with a directive.
Live example on jsfiddle.
var myApp = angular.module('myApp', ['ui.date']);
myApp.directive('uiDateFix', function($timeout) {
return {
restrict: "A",
require: 'ngModel',
priority: 100,
scope: {
ngRequired: "="
},
link: function(scope, elem, attr, ngModel) {
var originalValidate = null;
$timeout(function() {
if (!originalValidate)
originalValidate = ngModel.$validators.uiDateValidator;
ngModel.$validators.uiDateValidator = function uiDateValidator2(modelValue, viewValue) {
//Define correct validations
if (viewValue || scope.ngRequired)
return originalValidate(modelValue, viewValue);
else
return true;
}
}, 500);
}
}
});
//myApp.factory('myService', function() {});
myApp.controller('MyCtrl', function($scope) {
$scope.name = 'Superhero';
$scope.value = 'Superhero';
$scope.dateOptions = {
changeYear: true,
changeMonth: true,
yearRange: '1900:-0'
};
$scope.isReq = true;
$scope.dob = ""
})
<script src="https://code.jquery.com/jquery-2.2.1.js" charset="utf-8"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-date/1.0.0/date.js" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
<body ng-app="myApp">
<div ng-controller="MyCtrl">
<h1> Datepicker</h1>
<form name="person">
<label for="dateOfBirth">Date of Birth: </label>
<input ui-date="dateOptions" name="dateOfBirth" ng-model="dob" ui-date-fix ng-required="isReq" />
<label for="isReq">Required </label>
<input type="checkbox" name="isReq" ng-model="isReq" />
<p>
dob value: {{dob}}
</p>
<p>
dob valid: {{person.dateOfBirth.$valid}}
</p>
<p>
dob errors: {{person.dateOfBirth.$error}}
</p>
<hr>
<h2>Recreating the problem</h2>
<ol>
<li>With the field empty dob is valid</li>
<li>When you select a value from datepicker again the dob field is valid</li>
<li>When dob is manually removed, the field becomes invalid</li>
</ol>
</form>
</div>
</body>
It is an issue in the validator of the plugin, it is fixed in the master branch/dist/date.js.
So you can use that file instead of the one in the cdn to fix it

Angular templates

I'd like to know if this :
<field>
<input type="text" value="" />
<error>ERROR !!!</error>
</field>
is transformable into this :
<!-- field directive is transformed into div.field-container -->
<div class="field-container">
<div class="field">
<!-- input here -->
<input type="text" value="" />
</div>
<div class="error">
<!-- error directive is transformed into span -->
<span>ERROR !!!</span>
</div>
</div>
Thanks
You can make use of angular directives to achieve that:
var app = angular.module('myapp', []);
app.directive('errorDirective', function() {
return {
restrict: 'E',
replace: 'true',
template: '<div class="error"><span>ERROR !!!</span></div>'
};
});
Here is a working example: http://jsfiddle.net/fLddpk75/
Documentation: https://docs.angularjs.org/guide/directive

AngularJS ng-repeat - jquery Datepicker not working inside ng-repeat

jQuery datepicker not working inside a AngularJS ng-repeat block.
Not sure if anything wrong in code generation inside ng-repeat block. The same logic works outside ng-repeat.
Working code
<div class="form-group">
<label class="control-label col-md-4">TEST DATE</label>
<div class="input-group col-md-2">
<input type="text" id="testDate" name="testDate" readonly="readonly" class="form-control">
</div>
</div>
Not working code
<div ng-repeat="reportType in reportTypes">
<div class="form-group">
<label class="control-label col-md-4">{{reportType.reportTypeLabel}}</label>
<div class="input-group col-md-2">
<input type="text" id="{{reportType.reportTypeCodeId}}Date" readonly="readonly"
class="form-control">
</div>
</div>
</div>
Javascript
// Date picker dd/mm/yyyy
$(function() {
$("input[id*='date']").datepicker({
dateFormat : "dd/mm/yy"
});
});
$(function() {
$("input[id*='Date']").datepicker({
dateFormat : "dd/mm/yy"
});
});
Use this directive to initialize the datepicker after ng-repeat ends:
angular.module('mymodule').directive('ngOnFinishRender', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit(attr.broadcastEventName ? attr.broadcastEventName : 'ngRepeatFinished');
});
}
}
};
});
In your controller:
$scope.$on('ngRepeatFinished', function(){
$("input[id*='date']").datepicker({
dateFormat : "dd/mm/yy"
});
});
In your view, add the directive ng-on-finish-render to element with ng-repeat:
<div ng-repeat="reportType in reportTypes" ng-on-finish-render>
<div class="form-group">
<label class="control-label col-md-4">{{reportType.reportTypeLabel}}</label>
<div class="input-group col-md-2">
<input type="text" id="{{reportType.reportTypeCodeId}}Date" readonly="readonly"
class="form-control">
</div>
</div>
</div>
You can add broadcast-event-name="myNgRepeatFinished" parameter if you have more than one ng-repeat in your scope and they have different purposes
$scope.$on('myNgRepeatFinished', function(){
$("input[id*='date']").datepicker({
dateFormat : "dd/mm/yy"
});
});
You have to create a custom directive for the datepicker.
The View
<div ng-app="myApp" ng-controller="myController">
<div ng-repeat="report in repArray">
<div class="form-group">
<label>{{report.values.name}}</label>
<input type="text" datepicker ng-model="datevalue" />
</div>
</div>
The Directive
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function ($scope) {
$scope.report = [
{ 'name': 'rep1' },
{ 'name': 'rep2' },
{ 'name': 'rep3' }
]
$scope.repArray = Object.keys($scope.report)
.map(function (value, index) {
return { values: $scope.report[value] }
}
);
} ]);
myApp.directive("datepicker", function () {
function link(scope, element, attrs, controller) {
element.datepicker({
dateFormat: "dd/mm/yy"
});
}
return {
require: 'ngModel',
link: link
};
});

Strange behaviour using angular-ui-bootstrap date inside an angular-ui-modal

I am developing my first app using Angular and I can't see what's wrong.
I have used ui-bootstrap date with no issues in other places but then I tried using it inside a modal and whenever you pick a date inside the modal for the first time it works properly but then if you pick the wrong date and want to pick the correct one clicking the button to open the calendar a second time it doesn't work if it's inside the modal.
I have created a plunker sample where the error is reproduced.
Code fragments follows:
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link data-require="bootstrap-css#3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link data-require="bootstrap-theme#3.2.0" data-semver="3.2.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" />
<script data-require="angular.js#1.3.0-beta.5" data-semver="1.2.21" src="https://code.angularjs.org/1.2.21/angular.js"></script>
<script data-require="angular-ui-bootstrap#0.11.0" data-semver="0.11.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<h1>Angular ui date!</h1>
<div ng-controller="DateController">
<div class="row">
<div class="col-md-6">
<h4>Date(This works)</h4>
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" disabled
ng-model="activityDate" is-open="opened" datepicker-options="dateOptions"
ng-required="true" close-text="Close"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i
class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button type="button" class="btn btn-primary" ng-click="openModal()">Open Date Modal</button>
</div>
</div>
</div>
dateModal.html
<div>
<div class="modal-header">
<h3 class="modal-title">Date Modal Sample</h3>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<h4>Modal Date(works only the first time! whyyyyyy?????)</h4>
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" disabled
ng-model="dateModal" is-open="opened"
ng-required="true" close-text="Close"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</div>
app.js
'use strict';
(function () {
var myApp = angular.module('myApp', ['ui.bootstrap']);
myApp.controller('DateController', ['$scope', '$modal', '$log', function($scope, $modal, $log){
//Initializes date
$scope.today = function () {
$scope.activityDate = new Date();
};
//open calendar to select initial date
$scope.open = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
$log.info('open function was called');
};
$scope.today();
$scope.format = 'MM/dd/yyyy';
//open modal window
$scope.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'dateModal.html',
controller: 'DateModalController'
});
}
}]);
myApp.controller('DateModalController', ['$scope', '$modalInstance', function($scope, $modalInstance){
$scope.cancel = function () {
$modalInstance.dismiss('Cancel');
};
//Initializes date
$scope.today = function () {
$scope.dateModal = new Date();
};
//open calendar to select initial date
$scope.open = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
$log.info('open button from modal calendar field has been pressed!!!!');
};
$scope.today();
$scope.format = 'MM/dd/yyyy';
}]);
})();
Scopes inherit from their parent scopes.
The modal is created as a child of the scope that you passed in when initalising it (or on the $rootScope by default). When attempting to set a property directly on the scope, angular will automatically create it for you. However, if you try doing model.myProperty, if model doesn't exist on the child scope, it will travel up to the parent and correctly set it there (if it exists).
A good description on how scopes work can be found here: https://github.com/angular/angular.js/wiki/Understanding-Scopes
Here is a working sample without having to resort to using $parent.
http://plnkr.co/edit/WeJqirLDOoFuTqJEHEdg
<input type="text" class="form-control" datepicker-popup="{{format}}" disabled
ng-model="dateModal.date" is-open="dateModal.opened"
ng-required="true" close-text="Close"/>
Pretty sure it's related to the modal's scope overriding your scope and $scope.opened in the directive. I'm not sure the exact cause but you can work around it by using is-open="$parent.opened" in your dateModal template.

Categories

Resources