From df6f6e316a1633275f88b4bdd4fb01978fce7572 Mon Sep 17 00:00:00 2001
From: Phil Hughes <me@iamphill.com>
Date: Wed, 4 Jan 2017 13:16:14 +0000
Subject: [PATCH] Replaced more jQuery UI datepickers

---
 app/assets/javascripts/dispatcher.js.es6      |  1 +
 app/assets/javascripts/due_date_select.js.es6 | 49 ++++++++++++++-----
 app/assets/javascripts/gl_dropdown.js         |  6 ++-
 app/assets/javascripts/issuable_form.js       |  3 +-
 .../javascripts/member_expiration_date.js.es6 | 33 +++++++++----
 .../shared/milestones/_form_dates.html.haml   |  3 --
 6 files changed, 70 insertions(+), 25 deletions(-)

diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6
index edec21e3b6..477dbff270 100644
--- a/app/assets/javascripts/dispatcher.js.es6
+++ b/app/assets/javascripts/dispatcher.js.es6
@@ -96,6 +96,7 @@
           break;
         case 'projects:milestones:new':
         case 'projects:milestones:edit':
+        case 'projects:milestones:update':
           new ZenMode();
           new gl.DueDateSelectors();
           new gl.GLForm($('.milestone-form'));
diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js.es6
index 4409f908ee..5397b0aa34 100644
--- a/app/assets/javascripts/due_date_select.js.es6
+++ b/app/assets/javascripts/due_date_select.js.es6
@@ -1,5 +1,6 @@
 /* eslint-disable wrap-iife, func-names, space-before-function-paren, comma-dangle, prefer-template, consistent-return, class-methods-use-this, arrow-body-style, no-unused-vars, no-underscore-dangle, no-new, max-len, no-sequences, no-unused-expressions, no-param-reassign */
 /* global dateFormat */
+/* global Pikaday */
 
 (function(global) {
   class DueDateSelect {
@@ -31,6 +32,10 @@
 
     initGlDropdown() {
       this.$dropdown.glDropdown({
+        opened: () => {
+          const calendar = this.$datePicker.data('pikaday');
+          calendar.show();
+        },
         hidden: () => {
           this.$selectbox.hide();
           this.$value.css('display', '');
@@ -39,25 +44,37 @@
     }
 
     initDatePicker() {
-      this.$datePicker.datepicker({
-        dateFormat: 'yy-mm-dd',
-        defaultDate: $("input[name='" + this.fieldName + "']").val(),
-        altField: "input[name='" + this.fieldName + "']",
-        onSelect: () => {
+      const $dueDateInput = $(`input[name='${this.fieldName}']`);
+
+      const calendar = new Pikaday({
+        field: $dueDateInput.get(0),
+        format: 'yyyy-mm-dd',
+        defaultDate: new Date($dueDateInput.val()),
+        onSelect: (dateText) => {
+          const formattedDate = dateFormat(new Date(dateText), 'yyyy-mm-dd');
+
+          $dueDateInput.val(formattedDate);
+
           if (this.$dropdown.hasClass('js-issue-boards-due-date')) {
-            gl.issueBoards.BoardsStore.detail.issue.dueDate = $(`input[name='${this.fieldName}']`).val();
+            gl.issueBoards.BoardsStore.detail.issue.dueDate = $dueDateInput.val();
             this.updateIssueBoardIssue();
           } else {
-            return this.saveDueDate(true);
+            this.saveDueDate(true);
           }
         }
       });
+
+      this.$datePicker.append(calendar.el);
+      this.$datePicker.data('pikaday', calendar);
     }
 
     initRemoveDueDate() {
       this.$block.on('click', '.js-remove-due-date', (e) => {
+        const calendar = this.$datePicker.data('pikaday');
         e.preventDefault();
 
+        calendar.setDate(null);
+
         if (this.$dropdown.hasClass('js-issue-boards-due-date')) {
           gl.issueBoards.BoardsStore.detail.issue.dueDate = '';
           this.updateIssueBoardIssue();
@@ -154,14 +171,24 @@
     }
 
     initMilestoneDatePicker() {
-      $('.datepicker').datepicker({
-        dateFormat: 'yy-mm-dd'
+      $('.datepicker').each(function() {
+        const $datePicker = $(this);
+        const calendar = new Pikaday({
+          field: $datePicker.get(0),
+          format: 'yyyy-mm-dd',
+          defaultDate: new Date($datePicker.val()),
+          onSelect(dateText) {
+            $datePicker.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
+          }
+        });
+
+        $datePicker.data('pikaday', calendar);
       });
 
       $('.js-clear-due-date,.js-clear-start-date').on('click', (e) => {
         e.preventDefault();
-        const datepicker = $(e.target).siblings('.datepicker');
-        $.datepicker._clearDate(datepicker);
+        const calendar = $(e.target).siblings('.datepicker').data('pikaday');
+        calendar.setDate(null);
       });
     }
 
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index d9101b55c7..77fa662892 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -437,7 +437,7 @@
       }
     };
 
-    GitLabDropdown.prototype.opened = function() {
+    GitLabDropdown.prototype.opened = function(e) {
       var contentHtml;
       this.resetRows();
       this.addArrowKeyEvent();
@@ -457,6 +457,10 @@
         this.positionMenuAbove();
       }
 
+      if (this.options.opened) {
+        this.options.opened.call(this, e);
+      }
+
       return this.dropdown.trigger('shown.gl.dropdown');
     };
 
diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js
index d02e98bf44..423a4e3e40 100644
--- a/app/assets/javascripts/issuable_form.js
+++ b/app/assets/javascripts/issuable_form.js
@@ -40,10 +40,11 @@
         new Pikaday({
           field: $issuableDueDate.get(0),
           format: 'yyyy-mm-dd',
+          defaultDate: new Date($issuableDueDate.val()),
           onSelect: function(dateText) {
             $issuableDueDate.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
           }
-        }).setDate(new Date($issuableDueDate.val()));
+        });
       }
     }
 
diff --git a/app/assets/javascripts/member_expiration_date.js.es6 b/app/assets/javascripts/member_expiration_date.js.es6
index bf6c0ec279..aad84cbeeb 100644
--- a/app/assets/javascripts/member_expiration_date.js.es6
+++ b/app/assets/javascripts/member_expiration_date.js.es6
@@ -1,3 +1,5 @@
+/* global Pikaday */
+/* global dateFormat */
 (() => {
   // Add datepickers to all `js-access-expiration-date` elements. If those elements are
   // children of an element with the `clearable-input` class, and have a sibling
@@ -11,21 +13,34 @@
     }
     const inputs = $(selector);
 
-    inputs.datepicker({
-      dateFormat: 'yy-mm-dd',
-      minDate: 1,
-      onSelect: function onSelect() {
-        $(this).trigger('change');
-        toggleClearInput.call(this);
-      },
+    inputs.each((i, el) => {
+      const $input = $(el);
+
+      const calendar = new Pikaday({
+        field: $input.get(0),
+        format: 'yyyy-mm-dd',
+        minDate: new Date(),
+        defaultDate: new Date($input.val()),
+        onSelect: (dateText) => {
+          $input.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
+
+          $input.trigger('change');
+
+          toggleClearInput.call(this);
+        },
+      });
+
+      $input.data('pikaday', calendar);
     });
 
     inputs.next('.js-clear-input').on('click', function clicked(event) {
       event.preventDefault();
 
       const input = $(this).closest('.clearable-input').find(selector);
-      input.datepicker('setDate', null)
-        .trigger('change');
+      const calendar = input.data('pikaday');
+
+      calendar.setDate(null);
+      input.trigger('change');
       toggleClearInput.call(input);
     });
 
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
index 748b10a129..ed94773ef8 100644
--- a/app/views/shared/milestones/_form_dates.html.haml
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -10,6 +10,3 @@
     .col-sm-10
       = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
       %a.inline.prepend-top-5.js-clear-due-date{ href: "#" } Clear due date
-
-:javascript
-  new gl.DueDateSelectors();
-- 
2.30.9