📜 ⬆️ ⬇️

PickMeUp is a good jQuery datepicker plugin

Problem


Starting work on the next site needed datepicker. The most famous such datepicker is in jQuery UI, but since the jQuery UI was not used in the project, I didn’t want to pull even a part of it, I began to look for a decent alternative.

The requirements are as follows:

The requirements are quite logical, nothing more than natural.
What was my surprise when looking at a dozen two plug-ins, I did not find the right one.

For the curious, immediately a demo of what happened as a result.

The closest to the requirements was the DatePicker .
But he had several drawbacks:

It was possible to solve them one-time, but it was decided to bring to mind, because not the last project, and others can be useful.
')

Bicycle so bicycle


The first thing I wanted to change was to remove the pictures to round the edges. But the pictures in the cells of the table. I removed the cells - almost all the functionality fell off ... But there is no going back!

Then some things were refactored, bug fixes, small features added, bug fixes again, and so on.
It took about two full days, and it was worth it.

What happened


As an example, I cite the code generated by the original DatePicker:

Hidden text
<div class="datepicker" id="datepicker_828" style="display: block; position: relative; width: 196px; height: 148px;"> <div class="datepickerBorderT"></div> <div class="datepickerBorderB"></div> <div class="datepickerBorderL"></div> <div class="datepickerBorderR"></div> <div class="datepickerBorderTL"></div> <div class="datepickerBorderTR"></div> <div class="datepickerBorderBL"></div> <div class="datepickerBorderBR"></div> <div class="datepickerContainer" style="width: 176px; height: 128px;"> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <td> <table cellspacing="0" cellpadding="0" class="datepickerViewYears"> <thead> <tr> <th class="datepickerGoPrev"> <a href="#"> <span></span> </a> </th> <th colspan="6" class="datepickerMonth"> <a href="#"> <span>2002 - 2013</span> </a> </th> <th class="datepickerGoNext"> <a href="#"> <span></span> </a> </th> </tr> <tr class="datepickerDoW"> <th> <span>wk</span> </th> <th> <span>Mo</span> </th> <th> <span>Tu</span> </th> <th> <span>We</span> </th> <th> <span>Th</span> </th> <th> <span>Fr</span> </th> <th> <span>Sa</span> </th> <th> <span>Su</span> </th> </tr> </thead> <tbody class="datepickerMonths"> <tr> <td colspan="2"> <a href="#"> <span>Jan</span> </a> </td> <td colspan="2"> <a href="#"> <span>Feb</span> </a> </td> <td colspan="2"> <a href="#"> <span>Mar</span> </a> </td> <td colspan="2"> <a href="#"> <span>Apr</span> </a> </td> </tr> <tr> <td colspan="2"> <a href="#"> <span>May</span> </a> </td> <td colspan="2"> <a href="#"> <span>Jun</span> </a> </td> <td colspan="2"> <a href="#"> <span>Jul</span> </a> </td> <td colspan="2"> <a href="#"> <span>Aug</span> </a> </td> </tr> <tr> <td colspan="2"> <a href="#"> <span>Sep</span> </a> </td> <td colspan="2"> <a href="#"> <span>Oct</span> </a> </td> <td colspan="2"> <a href="#"> <span>Nov</span> </a> </td> <td colspan="2"> <a href="#"> <span>Dec</span> </a> </td> </tr> </tbody> <tbody class="datepickerDays"> <tr> <th class="datepickerWeek"> <a href="#"> <span>27</span> </a> </th> <td class="datepickerNotInMonth"> <a href="#"> <span>30</span> </a> </td> <td class=""> <a href="#"> <span>1</span> </a> </td> <td class=""> <a href="#"> <span>2</span> </a> </td> <td class=""> <a href="#"> <span>3</span> </a> </td> <td class=""> <a href="#"> <span>4</span> </a> </td> <td class="datepickerSaturday"> <a href="#"> <span>5</span> </a> </td> <td class="datepickerSunday"> <a href="#"> <span>6</span> </a> </td> </tr> <tr> <th class="datepickerWeek"> <a href="#"> <span>28</span> </a> </th> <td class=""> <a href="#"> <span>7</span> </a> </td> <td class=""> <a href="#"> <span>8</span> </a> </td> <td class=""> <a href="#"> <span>9</span> </a> </td> <td class=""> <a href="#"> <span>10</span> </a> </td> <td class=""> <a href="#"> <span>11</span> </a> </td> <td class="datepickerSaturday"> <a href="#"> <span>12</span> </a> </td> <td class="datepickerSunday"> <a href="#"> <span>13</span> </a> </td> </tr> <tr> <th class="datepickerWeek"> <a href="#"> <span>29</span> </a> </th> <td class=""> <a href="#"> <span>14</span> </a> </td> <td class=""> <a href="#"> <span>15</span> </a> </td> <td class=""> <a href="#"> <span>16</span> </a> </td> <td class=""> <a href="#"> <span>17</span> </a> </td> <td class=""> <a href="#"> <span>18</span> </a> </td> <td class="datepickerSaturday"> <a href="#"> <span>19</span> </a> </td> <td class="datepickerSunday"> <a href="#"> <span>20</span> </a> </td> </tr> <tr> <th class="datepickerWeek"> <a href="#"> <span>30</span> </a> </th> <td class=""> <a href="#"> <span>21</span> </a> </td> <td class=""> <a href="#"> <span>22</span> </a> </td> <td class=""> <a href="#"> <span>23</span> </a> </td> <td class=""> <a href="#"> <span>24</span> </a> </td> <td class=""> <a href="#"> <span>25</span> </a> </td> <td class="datepickerSaturday"> <a href="#"> <span>26</span> </a> </td> <td class="datepickerSunday"> <a href="#"> <span>27</span> </a> </td> </tr> <tr> <th class="datepickerWeek"> <a href="#"> <span>31</span> </a> </th> <td class=""> <a href="#"> <span>28</span> </a> </td> <td class=""> <a href="#"> <span>29</span> </a> </td> <td class=""> <a href="#"> <span>30</span> </a> </td> <td class="datepickerSelected"> <a href="#"> <span>31</span> </a> </td> <td class="datepickerNotInMonth"> <a href="#"> <span>1</span> </a> </td> <td class="datepickerNotInMonth datepickerSaturday"> <a href="#"> <span>2</span> </a> </td> <td class="datepickerNotInMonth datepickerSunday"> <a href="#"> <span>3</span> </a> </td> </tr> <tr> <th class="datepickerWeek"> <a href="#"> <span>32</span> </a> </th> <td class="datepickerNotInMonth"> <a href="#"> <span>4</span> </a> </td> <td class="datepickerNotInMonth"> <a href="#"> <span>5</span> </a> </td> <td class="datepickerNotInMonth"> <a href="#"> <span>6</span> </a> </td> <td class="datepickerNotInMonth"> <a href="#"> <span>7</span> </a> </td> <td class="datepickerNotInMonth"> <a href="#"> <span>8</span> </a> </td> <td class="datepickerNotInMonth datepickerSaturday"> <a href="#"> <span>9</span> </a> </td> <td class="datepickerNotInMonth datepickerSunday"> <a href="#"> <span>10</span> </a> </td> </tr> </tbody> <tbody class="datepickerYears"> <tr> <td colspan="2"> <a href="#"> <span>2002</span> </a> </td> <td colspan="2"> <a href="#"> <span>2003</span> </a> </td> <td colspan="2"> <a href="#"> <span>2004</span> </a> </td> <td colspan="2"> <a href="#"> <span>2005</span> </a> </td> </tr> <tr> <td colspan="2"> <a href="#"> <span>2006</span> </a> </td> <td colspan="2"> <a href="#"> <span>2007</span> </a> </td> <td colspan="2"> <a href="#"> <span>2008</span> </a> </td> <td colspan="2"> <a href="#"> <span>2009</span> </a> </td> </tr> <tr> <td colspan="2"> <a href="#"> <span>2010</span> </a> </td> <td colspan="2"> <a href="#"> <span>2011</span> </a> </td> <td colspan="2"> <a href="#"> <span>2012</span> </a> </td> <td colspan="2"> <a href="#"> <span>2013</span> </a> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </div> </div> 

and the code generated by PickMeUp:

Hidden text
 <div class="pickmeup pmu-view-days" style="position: relative; display: inline-block;"> <div class="pmu-instance"> <nav> <div class="pmu-prev pmu-button"></div> <div class="pmu-month pmu-button">November, 2013</div> <div class="pmu-next pmu-button"></div> </nav> <nav class="pmu-day-of-week"> <div>Mo</div> <div>Tu</div> <div>We</div> <div>Th</div> <div>Fr</div> <div>Sa</div> <div>Su</div> </nav> <div class="pmu-months"> <div class="pmu-button">Jan</div> <div class="pmu-button">Feb</div> <div class="pmu-button">Mar</div> <div class="pmu-button">Apr</div> <div class="pmu-button">May</div> <div class="pmu-button">Jun</div> <div class="pmu-button">Jul</div> <div class="pmu-button">Aug</div> <div class="pmu-button">Sep</div> <div class="pmu-button">Oct</div> <div class="pmu-button">Nov</div> <div class="pmu-button">Dec</div> </div> <div class="pmu-days"> <div class="pmu-not-in-month pmu-button">28</div> <div class="pmu-not-in-month pmu-button">29</div> <div class="pmu-not-in-month pmu-button">30</div> <div class="pmu-not-in-month pmu-button">31</div> <div class=" pmu-button">1</div> <div class="pmu-saturday pmu-button">2</div> <div class="pmu-sunday pmu-button">3</div> <div class=" pmu-button">4</div> <div class=" pmu-button">5</div> <div class=" pmu-button">6</div> <div class=" pmu-button">7</div> <div class=" pmu-button">8</div> <div class="pmu-saturday pmu-button">9</div> <div class="pmu-sunday pmu-button">10</div> <div class=" pmu-button">11</div> <div class=" pmu-button">12</div> <div class=" pmu-button">13</div> <div class=" pmu-button">14</div> <div class=" pmu-button">15</div> <div class="pmu-saturday pmu-button">16</div> <div class="pmu-sunday pmu-button">17</div> <div class="pmu-selected pmu-button">18</div> <div class=" pmu-button">19</div> <div class=" pmu-button">20</div> <div class=" pmu-button">21</div> <div class=" pmu-button">22</div> <div class="pmu-saturday pmu-button">23</div> <div class="pmu-sunday pmu-button">24</div> <div class=" pmu-button">25</div> <div class=" pmu-button">26</div> <div class=" pmu-button">27</div> <div class=" pmu-button">28</div> <div class=" pmu-button">29</div> <div class="pmu-saturday pmu-button">30</div> <div class="pmu-not-in-month pmu-sunday pmu-button">1</div> <div class="pmu-not-in-month pmu-button">2</div> <div class="pmu-not-in-month pmu-button">3</div> <div class="pmu-not-in-month pmu-button">4</div> <div class="pmu-not-in-month pmu-button">5</div> <div class="pmu-not-in-month pmu-button">6</div> <div class="pmu-not-in-month pmu-saturday pmu-button">7</div> <div class="pmu-not-in-month pmu-sunday pmu-button">8</div> </div> <div class="pmu-years"> <div class="pmu-button">2007</div> <div class="pmu-button">2008</div> <div class="pmu-button">2009</div> <div class="pmu-button">2010</div> <div class="pmu-button">2011</div> <div class="pmu-button">2012</div> <div class="pmu-button">2013</div> <div class="pmu-button">2014</div> <div class="pmu-button">2015</div> <div class="pmu-button">2016</div> <div class="pmu-button">2017</div> <div class="pmu-button">2018</div> </div> </div> </div> 

The code is not perfect, but much simpler and clearer, and therefore easier to draw it.

What else is new compared to the original:

This is the contents of the scss file:

 $border-radius : .4em; $background : #000; $color : #eee; $color-hover : #88c5eb; $nav-color : $color; $nav-color-hover : $color-hover; $not-in-month : #666; $not-in-month-hover : #999; $disabled : #333; $selected-background : #136a9f; $not-in-month-selected-background : #17384d; $day-of-week : $not-in-month-hover; @mixin display-flex() { display : -ms-flexbox; display : -webkit-flex; display : flex; } .pickmeup { background : $background; border-radius : $border-radius; display : none; position : absolute; * { -moz-box-sizing : border-box; box-sizing : border-box; } .pmu-instance { display : inline-block; height : 13.8em; padding : .5em; text-align : center; width : 15em; .pmu-button { color : $color; cursor : pointer; outline : none; text-decoration : none; } .pmu-button:hover { color : $color-hover; } .pmu-not-in-month { color : $not-in-month; } .pmu-disabled, .pmu-disabled:hover { color : $disabled; cursor : default; } .pmu-selected { background : $selected-background; } .pmu-not-in-month.pmu-selected { background : $not-in-month-selected-background; } nav { @include display-flex(); color : $nav-color; line-height : 2em; *:hover { color : $nav-color-hover; } .pmu-prev, .pmu-next { height : 2em; width : 1em; } .pmu-month { width : 12em; } } .pmu-years, .pmu-months { * { display : inline-block; line-height : 3.6em; width : 3.5em; } } .pmu-day-of-week { color : $day-of-week; cursor : default; } .pmu-day-of-week, .pmu-days { * { display : inline-block; line-height : 1.5em; width : 2em; } } .pmu-day-of-week * { line-height : 1.8em; } } &:not(.pmu-view-days) .pmu-days, &:not(.pmu-view-days) .pmu-day-of-week, &:not(.pmu-view-months) .pmu-months, &:not(.pmu-view-years) .pmu-years { display : none; } } 

Total


The size of the minified plug-in:
* 14.8 KiB JavaScript (4.2 KiB gzip)
* 1.8 KiB CSS (650 B gzip)

In order to simplify the layout, IE10 + is supported, and the current versions of other browsers (if you wish, you can make support for IE9-, but I don’t have that desire, I wrote it first of all for myself).

Demo Repository on GitHub

I sincerely hope that this jQuery plugin will be useful to someone other than me, I will be glad for constructive criticism and pull request.

In the near future, you can embed other localizations, in the bootstrap-datepicker repository there are many different ones.

UPD
We support the tradition of 30 lines.
https://gist.github.com/RubaXa/7547352 , thanks to RubaXa

UPD
In version 2.0.1, the plugin architecture has changed for the better.
Regarding the wishes in the comments:
In version 2.1.0 added new configuration options + several fixes.

Source: https://habr.com/ru/post/202640/


All Articles