Principle and Use of Handcrafted Date Selector xy-date-picker

Posted by somenoise on Fri, 06 Sep 2019 06:10:32 +0200

Recently, I spent almost two weeks of idle time creating a date selection component. Let's see what happens first

It can be said that it is a component that is often used and few people will actively implement it. After all, it still takes a certain amount of time to achieve it. So after normal work, you can try to create some basic component libraries, which can both exercise your basic skills and contribute to the community for the company~

Let's take a look at the usage first. It's recommended File Can interact in real time

Installation Use

There are usually several ways to install

  • npm
npm i xy-ui
  • cdn
<script type="module" src="https://unpkg.com/xy-ui/components/xy-pagination.js"></script>

<!--perhaps-->

<script type="module">
    import 'https://unpkg.com/xy-ui/components/xy-pagination.js'
</script>
  • github

Directly from github Copy the source code.

Use

<xy-date-picker></xy-date-picker>

One label thing, out of the box, is probably the most convenient date selector to use.

Implementation Principle

Here's a brief introduction to how dates are generated

To achieve a month's presentation, there are generally three parts: the previous month, the current month, the next month

To do this, we need to know

1. Last day of previous month
2. The number of days in the current month and the first day of the current month are the days of the week (easy to place)

If the last day of the preceding month is 31 and the first day of the month is Tuesday and the total number of days is 30, the arrangement for this month is determined

day one two three four five six
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3

The first is to get the last day of a month. Usually the number of days of a month is fixed, but February is not fixed. One way to do this is to list February separately and to determine whether it is 29 or 28 by calculating the leap year.

In fact, there is another way that we can take advantage of the fault tolerance mechanism of dates, such as

new Date(2019,2,1) //March 1, 2019
new Date(2019,2,0) //The day before March 1, 2019, the last day of February 2019

Then get the date of the day, that is, the number of days of the month

new Date(2019,2,0).getDate() //28

Then the first day of the month is the day of the week, which is easier

new Date(2019,2,1).getDay() //5, Friday

And then we can combine that information into a month's worth of information

function getDays(year,month){
    const lastdays = new Date(year,month-1,0).getDate();
    const days = new Date(year,month,0).getDate();
    const week = new Date(year,month-1,1).getDay();
    const prev = Array.from({length:week},(el,i)=>(month==0?year-1:year)+'-'+(month==0?12:month-1)+'-'+(lastdays+i-week+1));
    const current = Array.from({length:days},(el,i)=>year+'-'+month+'-'+(i+1));
    const next = Array.from({length:42 - days - week},(el,i)=>(month==12?year+1:year)+'-'+(month==12?1:month+1)+'-'+(i+1));
    return [...prev,...current,...next];
}

Here's a simple console output calendar

The source code is as follows, your little buddy can try it

function renderCalendar(d){ 
        const date = new Date(d||new Date); 
        const year = date.getFullYear(); 
        const month = date.getMonth(); 
        const day = date.getDate(); 
        const lastdays = new Date(year,month,0).getDate(); 
        const days = new Date(year,month+1,0).getDate(); 
        const week = new Date(year,month,1).getDay(); 
        const prev = Array.from({length:week},(el,i)=>([month==0?year-1:year,month==0?12:month,lastdays+i-week+1])); 
        const current = Array.from({length:days},(el,i)=>[year,month+1,i+1]); 
        const next = Array.from({length:42 - days - week},(el,i)=>([month==11?year+1:year,month==11?1:month+2,i+1])); 
        const final = [...prev,...current,...next]; 
        const now = Array.from({length:6},(el,i)=>final.slice(i * 7, i * 7 + 7)); 
        const s = `------------------ 
             ${year+' - '+(month+1+'').padStart(2,0)} 
%c------------------ 
| Su | Mo | Tu | We | Th | Fr | Sa | 
------------------ 
%c${now.map(el=>el.map(m=>(m[2]==1?'%c':'')+'| '+((m[2]+'').padStart(2,' ')+' ')).join('')+'|\n------------------\n').join('')} 
        ` 
        console.clear(); 
        console.log(s,"font-weight:bold;color:blue","color:#999","color:#000","color:#999") 
    }

The above is the principle of date generation, which further enables date switching, radio selection, range selection and other functions.

attribute

xy-date-picker defines the following attributes for wider use in combination.

Default value defaultvalue

You can specify an initial date default value to the date selector, which is a valid timestamp string, DataString, and defaults to the current date.

Supports strings like the following for reference Date.parse()

"2019-2-28"
"2019-02-28"
"2019/2/28"
"2019,2,28"
"2019 2 28"
"Feb 28 2019"
//...other date formats
//These all represent February 28, 2019.
<xy-date-picker defaultvalue="2019-2-28"></xy-date-picker>

Type type

Supports setting date selection type, choosing date (default), month, year to implement date selector, month selector, and year selector respectively.

<xy-date-picker></xy-date-picker>
<xy-date-picker type="month"></xy-date-picker>
<xy-date-picker type="year"></xy-date-picker>

Value value, date

Sets or returns the value property value of the date selector.The value is a date of the current type in the form 2019-10-10.

Returns the standard date format for a date, which can be converted to a date in any format.

//value
"2019-08-31"
//date
"Sat Aug 31 2019 14:54:05 GMT+0800 (China Standard Time)"

It can be set or obtained through JavaScript.

date.value; //Obtain
date.date; //Obtain
date.value = '2019-10-10';
//Native attribute operation
date.getAttribute('value');
date.getAttribute('date');
date.setAttribute('value','2019-10-10');

Minimum min, maximum max

Set date selection range, out of range is not optional, format with defaultvalue.

<xy-date-picker min="2019-8-20" max="2019-12-21"></xy-date-picker>
<xy-date-picker type="month" min="2019-5" max="2019-12"></xy-date-picker>
<xy-date-picker type="year" min="2018" max="2050"></xy-date-picker>

Disable disabled

Disabled disables the date selector and cannot be opened after disabled.

<xy-date-picker disabled></xy-date-picker>

direction

The dir allows you to set the direction of the date selector. By default, it is bottom left, with values of top, right, bottom, left, top left, top right, right top, right bottom, bottom left, bottom right, left top, left bottom.This property can be adjusted when your date selector is at the edge of the screen.

<xy-date-picker dir="righttop"></xy-date-picker>

range Selection range

Adding a range attribute enables date range selection.

<xy-date-picker range></xy-date-picker>

You can specify a default value of the default range in the form of 2019-10-10-2019-12-31, linked with ~Default to current date.

<xy-date-picker range defaultvalue="2019-10-10~2019-12-31"></xy-date-picker>

value and date are both arrays in range selection mode

//value
["2019-05-15", "2019-12-26"]
//date
["Wed May 15 2019 08:00:00 GMT+0800 (China Standard Time)", "Thu Dec 26 2019 08:00:00 GMT+0800 (China Standard Time)"]

Event event

After the date is selected, press the OK button to trigger the change callback.

<xy-date-picker onchange="console.log(event)"></xy-date-picker>

event:{
    detail:{
        value,
        date
    }
}

Other triggers

date.onchange = function(ev){
    console.log(this.value);
    console.log(this.date);
    console.log(ev.target.value);
    console.log(ev.detail.value);
    console.log(ev.detail.date);
}

date.addEventListener('change',function(ev){
    console.log(this.value);
    console.log(this.date);
    console.log(ev.target.value);
    console.log(ev.detail.value);
    console.log(ev.detail.date);
})

Other

xy-date-picker is implemented internally based on xy-popover and xy-date-pane.

<xy-popover >
    <xy-button class="date-btn"></xy-button>
    <xy-popcon>
        <xy-date-pane id="color-pane"></xy-date-pane>
        <div class="pop-footer">
            <xy-button id="btn-cancel">cancel</xy-button>
            <xy-button type="primary" id="btn-submit">confirm</xy-button>
        </div>
    </xy-popcon>
</xy-popover>

xy-date-pane is the date selection panel and can be used independently. If you only want a calendar, you can use this component.

<xy-date-pane></xy-date-pane>

Events and attributes are consistent with xy-date-picker.

Subsection

Overall, xy-date-picker is easy to use, and you don't need to write a lot of scripts, just like using an input, most of the time you just need to know one onchange event.

actually xy-ui Their component designs are close to the original, without those self-created events, such as onchange, where some date component libraries like to make datechange. Although the semantics are good, they are not native enough, not uniform enough, users are completely insensitive, do not know what to do without looking at the documents, but native is more representative., normative, so to speak, take this component and put it on the page, you can start most of the functions without looking at the api documentation at all.

at present xy-ui Most of the common components have been completed and will be supplemented in succession, with the hope that the little buddies who need them will be able to use them right away or go there github Give a star, thank you~

Topics: Javascript Attribute github npm