Add Bootstrap DateRangePicker in Angular Ui-Grid headerCellTemplate - angularjs

I'm trying to add a bootstrap DateRangePicker on my header template for Angular UI-Grid. I can see that the template is working properly because it shows the Bootstrap Icon. I do not want to use the native angular Type:'date'. I want to use a bootstrap date picker.
I have all the includes needed for this to show up.
<!-- Include Required Prerequisites -->
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"/>
<script type="text/javascript" src="//cdn.jsdelivr.net/momentjs/latest/moment.min.js"/>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap/latest/css/bootstrap.css" />
<!-- Include Date Range Picker -->
<script type="text/javascript" src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"/>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" />
This is my Template HTML
<!-- DatePickerTemplate HTML -->
<script type="text/ng-template" id="DatePickerTemplate.html">
<div ng-controller="DatePickerController">
<div>Sent On</div>
<div class="input-group date" datepicker-popup is-open="true"
ng-model="COL_FIELD" min-date="2010-01-01">
<input class="form-control">
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
</div>
</div>
</script>
This is my UI Grid columnDefinitons:
{ name: 'Sent On', field: 'SentDateTime', enableCellEdit: false,
allowCellFocus: false, type: 'date', cellFilter: 'date:"M-d-yy H:mm"',
headerCellTemplate: 'DatePickerTemplate.html' }
This is my Directive
app.directive("filterDatePicker", function(){
return {
restrict: 'E',
scope: true,
templateUrl: 'DatePickerTemplate.html'
};
});
I have an empty controller at the moment, what I want to do in the controller is get the dates I pick from the BootStrap DateRangePicker once it's working
Controller
app.controller('DatePickerController', [
'$scope', function($scope) {
// return date picked from bootstrap datepicker
}
]);
When I click on the little menu box it doesn't do anything. I'm not getting any errors in the developer console either.
Here is a Plunker, you can see both Date columns, one on the left is native the one on the right should be bootstrap which is not working.
Can someone please give me an idea of where I'm going wrong. I can't get the BootStrap DatePicker to open. I really want to add a DateRangePicker not just a regular Bootstrap Date Picker.
Date Filter Plunker

It works, using the latest versions of Angular (1.5.0), UI-Bootstrap (1.1.2) and UI-Grid (3.1.1) with correction of some mistakes you made. You forgot to inject the ui.bootstrap module into your application and you didn't add the uib-datepicker-popup directive to your HTML input element. Also you haven got direct access to scope from a custom template. You need to prefix grid.appScope to every property/method you want to access in your controller scope:
You can use grid.appScope in your row template to access elements in your controller's scope.
http://ui-grid.info/docs/#/tutorial/317_custom_templates
Otherwise it "works", at least thus far that the popup opens on tab and when you click the button but it won't overlap the headercell which can possibly be solved with CSS, but i'll leave that to you to figure out. Hope this helps. Good luck with your project. Here's a working snippet:
angular.module('App', [
'ui.bootstrap',
'ui.grid'
]);
angular.module('App').controller('Controller', [
'$scope',
function ($scope) {
$scope.gridOptions = {
enableFiltering: true,
columnDefs: [{
field: 'date',
filterHeaderTemplate: 'DatePicker.html'
}]
};
$scope.datePicker = {
opened: false,
open: function () {
$scope.datePicker.opened = true;
}
};
}
]);
#grid {
width: 100%;
height: 250px;
}
<!DOCTYPE html>
<html ng-app="App">
<head>
<meta charset="utf-8" />
<title>Angular 1.5.0</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link type="text/css" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.1.1/ui-grid.css" />
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap-tpls.js"></script>
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.1.1/ui-grid.js"></script>
<script type="text/ng-template" id="DatePicker.html">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup ng-model="grid.appScope.datePicker.value" is-open="grid.appScope.datePicker.opened" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="grid.appScope.datePicker.open()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
</script>
</head>
<body ng-controller="Controller">
<div id="grid" ui-grid="gridOptions"></div>
</body>
</html>

Related

Input value doesn't show inside bootstrap popover

I have a directive to display a bootstrap's popover where user can update some value. The problem is that my value is not visible as an input's value (it's bind, I can edit it). Same value is visible inside the popover just next to the input.
HTML
<div custom-popover popover-html="<div><span>{{costPrice}}</span><input type='text' ng-model='costPrice' /></div>"></div>
JS
$(elem).popover({
trigger: 'manual',
html: true,
content: () => {
var content = $compile(attr.popoverHtml)(scope);
return content;
},
placement: 'bottom'
});
Demo
It's of course some piece of whole project only, but it shows the issue. Any idea of how to make this value visible inside the input?
I think I finally figured out what's the issue.
You are using jquery for pop-over as it's not a good practice to use the jquery code with angular
Here in your case you are using angular and what ng-model does is it continuously watch on the element value and if it's change it calls the digest cycle to update all the values as per the model and vice versa.
So, as you have given the angular code to jquery content function it can cause the angular to stop watching for costPrice which you can see in popover if you implement it by ui-bootstrap popover or any other angular third party popovers then you can see the effects. Here is the code for that,
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<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">
</head>
<body>
<div ng-controller="PopoverDemoCtrl">
<button style="margin:70px;" uib-popover-template="dynamicPopover.templateUrl" popover-placement="bottom-right" popover-title="{{dynamicPopover.title}}"
type="button" class="btn btn-default">Popover With Template</button>
<script type="text/ng-template" id="myPopoverTemplate.html">
<div>{{dynamicPopover.content}}</div>
<div class="form-group">
<label>Popup Title:</label>
<input type="text" ng-model="dynamicPopover.content" class="form-control">
</div>
</script>
<script>
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($scope, $sce) {
$scope.dynamicPopover = {
content: 'Hello, World!',
templateUrl: 'myPopoverTemplate.html',
title: 'Title'
};
});
</script>
</div>
</body>
</html>
So as I said you gave the html with angular code to jquery to handle it and jquery cant handle the angular code so you get the error.
Hopefully this will help :)

js files doesn't load when changing state ui-router

I hope you can help me out or give me a hint to solve my problem.
I am making an app using angularjs and material design lite (css and js).
My problem is that the material design js file doesn't take affect on the partials once the state changes and basically I lost all the functionality that material design library provides me.
this is my code so far
index.html
<!doctype html>
<html ng-app="app">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Appy2go</title>
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700" type="text/css">
<!-- Material Design Lite -->
<script src="dist/js/material.min.js"></script>
<link rel="stylesheet" href="dist/css/material.pink-blue.min.css">
<!-- <script src="https://code.getmdl.io/1.2.0/material.min.js"></script>
<link rel="stylesheet" href="https://code.getmdl.io/1.2.0/material.indigo-pink.min.css"> -->
<!-- Material Design icon font -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.min.js"></script>
<script src="https://cdn.rawgit.com/auth0/angular-storage/master/dist/angular-storage.js"></script>
<script src="https://cdn.rawgit.com/auth0/angular-jwt/master/dist/angular-jwt.js"></script>
<script src="app.js"></script>
<script src="modules/home/home.js"></script>
<script src="modules/signin/signin.js"></script>
<link rel="stylesheet" href="dist/css/style.css">
</head>
<body>
<div id="app-wrapper" ui-view></div>
<!--THIS BUTTON WORKS AS SUPPOSED TO BE-->
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
Button
</button>
</body>
</html>
app.js
angular.module('app',[
'ui.router',
'app.home',
'app.signin'
])
.config(function($urlRouterProvider){
$urlRouterProvider.otherwise('/');
})
.controller('AppController',function($scope){
console.log("ready");
})
home module
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout-icon"></div> <!-- IT SHOULD DISPLAY AN ICON ON SMALL DEVICES -->
<div class="mdl-layout__header-row">
<span class="mdl-layout__title">App Name</span>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout__title">App Name</span>
<nav class="mdl-navigation">
link 1
link 2
link 3
</nav>
</div>
<main class="mdl-layout__content">
<div>Content</div>
<!-- Colored FAB button with ripple -->
<!-- Accent-colored raised button with ripple -->
<!-- THIS BUTTON DOESN'T WORK AS SUPPOSED TO BE -->
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
Button
</button>
</main>
<footer class="mdl-mini-footer">
<div class="mdl-mini-footer__right-section">
<div class="mdl-logo">Appy2go</div>
<ul class="mdl-mini-footer__link-list">
<li>Help</li>
<li>Privacy & Terms</li>
</ul>
</div>
</footer>
</div>
home.js
angular.module('app.home',[
'ui.router'
])
.config(function($stateProvider){
$stateProvider.state('home',{
url:'/',
controller: 'HomeController',
templateUrl: 'modules/home/home.html',
})
})
.controller('HomeController',function($scope,$http){
console.log("Ready");
})
Angular has to know when to look for changes in the variables. If you have non-angular code changing things then you have to tell angular to rerun the digest cycle.
Here's an example where I wrapped the jQuery Dialog function in Angular. I'm having to manually tell Angular to WATCH and APPLY.
app.directive("dialog", function() {
return {
restrict: 'A',
scope: {
dialog:"=",
},
controller: function($scope) {
$scope.$watch("dialog", function(){
if($scope.dialog){
$scope.open();
}else{
$scope.close();
}
});
},
link: {
pre: function(scope, element, attributes) {
scope.open = function() {
element.dialog({
height: attributes.height,
width: attributes.width
});
};
scope.close = function() {
element.dialog("close");
};
},
post: function(scope, element, attributes) {
scope.open();
element.on("dialogclose", function(){
if(scope.dialog){
scope.dialog = false;
scope.$apply();
}
});
}
},
};
});
Rest of the code is here.
https://plnkr.co/edit/myBzYyL2BHOP8CtRpqrr?p=info
Your routing code should be in the first module which is the main module. I feel that's where your problem is, I am not on a PC right now to be able to replicate your code and test. But change that first.

how to bind angularjs controller data to bootstrap popover

In my angularJs app, i am using bootstrap popover and having problem of binding controller data to content of popover.
below is my code.
<ul>
<li ng-repeat="rpt in obj.reports track by rpt.name">
{{rpt.name}}
<span class="glyphicon glyphicon-info-sign"
data-toggle="popover" data-trigger="hover"
title="Driver reports" data-content="rpt.info" popover>
</span>
</li>
</ul>
Please help me how to bind {{rpt.info}} to data-content of popover.
So for making bootstrap work with angular, you could use one of these awesome modules.
Angular Strap
or
Angular UI Boostrap
Angular Strap's modal: http://mgcrea.github.io/angular-strap/#/modals
Angular UI's modal: https://angular-ui.github.io/bootstrap/#/modal
I would use UI Bootstrap (https://angular-ui.github.io/bootstrap/#/top) since it is an Angular app. Here's your code using UI Bootstrap:
var app = angular.module('popoverApp', ['ui.bootstrap']);
app.controller('MainCtrl', function() {
var vm = this;
this.reports = [{
name: 'Report 1',
info: 'this is report 1'
}, {
name: 'Report 2',
info: 'this is report 2'
}, {
name: 'Report 3',
info: 'this is report 3'
}];
});
<!DOCTYPE html>
<html ng-app="popoverApp">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl as obj">
<ul>
<li ng-repeat="rpt in obj.reports track by rpt.name">
{{rpt.name}}
<div class="glyphicon glyphicon-info-sign" uib-popover="{{rpt.info}}" popover-trigger="mouseenter" popover-title="Driver reports" popover-placement="right">
</div>
</li>
</ul>
</body>
</html>

element's "collapse" attribute not working?

I'm trying to build a table as in this JSFiddle which I found here.
I notice lots of elements have a collapse="<boolean>" property and as long as the property is true, you will get a nice collapse animation. I tried finding documentation about the collapse attribute online as well and didn't find anything. However, I also noticed the version of angular is rather outdated (1.0.5 instead of 1.5 that I'm currently using). If I try to replace the reference to angular 1.5, the jsfiddle example also stops working. My question is, assuming collapse is deprecated, how can I reproduce this effect in angular 1.5?
The collapse/uib-collapse directive belongs to the angular-ui-bootstrap library, the documentation can be found here:
https://angular-ui.github.io/bootstrap/#/collapse
There is nothing wrong with the directive when running under Angular 1.5.0:
angular.module('App', [
'ngAnimate',
'ui.bootstrap'
]);
angular.module('App').controller('Controller', [
'$scope',
function ($scope) {
$scope.isCollapsed = false;
}
]);
<!DOCTYPE html>
<html ng-app="App">
<head>
<meta charset="utf-8" />
<title>Angular 1.5.0</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link type="text/css" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular-animate.js"></script>
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap-tpls.js"></script>
<script type="application/javascript" src="app.js"></script>
</head>
<body ng-controller="Controller">
<button type="button" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
<hr>
<div uib-collapse="isCollapsed">
<div class="well well-lg">
Some content
</div>
</div>
</body>
</html>

Broken bindings when using modal dialog in angular

I am using the ngModal modal dialog box directive for my angular application. It's displaying some weird behavior that I don't quite understand. When I attach variables directly to the controller's $scope and reference them in the dialog box, the binding breaks. Changing their values in the dialog has no effect on the variables in the controller. But if I add the variables as properties to an object and then add the object to the $scope it works. In other words, if I do this
$scope.v1 = 1
$scope.v2 = 'abc'
it doesn't work, but if I do
$scope.myData = {
v1: 1,
v2: 'abc'
}
things work fine. What's the deal? You can see a working version of the code here and a broken version here.
If the plunk apps aren't loading for you, here is the code:
html
<!DOCTYPE html>
<html data-ng-app='ngModalDemo'>
<head>
<title>ngQuickDate Demo</title>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="ng-modal.css" media="all" />
<style type='text/css'>
body{font-family:'Helvetica Neue',Helvetica,sans-serif}
h1 { padding: 0; margin: 0; }
.ng-cloak { display: none; }
</style>
</head>
<body>
<div ng-controller='DemoController'>
<modal-dialog show='myData.modalShown' width='500px' dialog-title='Modal Dialog Title' on-close='logClose()'>
<p>This is some html content</p>
<p>
<label for='hello'>Hello:</label>
<input type='text' name='hello' ng-model='myData.hello' />
</p>
<p>
<label for='foo'>Foo:</label>
<input type='text' name='foo' ng-model='myData.foo' />
</p>
<img src='http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg' width='300px'/>
</modal-dialog>
<button ng-click='toggleModal()'>Toggle Modal</button>
<br/>
<br/>
<br/>
<p><strong>Shown?</strong> {{myData.modalShown}}</p>
<p><strong>Hello</strong>: {{myData.hello}}</p>
<p><strong>Foo</strong>: {{myData.foo}}</p>
</div>
<script type="text/javascript" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script type="text/javascript" src="ng-modal.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="controller.js"></script>
</body>
</html>
angular app
app.config(function(ngModalDefaultsProvider) {
return ngModalDefaultsProvider.set({
closeButtonHtml: "<i class='fa fa-times'></i>"
});
});
angular controller
app = angular.module('ngModalDemo')
app.controller('DemoController', function($scope) {
$scope.myData = {
link: "http://google.com",
modalShown: false,
hello: 'world',
foo: 'bar'
}
$scope.logClose = function() {
console.log('close!');
};
$scope.toggleModal = function() {
$scope.myData.modalShown = !$scope.myData.modalShown;
};
});

Resources