Angular UI Bootstrap datepicker malfunctioning - angularjs

I am using Angular Ui Datepicker in my app. Strange thing is happening, may be a bug. The date picker is not functioning (not showing) if there is a child element inside the datepicker element.
In my example below if I put span (or any other) tag inside a tag - where I have put my datepicker - it will not work, but if there is not child element inside of it , it works as expected.
Is this a bug or I am missing something ?
Edit : Created A Fiddle Also
var app = angular.module('app', ['ui.bootstrap']);
app.controller("TestController", function($scope) {
$scope.isOpen = false;
$scope.isOpen2 = false;
$scope.isOpen3 = false;
$scope.popupOptions = {};
});
<link href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="app">
This will show Date picker
<br />
<a href="javascript://" ng-model="deadline2" is-open="isOpen2" ng-click="isOpen2 = !isOpen2" datepicker-popup="popupOptions"> <span> This will not </span>
</a>
<br />
<a href="javascript://"> <span ng-model="deadline2" is-open="isOpen3" datepicker-popup="popupOptions" ng-click="isOpen3 = !isOpen3"> This will also show </span>
</a>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js"></script>

Looks like the datepicker can only be set on the innermost elements. It might be that way by design as I found no examples where datepicker is set on a parent element.
Also, you code works if the datepicker is set on span(or any other child element).
<a href="javascript://">
<span ng-model="deadline" is-open="isOpen" ng-click="isOpen = !isOpen" datepicker-popup="popupOptions">datepicker set on span inside anchor</span>
</a>
Plnkr

Here is an example to use the directive with a bootstrap input, displaying a calendar button
HTML
<p class="input-group">
<input type="text" class="form-control" datetime-picker="dd MMM yyyy HH:mm" ng-model="myDate" is-open="isOpen" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openCalendar($event, prop)"><i class="fa fa-calendar"></i></button>
</span>
</p>
JAVASCRIPT
app.controller('MyController', function() {
var that = this;
this.isOpen = false;
this.openCalendar = function(e) {
e.preventDefault();
e.stopPropagation();
that.isOpen = true;
};
});
See demo : https://github.com/Gillardo/bootstrap-ui-datetime-picker

Related

Angular.js $cookies : not properly saved/loaded

I am trying to use a simple input that can be retrieved by a cookie automatically.
My angular controller is :
<script>
var app = angular.module('mantis', ['ngCookies']);
app.controller('main', function($scope, $cookies) {
$scope.nom = '';
$scope.WriteNom = function () {
$cookies.put('Nom', $scope.nom);
};
$scope.ReadNom = function () {
$scope.nom = $cookies.get('Nom');
return $scope.nom;
};
});
</script>
In my page, I made a div where I can change the variable "nom" flawlessly.
The value should be loaded with ng-init (from cookie)
It changes with ng-model
And it should be saved with ng-click
<div class="container" ng-app="mantis" ng-controller="main">
<!-- Assigné à -->
<div class="col-lg-12">
<div class="input-group" ng-init="nom=ReadNom()">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input id="nom" type="text" class="form-control" name="nom" placeholder="Assigné à (id)" ng-model="nom">
<span class="input-group-btn">
<button class="btn btn-secondary" type="button" ng-click="WriteNom()">Sauvegarder</button>
</span>
</div>
</div>
(...)
And then, somewhere else, i can use "nom" where I need it by using {{nom}}
It's almost working :
The value is properly changed when I type in the input box and I can use it
The cookie is not changed when I click on the button nor it's loaded when I load the page
Remove the return part,
HTML:
<div class="input-group" ng-init="ReadNom()">
Controller:
$scope.ReadNom = function () {
$scope.nom = $cookies.get('Nom');
};
DEMO

Angular UI Bootstrap Datetimepicker with seconds

I want to get bootstrap datetimepicker input value in angularjs controller. I am using following custom directive to achieve this . But i am getting the value is undefined. I have added the code related to html and angular code related to the issue.
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.2/locale/en-gb.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-resource.js"></script>
<div class="form-group">
<div class='input-group date' id='datetimepickerFrom' datetimepicker
ng-model="fromDate" >
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
JS
'use strict';
var App = angular.module('app',['ngResource']);
App.directive('datetimepicker', function(){
return {
require: '?ngModel',
restrict: 'A',
link: function(scope, element, attrs, ngModel){
if(!ngModel) return; // do nothing if no ng-model
ngModel.$render = function(){
element.find('#datetimepickerFrom').val( ngModel.$viewValue || '' );
};
element.datetimepicker({
format : 'YYYY-MM-DD HH:mm:ss'
});
element.on('dp.change', function(){
scope.$apply(read);
});
read();
function read() {
var value = element.find('#datetimepickerFrom').val();
ngModel.$setViewValue(value);
console.log(ngModel.$setViewValue(value));
}
}
};
});
App.controller('myController', ['$scope', function($scope) {
$scope.fromDate = moment();
}]);
I have found a package for you to fix your problem which is in the link.
LINK
Easy way to achieve it follow these below steps
Add this markup.
You need to include the following scripts
//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js
//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.0.1.js
//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css
//cdn.rawgit.com/zhaber/datetimepicker/master/datetimepicker.js
//cdn.rawgit.com/zhaber/datetimepicker/master/datetimepicker.css
Controller will hold the model value in $scope.date which contains the date and time.
Update 1
This control does not support Seconds, I would suggest you to go with Angular UI Bootstrap as below
Include the above references expect last two and use the below markup.
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup is-open="popup1.opened" ng-model="fromDate" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
<div uib-timepicker ng-model="fromTime" ng-change="changed()" hour-step="1" minute-step="1" show-meridian="ismeridian" show-seconds="true"></div>
Add this module as a dependency ui.bootstrap
Use the below code to combine your value
$scope.changed = function () {
var month = $scope.fromDate.getMonth()+1;
var day = $scope.fromDate.getDate();
var year = $scope.fromDate.getFullYear();
var hour = $scope.fromTime.getHours();
if (hour < 10)
hour = "0"+hour;
var min = $scope.fromTime.getMinutes();
if (min < 10)
min = "0"+min;
var sec = $scope.fromTime.getSeconds();
if (sec < 10)
sec = "0"+sec;
//put it all togeter
var dateTimeString = month+'/'+day+'/'+year+' '+hour+':'+min+':'+sec;
$scope.fromDateTime= dateTimeString;
};
Your live ng-model value combined together
fromDateTime:{{fromDateTime |date : 'yyyy-MM-dd HH:mm:ss'}}
So by this if the seconds value is changed only you will get the actual Date Time

Variable not rendering in {{ }} but only in ng-bind

I'm facing a problem in AngularJS and I'm not able to solve it.
I have a simple search bar in my html code :
<html ng-app="webApp">
<body>
<div class="row" ng-controller="IndexController">
<div class="col-lg-6 col-lg-offset-3 text-center">
<form>
<div class="input-group">
<input type="text" class="form-control" id="search_input" placeholder="Search for..." ng-model="search">
<span class="input-group-btn">
<button class="btn btn-default" type="submit" ng-click="research()"><i class="glyphicon glyphicon-search"></i></button>
</span>
</div>
</form>
Search : {{search}}
<span ng-bind="search"></span>
</div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="./static/javascripts/angular/angular.module.js" type="text/javascript"></script>
<script src="./static/javascripts/angular/controllers/index.controller.js" type="text/javascript"></script>
</html>
My module is declared in an external file :
angular.module('webApp', ['ui.bootstrap', 'elasticsearch', 'angular-highlight']);
I have a simple controller which is binding the value from a search bar :
angular.module('webApp').controller('IndexController', IndexController);
function IndexController($scope, $window, $http) {
$scope.search = '';
$scope.research = function(){
console.log($scope.search);
window.location.href = "http://localhost:4000/results?search=" + $scope.search + "&size=20";
};
}
So my problem is that I my variable search is well rendered in the ng-bind directive but not at all between {{ }}. I have no errors in my console.
Would you have an idea why ?
Thank you in advance for your help.
Regards
Be aware of "scope soup". Since you are passing modules into your application, there is a possibility of an non-aliased controller having the same $scope.search variable. I recommend aliasing your controller on the markup [ex. IndexController as IndexCtrl] and in the controller change $scope to a this reference.
Example:
var vm = this; //preference
this.search = '';
this.research = function(){
console.log(vm.search);
window.location.href = "http://localhost:4000/results?search=" + vm.search + "&size=20";
};
Additionally, you would then reference the search variable in your markup like this:
search: {{IndexCtrl.search}}
Depending on you intent, you may also want to inject the $location service into your controller and replace window.location.href(...) with $location.path(...)
Remember that ngBind is for one-way binding where as ngModel is for two-way binding!

Angular UI Bootstrap Popover - How add a close button

I've a table with a popover for every cell as in the follow example:
the call to popover:
<td ng-repeat="i in c.installments" ng-class="{ 'first' : i.first, 'last' : i.last, 'advance' : i.advance.value > 0, 'edited' : i.edited, 'final-installment' : i.last }" popover-trigger="{{ popoverFilter(i) }}" popover-placement="top" popover-title="{{i.id == 0 ? 'Advance' : 'Installment ' + i.id}}" popover-append-to-body="true" popover-template="popoverTemplate(i)" ng-init="payment= i; newpayment= i.amount.rounded_value" >
The popover template:
<script type="text/ng-template" id="editPopoverTemplate.html">
<form name="editPayment">
<h2>{{payment.amount.value|currency:undefined:cents}}</h2>
<div class="form-group" ng-class="{ 'has-error' : editPayment.newpayment.$invalid }">
<label>New value:</label>
<input type="number" name="newpayment" ng-model="newpayment" class="form-control no-spinner" step="1" min="10" required>
<span ng-messages="editPayment.newpayment.$error" class="help-block" role="alert">
<span ng-message="required">The value is mandatory</span>
<span ng-message="min">The value is too low</span>
<span ng-message="max">The value is too hight</span>
</span>
</div>
<div class="btn-group btn-group-justified" role="group">
<div class="btn-group" role="group">
<button class="btn" type="button">Cancel</button>
</div>
<div class="btn-group" role="group">
<button class="btn btn-primary" type="button" ng-disabled="editPayment.$invalid">Save</button>
</div>
</div>
</form>
</script>
working example on plunker
I need to close the popover via a "Cancel" button inside the popover.
It's possible? I need to extend the Angular UI Bootstrap library to do that?
Any help is appreciated.
The solution suggested in the linked answer close the popover when user click inside the popover, or outside the popover, but i need to close it by "close" button inside the popover.
The proper solution using the new popover-is-open attribute, as mentioned by #icfantv below, allows the use of controller scopes. I placed a live example in Codepen, and it goes like this:
app = angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
app.controller(
'myPopoverCtrl', ['$scope',
function($scope) {
// query popover
$scope.myPopover = {
isOpen: false,
templateUrl: 'myPopoverTemplate.html',
open: function open() {
$scope.myPopover.isOpen = true;
$scope.myPopover.data = 'Hello!';
},
close: function close() {
$scope.myPopover.isOpen = false;
}
};
}
]);
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js">
</script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body
ng-app="ui.bootstrap.demo"
class="container">
<button
class="btn btn-danger"
ng-controller="myPopoverCtrl"
popover-template="myPopover.templateUrl"
popover-title="This is a popover"
popover-placement="bottom"
popover-is-open="myPopover.isOpen"
ng-click="myPopover.open()">Click me!</button>
<script type="text/ng-template"
id="myPopoverTemplate.html">
<h2 ng-bind="myPopover.data" />
<button class="btn btn-success"
ng-click="myPopover.close()">Close me!</button>
</script>
</body>
Original answer:
I spent the last two days on this problem, and finally came up with a simple enough hack. This goes on my controller:
$scope.close = function(e) {
el = angular.element(e.target).closest("td"); // `td` is the parent of my clickable
// element, in this case a `span`
$timeout(function() { // need $timeout so we don't conflict with the digest loop
el.children(":first").trigger('close'); // couldn't select the `span` element directly
});
},
Now we set up the close trigger on the provider:
app.config(['$tooltipProvider', function($tooltipProvider){
$tooltipProvider.setTriggers({
'click': 'close', // Clicks now only open the tooltip, 'close' events close it.
});
}]);
And on my custom popover HTML template:
<button type="button"
class="btn btn-sm btn-success pull-right"
ng-click="close($event)">Close</button>
Voila! I can now close the popover through the button!
This solution for several ng-repeat popovers via isOpen field of popover's scope.
angular.module('ui.bootstrap.demo', ['ui.bootstrap']).controller('PopoverDemoCtrl', function ($scope) {
$scope.template = 'myPopoverTemplate.html';
$scope.close = function(e) {
angular.element(e.target).parent().parent().parent().parent().scope().$parent.isOpen = false;
}
});
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.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">
<body ng-app="ui.bootstrap.demo">
<div ng-controller="PopoverDemoCtrl">
<button ng-repeat="item in ['First Popover','Second Popover','Third Popover']" popover-placement='bottom' uib-popover-template="template" popover-title="{{item}}" type="button" class="btn btn-default">{{item}}</button>
<script type="text/ng-template" id="myPopoverTemplate.html">
<div class="form-group">
<button class='btn btn-danger' ng-click='close($event)'>Close Me</button>
</div>
</script>
</div>
</body>
Starting with Angular UI Bootstrap release 0.13.4, we've added the ability to programmatically close tooltips and popovers via the tooltip-is-open or popover-is-open boolean attribute.

How to dynamically create text box when we click on a link using angularjs

I have a problem to show INPUT field when do some action.
I have BUTTON (Click here) as soon as user made a click event on button i wanted to show input field
I have done this by using jQuery.
Can any one help me in Angular.js
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.boxShow = false;
});
</script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
show box
<div ng-show="boxShow">
<textarea rows="4" cols="50">text</textarea>
</div>
</div>
</div>
https://jsfiddle.net/bxwjpmaa/1/
HTML
<div class="btn btn-primary" ng-click="openTextBox();">Click Me To open text box</div>
<div ng-show="openTextBox == true">
<input type="text"/>
</div>
SCRIPT :
$scope.openTextBox = function () {
$scope.openTextBox = true;
}
please don't take scope variables and function names same
example here
$scope.openTextBox = function () {
$scope.openTextBox = true;
}
//this is not correct as per angular documentation because scope.openTextBox name already assigned to scope function,again its assigning scope variable "$scope.openTextBox = true" here u will get errors when ever u clicked div second time" TypeError: boolean is not a function" it will throw this error.so please dont use which is already assigned scope function dont assign scope variable
see this fiddle url : https://jsfiddle.net/veerendrakumarfiddle/bxwjpmaa/2/
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<ol>
<li ng-repeat="element in elements">
<input type="text" ng-model="element.value"/>
</li>
</ol>
<br/>
<b>Click here to add Textbox:</b><br/><input type="button" value="New Item" ng-click="newItem()"/>
<br/>
<br/>
<b>Click here to see ng-model value:</b><br/>
<input type="button" value="submit" ng-click="show(elements)">
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
var counter=0;
$scope.elements = [ {id:counter, value : ''} ];
$scope.newItem = function(){
counter++;
$scope.elements.push( { id:counter,value:''} );
}
$scope.show=function(elements)
{
alert(JSON.stringify(elements));
}
});
</script>
</body>
</html>

Resources