4

我正在將Eternicode's Bootstrap Datepicker集成到我的應用程序中。我不知道如何將它連接到我的模型,所以我發現了一個指令,使用它從here。現在我的頁面上有日期選擇器,但當點擊輸入字段時它不會保持打開狀態。日期選擇器幾乎立即打開和關閉。如果我點擊相鄰的字段並將選項卡放入日期選擇器字段,它將保持打開狀態,如預期的那樣。我也有問題得到它出現在我想要的地方。當它確實打開時,它是在一些其他元素之下並且不合適。它應該直接在輸入字段下方打開。見下面的截圖。Angular Bootstrap DatePicker指令(Eternicode版本)不會保持打開狀態

misplaced

在我的控制,我有:

$scope.dateOptions = { 
    format: 'dd/mm/yyyy', 
    autoclose: false, 
    clearBtn: true, 
    container: '#datepicker', 
    showOnFocus: true, 
    startDate: new Date(), 
    todayBtn: true, 
    todayHighlight: true, 
    weekStart: 1, 
    zIndexOffset: 5000 
} 
$scope.newPost = { 
    token: $scope.token, 
    post: $scope.post, 
    posts: { 
     twitter: null, 
     facebook: null, 
     linkedin: null 
    }, 
    attachment_url: $scope.attachment_url, 
    media_url: $scope.media_url, 
    services: { 
     twitter: $scope.twitter, 
     facebook: $scope.facebook, 
     linkedin: $scope.linkedin 
    }, 
    dateObject: today, 
    timeObject: today 
}; 

然後在我的指導,我有:

.directive('bDatepicker', function(){ 
    return { 
     require: '?ngModel', 
     restrict: 'A', 
     link: function ($scope, element, attrs, controller) { 
      var updateModel, onblur; 

      if (controller != null) { 

       updateModel = function (event) { 
        element.datepicker('hide'); 
        element.blur(); 
       }; 

       onblur = function() { 
        //we'll update the model in the blur() handler 
        //because it's possible the user put in an invalid date 
        //in the input box directly. 
        //Bootstrap datepicker will have overwritten invalid values 
        //on blur with today's date so we'll stick that in the model. 
        //this assumes that the forceParse option has been left as default(true) 
        //https://github.com/eternicode/bootstrap-datepicker#forceparse 
        var date = element.val(); 
        return $scope.$apply(function() { 
         return controller.$setViewValue(date); 
        }); 
       }; 

       controller.$render = function() { 
        var date = controller.$viewValue; 
        if (angular.isDefined(date) && date != null && angular.isDate(date)) 
        { 
         element.datepicker().data().datepicker.date = date; 
         element.datepicker('setValue'); 
         element.datepicker('update'); 
        } else if (angular.isDefined(date)) { 
         throw new Error('ng-Model value must be a Date object - currently it is a ' + typeof date + ' - use ui-date-format to convert it from a string'); 
        } 
        return controller.$viewValue; 
       }; 
      } 
      return attrs.$observe('bDatepicker', function (value) { 
       var options; 
       options = { }; //<--- insert your own defaults here! 
       if (angular.isObject(value)) { 
        options = value; 
       } 
       if (typeof (value) === "string" && value.length > 0) { 
        options = angular.fromJson(value); 
       } 
       return element.datepicker(options).on('changeDate', updateModel).on('blur', onblur); 
      }) 
     } 
    } 
}); 

最後在我看來,我有:

<input b-datepicker="{{dateOptions}}" ng-model="newPost.dateObject" id="datepicker"> 

我創造了一個小提琴,但我無法讓它正確地工作。我得到一個Uncaught Error: [$injector:modulerr]錯誤,我無法弄清楚如何解決。這裏是鏈接:https://jsfiddle.net/kxge3cqf/

這裏從`social_media_posts.json樣品:

[ 
    { 
     id: 50, 
     company_id: 94, 
     employer_id: 3, 
     post: "testing without attachments", 
     attachment_url: null, 
     twitter: true, 
     facebook: false, 
     linkedin: false, 
     post_date: "Fri, Oct 30, 2015", 
     post_time: " 2:50 PM EDT" 
    }, 
    { 
     total_count: 1 
    } 
] 

這裏是從groups.json樣品:

{ 
    groups: { 
     1: { 
      id: 1, 
      name: "Human Resources", 
      created_at: "2015-10-27T16:23:07.287Z", 
      updated_at: "2015-11-01T16:11:43.329Z", 
      company_id: 94 
     }, 
     2: { 
      id: 2, 
      name: "Marketing", 
      created_at: "2015-11-01T15:32:28.988Z", 
      updated_at: "2015-11-01T16:11:43.354Z", 
      company_id: 94 
     } 
    } 
} 

這裏從contacts.json樣品:

{ 
    contacts: { 
     1: { 
      id: 1, 
      first_name: "Foo", 
      last_name: "Bar", 
      email: "[email protected]", 
      created_at: "2015-10-27T16:24:00.832Z", 
      updated_at: "2015-11-01T16:11:52.426Z", 
      company_id: 94 
     } 
    } 
} 
+0

你能提供一個小提琴嗎? –

+0

我創建了一個小提琴,但我無法讓它正常工作。我收到一個'未捕獲的錯誤:[$ injector:modulerr]'錯誤,我無法弄清楚如何解決。這裏是鏈接:https://jsfiddle.net/kxge3cqf/ – ACIDSTEALTH

+0

@ACIDSTEALTH我在本地環境中複製代碼,並且'[$ injector:modulerr]'似乎是因爲'angular.module('myApp',['ui .bootstrap'])',這裏ui.bootstrap沒有被定義,在從外部鏈接包含它之後,我又得到了'無法加載file:///contacts.json。 '和類似的groups.json和socila_media_posts.json,你可以提供這些文件或虛擬數據。所以我可以研究它。 但是,當我試圖分開偵探部分和它有什麼問題。 –

回答

2

這看起來像是你的問題

$event.stopPropagation(); 

angular.module('peskyDatepicker', ['ui.bootstrap']) 
 
.controller('DatepickerDemoCtrl', ['$scope', 
 
function ($scope) { 
 
    
 
    var vm = this; 
 
    
 
    vm.valuationDate = new Date(); 
 
    vm.valuationDatePickerIsOpen = false; 
 
    vm.opens = []; 
 
    
 
    $scope.$watch(function() { 
 
     return vm.valuationDatePickerIsOpen; 
 
    },function(value){ 
 
     vm.opens.push("valuationDatePickerIsOpen: " + value + " at: " + new Date()); 
 
    }); 
 
    
 
    vm.valuationDatePickerOpen = function ($event) { 
 
    
 
     if ($event) { 
 
      $event.preventDefault(); 
 
      $event.stopPropagation(); // This is the magic 
 
     } 
 
     this.valuationDatePickerIsOpen = true; 
 
    }; 
 
}]);
<!DOCTYPE html> 
 
<html ng-app="peskyDatepicker"> 
 

 
    <head> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.min.js"></script> 
 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" /> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    <script src="script.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <div ng-controller="DatepickerDemoCtrl as vm"> 
 
     <pre>Selected date is: <em>{{vm.valuationDate | date:'fullDate' }}</em> 
 
     </pre> 
 
     <div class="row"> 
 
     <div class="col-md-3"> 
 
      <p class="input-group"> 
 
      <span class="input-group-btn"> 
 
       <button type="button" class="btn btn-default" 
 
         ng-click="vm.valuationDatePickerOpen()"> 
 
       <i class="glyphicon glyphicon-calendar"></i> 
 
       </button> 
 
      </span> 
 
      <input type="text" class="form-control" 
 
        datepicker-popup="mediumDate" 
 
        is-open="vm.valuationDatePickerIsOpen" 
 
        ng-click="vm.valuationDatePickerOpen()" 
 
        ng-model="vm.valuationDate" /> 
 
      <span class="input-group-btn"> 
 
       <button type="button" class="btn btn-default" 
 
         ng-click="vm.valuationDatePickerOpen($event)"> 
 
       <i class="glyphicon glyphicon-calendar"></i> 
 
       </button> 
 
      </span> 
 
      </p> 
 
     </div> 
 
     </div> 
 
     <p class="col-md-3"> 
 
     The left button <em>doesn't</em> work (opens the picker and closes right away).<br /> 
 
     The right button <em>does</em> work (opens the picker and stays open).<br /> 
 
     And it's all down to <code>$event.stopPropagation();</code> - funny huh?</code> 
 
     </p> 
 
     <ul> 
 
     <li ng-repeat="open in vm.opens">{{open}}</li> 
 
     </ul> 
 
    </div> 
 
    </body> 
 

 
</html>

並有一個博客這個問題,也是 http://blog.johnnyreilly.com/2015/05/angular-ui-bootstrap-datepicker-weirdness.html

將嘗試找出什麼在你的代碼中的問題正是,你的時間可以有看看它。

EDIT1

你爲什麼不使用默認類型= 「日期」 像

<input type="date" ng-model="date" value="{{ date | date: 'yyyy/MM/dd' }}" /> 
<br />{{ date | date: 'dd/MM/yyyy' }} 

EDIT2

OK想你的代碼,拿出了只有日期相關的部分,它工作正常。

所以在你的代碼中一定有其他東西在引起這個。 這裏是我試過的代碼,如果有幫助

angular.module('ui.bootstrap.demo', ['ngAnimate']); 
 
angular.module('ui.bootstrap.demo').controller('DatepickerDemoCtrl', function($scope,$filter) { 
 
    $scope.dateOptions = { 
 
     format: 'dd/mm/yyyy', 
 
     autoclose: false, 
 
     clearBtn: true, 
 
     // container: '#datepicker', 
 
     showOnFocus: true, 
 
     startDate: new Date(), 
 
     todayBtn: true, 
 
     todayHighlight: true, 
 
     weekStart: 1, 
 
     zIndexOffset: 5000 
 
    } 
 
}); 
 

 
angular.module('ui.bootstrap.demo').directive('bDatepicker', function() { 
 
    return { 
 
     require: '?ngModel', 
 
     restrict: 'A', 
 
     link: function($scope, element, attrs, controller) { 
 
      var updateModel, onblur; 
 

 
      if (controller != null) { 
 

 
       updateModel = function(event) { 
 
        console.log($scope.dateObject); 
 
        element.datepicker('hide'); 
 
        element.blur(); 
 
       }; 
 

 
       onblur = function() { 
 
        //we'll update the model in the blur() handler 
 
        //because it's possible the user put in an invalid date 
 
        //in the input box directly. 
 
        //Bootstrap datepicker will have overwritten invalid values 
 
        //on blur with today's date so we'll stick that in the model. 
 
        //this assumes that the forceParse option has been left as default(true) 
 
        //https://github.com/eternicode/bootstrap-datepicker#forceparse 
 
        var date = element.val(); 
 
        return $scope.$apply(function() { 
 
         return controller.$setViewValue(date); 
 
        }); 
 
       }; 
 

 
       controller.$render = function() { 
 
        var date = controller.$viewValue; 
 
        if (angular.isDefined(date) && date != null && angular.isDate(date)) { 
 
         // element.datepicker().data().datepicker.date = date; 
 
         element.datepicker('update', date); 
 
         element.datepicker('setValue'); 
 
         element.datepicker('update'); 
 
        } else if (angular.isDefined(date)) { 
 
         throw new Error('ng-Model value must be a Date object - currently it is a ' + typeof date + ' - use ui-date-format to convert it from a string'); 
 
        } 
 
        return controller.$viewValue; 
 
       }; 
 
      } 
 
      return attrs.$observe('bDatepicker', function(value) { 
 
       var options; 
 
       options = {}; //<--- insert your own defaults here! 
 
       if (angular.isObject(value)) { 
 
        options = value; 
 
       } 
 
       if (typeof(value) === "string" && value.length > 0) { 
 
        options = angular.fromJson(value); 
 
       } 
 
       return element.datepicker(options).on('changeDate', updateModel).on('blur', onblur); 
 
      }) 
 
     } 
 
    } 
 
});
<!doctype html> 
 
<html ng-app="ui.bootstrap.demo"> 
 

 
<head> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/js/bootstrap-datepicker.min.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-animate.js"></script> 
 
    <script src="example.js"></script> 
 
    <!-- <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> --> 
 
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.0/css/bootstrap-datepicker.standalone.min.css" rel="stylesheet"> 
 
</head> 
 

 
<body ng-controller="DatepickerDemoCtrl"> 
 
    <input b-datepicker="{{dateOptions}}" ng-model="dateObject" id="datepicker" > 
 
    </br> 
 
    Date: {{dateObject}} 
 
</body> 
 

 
</html>

如果你可以提供一些混帳回購或工作普拉克/撥弄我可以找出究竟是什麼錯。但目前這是我所擁有的。希望它有幫助

+0

我將此標記爲答案,因爲它可以立即解決日期選擇器打開/關閉的問題。我的老闆現在決定採用更簡單的實施方式(日/月/年下拉),所以我沒有機會回去徹底測試解決方案,但是根據我在博客文章和Plunck中看到的內容,我認爲這將足以讓我下次在這個問題上得到解決(這可能很快)。謝謝! – ACIDSTEALTH

+0

@ACIDSTEALTH在回答這個問題時偶然發現了http://amsul.ca/pickadate.js/date/或https://github.com/alongubkin/angular-datepicker(兩者都一樣)我喜歡它是用戶界面,沒有用過這但用戶界面不錯 –

+0

那些都顯得很不舒服。比Bootstrap風格好得多。 – ACIDSTEALTH