<!DOCTYPE html>
<html ng-app="UiGridDatepicker">

  <head>
    <link data-require="bootstrap@*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <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 rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css">
    
    <script data-require="jquery@*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.3.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.js"></script>
    
    <link rel="stylesheet" href="style.css" />
    <script src="app.js"></script>
    <script src="date-text-filter.js"></script>
    <script src="ui-grid-edit-datepicker.js"></script>
  </head>

  <body ng-controller="GridController">
    <div id="grid" ui-grid="gridOptions" ui-grid-edit ui-grid-cellnav ui-grid-move-columns class="grid"></div>
  </body>

</html>
.datepicker-wrapper ul {
    visibility: hidden;
}
var app = angular.module('UiGridDatepicker', [
    'ui.bootstrap',
    'ui.grid',
    'ui.grid.edit',
    'ui.grid.cellNav',
    'ui.grid.moveColumns'
]);

app.controller('GridController', ['$scope', function ($scope) {

    $scope.data = [];

    var generateData = function() {
      for (var i = 0, i_length = 30; i < i_length; i++)   {
          $scope.data.push({
              "firstName": "Cox",
              "lastName": "Carney",
              "company": "Enormo",
              "date": '10/14/2015 02:45:33 AM'
          });
          $scope.data.push({
              "firstName": "Lorraine",
              "lastName": "Wise",
              "company": "Comveyer",
              "date": '10/15/2015 10:52:54 AM'
          });
          $scope.data.push({
              "firstName": "Nancy",
              "lastName": "Waters", 
              "company": "Fuelton",
              "date": '09/09/2014 07:32:11 AM'
          });
      }
    }();

    $scope.gridOptions = {
        enableGridMenu: true,
        data: 'data',
        columnDefs: [  
            { name: 'First Name', field: 'firstName' },
            { name: 'Last Name', field: 'lastName'},
            { name: 'Company', field: 'company' },
            { name: 'Date',
                field: 'date',
                cellFilter: 'textDate:"M/d/yyyy"',
                editableCellTemplate: '<div><form name="inputForm"><div ui-grid-edit-datepicker col-Obj="row" row-field="MODEL_COL_FIELD" ng-class="\'colt\' + col.uid"></div></form></div>'
            }
        ],
        enableCellEditOnFocus: true
    };
}]);
var app = angular.module('UiGridDatepicker');

app.filter('textDate', ['$filter', function ($filter) {
    return function (input, format) {
        var date = new Date(input);
        return $filter('date')(date, format);
    };
}]);
var app = angular.module('UiGridDatepicker');
app.directive("uiTestDateEditor",["$scope",function(scope){
   return {
            restrict: "A",
            scope: {
                ctrlId:"=",
                modelValue: "=",
                minValue: "=",
                isDisabled: "=",
                ctrlObj:"="
            },
            template: "<span></span>",
            controller: function(scope){
              console.log("scope",scope);
            }
        };
}]);
app.directive('uiGridEditDatepicker', ['$timeout', '$document', 'uiGridConstants', 'uiGridEditConstants', function($timeout, $document, uiGridConstants, uiGridEditConstants) {
    return {
        template: function(element, attrs) {
          
            var html = '<div class="datepicker-wrapper" ><input uib-datepicker-popup is-open="isOpen" ng-model="' + attrs.rowField + '" ng-change="changeDate($event)" on-open-focus="false" disabled/></div>';
            console.log("attrs",html);
            return html;
        },
        require: ['?^uiGrid', '?^uiGridRenderContainer'],
        scope: true,
        compile: function() {
            return {
                pre: function($scope, $elm, $attrs) {

                },
                post: function($scope, $elm, $attrs, controllers) {
                  console.log("attrs",$attrs);
                    var setCorrectPosition = function() {
                        var gridElement = $('.ui-grid-viewport');
                        var gridPosition = {
                            width: gridElement.outerWidth(),
                            height: gridElement.outerHeight(),
                            offset: gridElement.offset()
                        };

                        var cellElement = $($elm);
                        var cellPosition = {
                            width: cellElement.outerWidth(),
                            height: cellElement.outerHeight(),
                            offset: cellElement.offset()
                        };

                        var datepickerElement = $('ul', cellElement);
                        var datepickerPosition = {
                            width: datepickerElement.outerWidth(),
                            height: datepickerElement.outerHeight()
                        };
                        var newOffsetValues = {};

                        var isFreeOnRight = (gridPosition.width - (cellPosition.offset.left - gridPosition.offset.left) - cellPosition.width) > datepickerPosition.width;
                        if (isFreeOnRight) {
                            newOffsetValues.left = cellPosition.offset.left + cellPosition.width;
                        } else {
                            newOffsetValues.left = cellPosition.offset.left - datepickerPosition.width;
                        }

                        var freePixelsOnBottom = gridPosition.height - (cellPosition.offset.top - gridPosition.offset.top) - cellPosition.height;
                        var freePixelsOnTop = gridPosition.height - freePixelsOnBottom - cellPosition.height;
                        var requiredPixels = (datepickerPosition.height - cellPosition.height) / 2;
                        if (freePixelsOnBottom >= requiredPixels && freePixelsOnTop >= requiredPixels) {
                            newOffsetValues.top = cellPosition.offset.top - requiredPixels + 10;
                        } else if (freePixelsOnBottom >= requiredPixels && freePixelsOnTop < requiredPixels) {
                            newOffsetValues.top = cellPosition.offset.top - freePixelsOnTop + 10;
                        } else {
                            newOffsetValues.top = gridPosition.height - datepickerPosition.height + gridPosition.offset.top - 20;
                        }

                        datepickerElement.offset(newOffsetValues);
                        datepickerElement.css("visibility", "visible");
                    };

                    $timeout(function() {
                        setCorrectPosition();
                    }, 0);

                    $scope.isOpen = true;

                    var uiGridCtrl = controllers[0];
                    var renderContainerCtrl = controllers[1];

                    var onWindowClick = function (evt) {
                        var classNamed = angular.element(evt.target).attr('class');
                        var inDatepicker = (classNamed.indexOf('datepicker-calendar') > -1);
                        if (!inDatepicker && evt.target.nodeName !== "INPUT") {
                            $scope.stopEdit(evt);
                        }
                    };

                    var onCellClick = function (evt) {
                        console.log('click')
                        angular.element(document.querySelectorAll('.ui-grid-cell-contents')).off('click', onCellClick);
                        $scope.stopEdit(evt);
                    };

                    $scope.changeDate = function (evt) {
                        $scope.stopEdit(evt);
                    };

                    $scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
                        if (uiGridCtrl.grid.api.cellNav) {
                            uiGridCtrl.grid.api.cellNav.on.navigate($scope, function (newRowCol, oldRowCol) {
                                $scope.stopEdit();
                            });
                        } else {
                            angular.element(document.querySelectorAll('.ui-grid-cell-contents')).on('click', onCellClick);
                        }
                        angular.element(window).on('click', onWindowClick);
                    });

                    $scope.$on('$destroy', function () {
                        angular.element(window).off('click', onWindowClick);
                    });

                    $scope.stopEdit = function(evt) {
                        $scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
                    };

                    $elm.on('keydown', function(evt) {
                        switch (evt.keyCode) {
                            case uiGridConstants.keymap.ESC:
                                evt.stopPropagation();
                                $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
                                break;
                        }
                        if (uiGridCtrl && uiGridCtrl.grid.api.cellNav) {
                            evt.uiGridTargetRenderContainerId = renderContainerCtrl.containerId;
                            if (uiGridCtrl.cellNav.handleKeyDown(evt) !== null) {
                                $scope.stopEdit(evt);
                            }
                        } else {
                            switch (evt.keyCode) {
                                case uiGridConstants.keymap.ENTER:
                                case uiGridConstants.keymap.TAB:
                                    evt.stopPropagation();
                                    evt.preventDefault();
                                    $scope.stopEdit(evt);
                                    break;
                            }
                        }
                        return true;
                    });
                }
            };
        }
    };
}]);