๐Ÿ—“ datepicker ์ปค์Šคํ…€ํ•˜๊ธฐ - ๋ชจ๋‹ฌ์ฐฝ ๋””์ž์ธ

jellykellyยท2023๋…„ 6์›” 15์ผ
0

UI Interaction

๋ชฉ๋ก ๋ณด๊ธฐ
1/3
post-thumbnail
post-custom-banner

jQuery UI์—์„œ ์ œ๊ณตํ•˜๋Š” datepicker ์œ„์ ฏ์€ input์„ ํด๋ฆญํ•˜๋ฉด ๋‹ฌ๋ ฅ์ด ์—ด๋ฆฌ๊ณ , ๋‚ ์งœ ์„ ํƒ or ๋‹ฌ๋ ฅ ๋ฐ”๊นฅ ์˜์—ญ์„ ํด๋ฆญํ•˜๋ฉด ๋‹ฌ๋ ฅ์ด ๋‹ซํžˆ๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ html์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๋‹ฌ๋ ฅ์ด ์—ด๋ ธ์„ ๋•Œ ์•„๋ž˜์— ๋ถˆํˆฌ๋ช… ๋ฐฐ๊ฒฝ(dim)์„ ๊น”์•„์„œ ๋ชจ๋‹ฌ์ฐฝ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ํšจ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด ๋ณผ๊ฒŒ์š”.
datepicker ์‚ฌ์šฉ๋ฒ•์€ ๋งค์šฐ ์‹ฌํ”Œํ•˜๋ฏ€๋กœ ์„ค์น˜์™€ ์‚ฌ์šฉ๋ฒ•์€ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋””์ž์ธ ์ปค์Šคํ…€๋งŒ ํฌ์ŠคํŒ… ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


์‹œ~์ž‘! ๐Ÿค—


datepicker ๊ธฐ๋ณธ ๊ตฌ์กฐ

<body>
	<div id="wrap">input ์˜์—ญ</div>
	<div id="ui-datepicker-div">๋‹ฌ๋ ฅ ์˜์—ญ</div>
</body>

datepicker ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋ฉด div#ui-datepicker-div๊ฐ€ ์ž๋™์œผ๋กœ body ๊ฐ€์žฅ ํ•˜๋‹จ์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
๋‹ฌ๋ ฅ์„ ๋ชจ๋‹ฌ์ฐฝ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋ฐฐ๊ฒฝ์„ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด div#ui-datepicker-div ์œ„์— ํ˜•์ œ ํƒœ๊ทธ๋กœ div๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋„ค์š”.

๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด ์ƒ์„ฑ

Javascript

// datapicker ๊ธฐ๋ณธ ์„ธํŒ…
datepickerInput.datepicker({
    ...
  }
});


// datepicker ์ปค์Šคํ…€ ์‹œ์ž‘

const calendar = document.querySelector('#ui-datepicker-div');

// ๋ฐฐ๊ฒฝ ์˜์—ญ ํƒœ๊ทธ ์ƒ์„ฑ ๋ฐ ๋‹ฌ๋ ฅ์˜ ์ด์ „ ํ˜•์ œ์œ„์น˜๋กœ ์ถ”๊ฐ€
const dim = document.createElement('div');
dim.classList.add('datepicker-layer');
calendar.before(dim);

datepicker ์ดˆ๊ธฐ ์„ค์ • ์ดํ›„์— ๋‹ฌ๋ ฅ ์˜์—ญ์ด ์ƒ์„ฑ๋˜๋ฏ€๋กœ(๋ณ€์ˆ˜ calendar), DOM ์ œ์–ด๋ฅผ ์œ„ํ•ด datepicker ์ดˆ๊ธฐ ์„ค์ • ํ›„ ๋ฐฐ๊ฒฝ ์˜์—ญ ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์—ฌ๊ธฐ๊นŒ์ง€ ์ถ”๊ฐ€ํ•˜๋ฉด ๋‹ฌ๋ ฅ ์˜์—ญ์˜ ์ด์ „ ํ˜•์ œ ์œ„์น˜๋กœ ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด(dim)๊ฐ€ ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค.
<body>
	<div id="wrap">input ์˜์—ญ</div>
    <div class="datepicker-layer">๐Ÿ‘‰ ์ถ”๊ฐ€๋œ ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด ์˜์—ญ ๐Ÿ‘ˆ</div>
	<div id="ui-datepicker-div">๋‹ฌ๋ ฅ ์˜์—ญ</div>
</body>

CSS

.datepicker-layer๊ฐ€ ํ™”๋ฉด ์ „์ฒด๋ฅผ ์ฐจ์ง€ํ•˜๋„๋ก ์Šคํƒ€์ผ๋งํ•˜๊ณ  display: none ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋‚ ์งœ ์„ ํƒ ์ „์—๋Š” ๋ณด์ด์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ๊ฐ’์ด๋‹ˆ๊นŒ์š”!

.datepicker-layer {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 100;
    display: none;
}

๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด show

์ด์ œ ์ธํ’‹๋ฐ•์Šค๋ฅผ ํด๋ฆญํ•ด์„œ ๋‹ฌ๋ ฅ์ด ์—ด๋ฆด ๋•Œ ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด๊ฐ€ ๋ณด์ด๊ฒŒ ์„ค์ •ํ•ด๋ณผ๊ฒŒ์š”. ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด์˜ display๊ฐ’์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

// ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด display ์ œ์–ด ํ•จ์ˆ˜
const layer = document.querySelector('.datepicker-layer');

function dimDisplay(display) {
  layer.style.display = display;
}

//๋ฐฐ๊ฒฝ์˜์—ญ show
datepickerInput.addEventListener('click', () => {
	dimDisplay('block');
})

์˜ค๋ฅ˜๋ฐœ์ƒ ๐Ÿšจ๐Ÿšจ๐Ÿšจ

input์„ ํด๋ฆญํ•˜๋ฉด ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด์˜ display: block์ด ๋˜๋Š” ๊ฐ„๋‹จํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ์•„๋ฌด๋Ÿฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ๐Ÿคฏ ์ฝ˜์†”์„ ์ฐ์–ด๋ด๋„ ์•„๋ฌด ์ด๋ฒคํŠธ๊ฐ€ ๊ฐ์ง€๋˜์ง€ ์•Š์•„์š”..... ๋งˆํฌ์—… ๊ตฌ์กฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด์„œ ์ด๋ฆฌ์ €๋ฆฌ ์ˆ˜์ •ํ•ด๋ด๋„ ์—ฌ์ „ํžˆ ๋ฐ˜์‘ ์—†๋Š” ๋„ˆ.... ๐Ÿ˜ญ


๊ทธ๋ž˜๋„ ์–ด์ฉŒ๊ฒ ์–ด์š”... ํ•ด๋‚ด์•ผ์ฃ .......
์˜ค๋ฅ˜๋Š” ๋‚˜์ค‘์— ์ฐพ๊ณ  ์ผ๋‹จ ๋งŒ๋“ค๊ณ  ๋ณด์ž(!)

ํ•ด๊ฒฐ ๐Ÿ› ๐Ÿ› ๐Ÿ› 

๊ทธ๋ž˜์„œ ์ƒ๊ฐํ•ด ๋‚ธ ๋ฐฉ๋ฒ•!

inputํƒœ๊ทธ ์ด๋‹ˆ๊นŒ ํด๋ฆญํ•˜๋ฉด focus๊ฐ€ ๋˜์ž–์•„์š”? click ์ด๋ฒคํŠธ ๋Œ€์‹  focus์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด๋ด…๋‹ˆ๋‹ค.

datepickerInput.addEventListener('focus', () => {
	dimDisplay('block');
})

์งœ์ž” ๋ฐฐ๊ฒฝ์ด ์ž˜ ๋‚˜์˜ต๋‹ˆ๋‹ค! ๐Ÿฅณ

๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด hide

์—ด์—ˆ์œผ๋‹ˆ ์ด์ œ ๋‹ค์‹œ ๋‹ซ์•„๋ด…์‹œ๋‹ค. ๋ชจ๋‹ฌ์ฐฝ(๋‹ฌ๋ ฅ)์ด ๋‹ซํž ๋•Œ ๋ฐฐ๊ฒฝ ํ™”๋ฉด์„ ์ˆจ๊ธฐ๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€ ์ž…๋‹ˆ๋‹ค.

  1. ๋‹ฌ๋ ฅ ๋‚ด๋ถ€์˜ ๋‚ ์งœ๋ฅผ ์„ ํƒ
  2. ๋‹ฌ๋ ฅ์ด ์•„๋‹Œ ๋ฐฐ๊ฒฝ์„ ํด๋ฆญ

1. ๋‚ ์งœ ์„ ํƒ ์‹œ ๋ชจ๋‹ฌ์„ ๋‹ซ๊ณ  ๋ฐฐ๊ฒฝ ์ˆจ๊น€

datepicker์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ์˜ต์…˜ ์ค‘ onSelect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ ์งœ๋ฅผ ์„ ํƒํ–ˆ์„ ๋•Œ ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด๋ฅผ display: none ์ฒ˜๋ฆฌ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

datepickerInput.datepicker({
  ...
  onSelect: function () {
      dimDisplay('none');
    }
  }
});



2. ๋ฐฐ๊ฒฝ ์˜์—ญ์„ ํด๋ฆญํ•ด์„œ ๋ชจ๋‹ฌ์„ ๋‹ซ๊ณ  ๋ฐฐ๊ฒฝ ์ˆจ๊น€

<body>
	<div id="wrap">input ์˜์—ญ</div>
    <div class="datepicker-layer">๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด ์˜์—ญ</div>
	<div id="ui-datepicker-div">๋‹ฌ๋ ฅ ์˜์—ญ</div>
</body>

ํ˜„์žฌ ๋งˆํฌ์—…์ด ์œ„์™€ ๊ฐ™์ด ๋งค์šฐ ๊ฐ„๋‹จํ•œ ๊ตฌ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ˆœํžˆ ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด ์˜์—ญ์„ ํด๋ฆญํ•ด์„œ ๋ชจ๋‹ฌ์ฐฝ(๋‹ฌ๋ ฅ)์„ ๋‹ซ์„ ๋•Œ ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด์˜ display: none์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const layer = document.querySelector('.datepicker-layer');

layer.addEventListener('click', function (e) {
	dimDisplay('none');
});

์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ๋งˆํฌ์—…์ผ ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋‹ฌ๋ ฅ ์ด์™ธ์˜ ๋ชจ๋“  ์˜์—ญ์„ ํด๋ฆญ ์‹œ ๋ฐฐ๊ฒฝ display: none์ฒ˜๋ฆฌ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค.

window.addEventListener('click', function (e) {
	if (e.target === layer) {
		dimDisplay('none');
	}
});

if (e.target === layer) ์กฐ๊ฑด์„ ๋„ฃ์–ด ํด๋ฆญํ•œ ์˜์—ญ์ด layer์ผ๋•Œ๋งŒ ๋ฐฐ๊ฒฝ ๋ ˆ์ด์–ด์˜ display: none ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์กฐ๊ฑด์ด ์—†๋‹ค๋ฉด ๋‚ ์งœ๋ฅผ ์„ ํƒํ•˜๋Š” ์ธํ’‹๋„ window ์˜์—ญ์œผ๋กœ ์žกํžˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ธํ’‹์„ ํด๋ฆญํ•  ๋•Œ ๋ฐฐ๊ฒฝ์˜ display๊ฐ€ none์ด ๋˜์–ด ๋ฐฐ๊ฒฝ์ด ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ „์ฒด์ฝ”๋“œ ๋ณด๊ธฐ ๐Ÿ—

profile
Hawaiian pizza with extra pineapples please! ๐Ÿฅค
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€