Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!-- Preset the date selection adding the attributes data-from="YYYY-MM-DDT00:00:00" and data-to="YYYY-MM-DDT00:00:00" -->

<div class="datepicker"></div>
              
            
!

CSS

              
                /* Datepicker */
.datepicker {
	display: inline-block
}

/* Header */
.datepicker header {
	display: flex;
	justify-content: space-between;
}

.datepicker header > * {
	align-self: center;
}

/* Nav buttons */
.datepicker header button {}

/* Prev button */
.datepicker header :first-child {}

/* Next button */
.datepicker header :last-child {}

/* Month & year */
.datepicker h3 {}

/* Calendar */
.datepicker table {}

/* Weekdays */
.datepicker thead {}

.datepicker thead tr {}

/* Weekday */
.datepicker th {}

/* Month days */
.datepicker tbody {}

.datepicker tbody tr {}

/* Month day */
.datepicker tbody td {}

/* Day types */
.datepicker .empty {
	pointer-events: none;
}

.datepicker tbody td:hover {
	background: silver;
}

.datepicker .today {
	background: green;
}

.datepicker .selected {
	background: red;
}

.datepicker .selected-from {
	background: red;
}

.datepicker .selected-to {
	background: blue;
}

.datepicker .included {
	background: violet;
}

/* Footer */
.datepicker footer {
	display: flex;
	justify-content: space-between;
}

.datepicker footer > * {
	align-self: center;
}

/* Footer buttons */
.datepicker footer buttons {}

/* Clear button */
.datepicker footer :first-child {}

/* Accept button */
.datepicker footer :last-child {}

/* Selected days */
.datepicker p {}
              
            
!

JS

              
                var datepicker = document.querySelectorAll('.datepicker');

if (datepicker) {
	datepicker.forEach(function(element) {
		// BUILD
		// Header
		var header = document.createElement('header');
		element.appendChild(header);

		var prev = document.createElement('button');
		prev.textContent = 'Prev';
		header.appendChild(prev);

		var h3 = document.createElement('h3');
		header.appendChild(h3);

		var next = document.createElement('button');
		next.textContent = 'Next';
		header.appendChild(next);

		// Calendar
		var table = document.createElement('table');
		element.appendChild(table);

		var thead = document.createElement('thead');
		table.appendChild(thead);

		var tr = document.createElement('tr');
		thead.appendChild(tr);

		var weekdays = ['Mon', 'Tue', 'Wed', 'Tru', 'Fri', 'Sat', 'Dun'];

		for (var i = 0; i < 7; i++) {
			var th = document.createElement('th');
			th.textContent = weekdays[i];
			tr.appendChild(th);
		}

		var tbody = document.createElement('tbody');
		table.appendChild(tbody);

		for (var week = 0; week < 6; week++) {
			var tr = document.createElement('tr');
			tbody.appendChild(tr);

			for (var day = 0; day < 7; day++) {
				var td = document.createElement('td');
				tr.appendChild(td);
			}
		}

		var slots = tbody.querySelectorAll('td');

		// Footer
		var footer = document.createElement('footer');
		element.appendChild(footer);

		var clear = document.createElement('button');
		clear.textContent = 'Clear';
		footer.appendChild(clear);

		var range = document.createElement('p');
		footer.appendChild(range);

		var accept = document.createElement('button');
		accept.textContent = 'Accept';
		footer.appendChild(accept);

		// SET CALENDAR
		var today  = new Date();
		var month  = today.getMonth();
		var year   = today.getFullYear();
		var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

		function set_selection() {
			var from = element.getAttribute('data-from');
			var to   = element.getAttribute('data-to');

			if (from) {
				slots.forEach(function(slot) {
					var date = slot.getAttribute('data-date');

					slot.classList.remove('selected','selected-from','selected-to','included');

					// Set from
					if (date == from) {
						slot.classList.add('selected');
					}

					// Set to
					if (to && to != from ) {
						// If from is in view
						if (element.querySelector('.selected')) {
							element.querySelector('.selected').classList.replace('selected','selected-from');
						}
						
						if (slot.getAttribute('data-date') == to) {
							slot.classList.add('selected-to');
						}

						// Set included
						var from_date = new Date(element.getAttribute('data-from'));
						var to_date   = new Date(element.getAttribute('data-to'));

						if (!slot.classList.contains('empty')) {
							var date = new Date(slot.getAttribute('data-date'));

							if (date > from_date && date < to_date) {
								slot.classList.add('included');
							}
						}
					}
				});
			}
		}

		function days_selected() {
			var days_selected = 0 + ' days';
			
			from = element.getAttribute('data-from');
			to   = element.getAttribute('data-to');

			if (from) {
				days_selected = 1 + ' day';

				if (to) {
					days_selected = ((new Date(to).getTime() - new Date(from).getTime()) / (1000 * 3600 * 24) + 1) + ' days';
				}
			}

			range.textContent = days_selected;
		}

		function set_calendar() {
			// Set month and year
			h3.textContent = months[month] + ' ' + year;

			// Clear slots
			slots.forEach(function(slot) {
				slot.textContent = '';
				slot.removeAttribute('class');
				slot.removeAttribute('data-date');
			});
			
			// Set days
			var days_in_month = new Date(year, month+1, 0).getDate();
			var first_weekday = new Date(year, month, 0).getDay();

			for (var i = 0; i < days_in_month; i++) {
				var day = slots[i+first_weekday];

				set_date = function() {
					data_month = month+1;
					data_day   = i+1;

					if (data_month < 10) {
						data_month = '0' + data_month;
					}

					if (data_day < 10) {
						data_day = '0' + data_day;
					}

					return year + '-' + data_month + '-' + data_day + 'T00:00:00';
				}

				day.setAttribute('data-date', set_date());
				day.textContent = i+1;
			}
			
			slots.forEach(function(slot) {
				// Set today
				if ( new Date(slot.getAttribute('data-date')).getTime() == today.setHours(0,0,0,0) ) {
					slot.classList.add('today');
				}

				// Block empty slots
				if (slot.textContent == '') {
					slot.classList.add('empty');
				}
			});

			// Set selection and return days selected
			set_selection();
			days_selected();
		}

		set_calendar();

		// NAVIGATION
		prev.onclick = function() {
			month -= 1;

			if (month < 0) {
				month = 11;
				year -= 1;
			}

			set_calendar();
		}

		next.onclick = function() {
			month += 1;

			if (month > 11) {
				month = 0;
				year += 1;
			}

			set_calendar();
		}

		// SELECTION
		slots.forEach(function(slot) {
			slot.onclick = function() {
				var from       = element.getAttribute('data-from');
				var to         = element.getAttribute('data-to');
				var date       = slot.getAttribute('data-date');
				
				// Set from
				if (!from) {
					element.setAttribute('data-from', date);

					// FROM CALLBACK HERE
				}
				
				else {
					// Set to
					if (!to) {
						if ( new Date(date) >= new Date(from) ) {
							element.setAttribute('data-to', date);
						}

						else {
							element.setAttribute('data-from', date);
							element.setAttribute('data-to', from);
						}

						// TO CALLBACK HERE
					}

					// Reset from
					else {
						element.setAttribute('data-from', date);
						element.removeAttribute('data-to');
					}
				}

				// Set selection and return days selected
				set_selection();
				days_selected();
			}
		});

		// Clear
		clear.onclick = function() {
			element.removeAttribute('data-from');
			element.removeAttribute('data-to');

			slots.forEach(function(slot) {
				slot.classList.remove('selected', 'selected-from', 'included', 'selected-to');
			});

			days_selected();

			// CLEAR CALLBACK HERE
		}

		// Accept
		accept.onclick = function() {
			// ACCEPT CALLBACK HERE
		}
	});
}
              
            
!
999px

Console