Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use bootstrap datepicker inside ng-grid

I'm trying to use bootstrap datepicker (via angulart ui bootstrap) inside an ng-grid.

I'm setting the grid with:

$scope.gridSettings = {
    data: "myData",
    enableCellSelection: true,
    enableRowSelection: false,
    enableCellEditOnFocus: true,
    columnDefs:
        [
            { field: "StartDate", displayName: "Date", 
              editableCellTemplate: '<input type="text" datepicker-popup="dd/MM/yyyy" ng-model="COL_FIELD" />' }
        ]
};

And it works, when I click a cell it changes into a datepicker - but - the calendar popup is clipped by the cell boundaries - this means that I can only see the part of the popup that fits into the cell (the top border)

What do I need to set to allow the datepicker popup to appear above the grid instead of being clipped to the cell?

Update: tried switching from Angular UI bootstrap to angular-strap, now the datepicker works but I have the exact same problem with the timepicker

like image 361
Nir Avatar asked Jan 07 '14 23:01

Nir


2 Answers

Use datepicker-append-to-body=true

$scope.gridSettings = {
data: "myData",
enableCellSelection: true,
enableRowSelection: false,
enableCellEditOnFocus: true,
columnDefs:
    [
        { field: "StartDate", displayName: "Date", 
          editableCellTemplate: '<input type="text" datepicker-popup="dd/MM/yyyy" datepicker-append-to-body=true ng-model="COL_FIELD" />' }
    ]

};

like image 88
lmyers Avatar answered Oct 23 '22 18:10

lmyers


I actually had the same issue and eventually came up with this solution. Seems to be working well. The basic idea here is to hook on the datetimepicker show event (dp.show), detach it from wherever parent it may have, attach it to the body with position=absolute and set its location just below the target element.

Note that the below code is taken from a directive wrapping the bootstrap datetimepicker, however the same solution should apply anywhere as long as you can get a handle on the picker element.

Hope that helps someone :)

function link ($scope, $element, $attrs, ngModelCtrl) {

    ////////////////////////////////////////////////////////////////////////////////
    // the following code handles positioning of the datetimepicker widget
    // just below the target element. This is to avoid the hideous datepicker bug
    // that causes it to be trimmed when its parent has limited height
    // Z.P
    ////////////////////////////////////////////////////////////////////////////////
    $element.on('dp.show', function(e) {

        // get the datetimepciker
        var elem = angular.element('.bootstrap-datetimepicker-widget');

        // detach from parent element and append to body
        angular.element('body').append(elem);

        // get target element
        var target = e.currentTarget || e.delegateTarget || e.target;

        // get bounding rects of parent and element
        var targetRect = angular.element(target)[0].getBoundingClientRect();
        var elemRect = elem[0].getBoundingClientRect();

        // do some math
        var marginTop = 10;
        var center = targetRect.left + (targetRect.width / 2) - (elemRect.width / 2);
        var top = targetRect.bottom + marginTop;

        // position the widget properly just below parent
        elem.css('position', 'absolute');
        elem.css('z-index', '10000000000000');
        elem.css('top', top + 'px');
        elem.css('bottom', 'auto');
        elem.css('left', center + 'px');
    });
}
like image 35
Zacky Pickholz Avatar answered Oct 23 '22 18:10

Zacky Pickholz