JSFiddle - React, Tailwind, and code Playground
by whelkaholism
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.18/dayjs.min.js"></script>
<script src="https://cdn.cfront-cloud.co.uk/scripts/koa1.2/cf.DOM.js"></script>
<input type="text" data-bind="dateFilter: FilterDate" />
<br/>
<br/>
<input type="text" readonly="true" data-bind="value: FilterDate" />
CSS
.koa-date-filter {
position: relative;
display: flex;
align-items: center;
}
.koa-date-filter .show-date-filter::before {
content: '...'
}
.koa-date-filter .date-filter-ui {
display: none;
position: absolute;
z-index: 1;
background: #ffffff;
border: 1px solid #909090;
border-radius: 10px;
border-top-left-radius: 0;
padding: 1em;
width: 300%;
height: fit-content;
top: 100%;
}
.koa-date-filter .date-filter-ui.show {
display: flex;
flex-direction: column;
gap: 0.5em
}
.koa-date-filter .date-filter-ui select,
.koa-date-filter .date-filter-ui input[type=date] {
width: unset !important;
background: rgba(0, 0, 0, 0.05);
color: #212121 !important;
}
.koa-date-filter .date-filter-ui .date-filter-range {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.koa-date-filter .date-filter-ui.show {
width: 330px
}
.koa-date-filter .date-filter-ui.show button {
padding: 0.25em 0.5em;
line-height: unset;
margin: 0;
}
.koa-date-filter .date-filter-ui.show button.selected {
background: #eeeecc
}
.koa-date-filter .date-filter-ui.show * {
font-size: 13px;
}
.koa-date-filter .date-filter-ui .date-filter-mode {
margin-bottom: 1rem;
}
.koa-date-filter .date-filter-side, .date-filter-single {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
JavaScript
if (typeof (Date.hasValue) == 'undefined') Date.hasValue = function(s) { return !!s && !/^0001[\-\/\.]/.test(s); };
/*
::date: Simple binding to take the ISO date+time strings returned by Core services and allow them to bind to am HTML [type=date] field
::dateFilter: Popup UI to assist with entering ambiguous dates expected by fuzzy date filtering
*/
(function()
{
// ------------------------------------------------------------------------------------------------------------------------------------------------
// DATES
ko.bindingHandlers.date = {
init:
function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
{
if (el.nodeName == 'INPUT' && el.type != 'date')
el.type = 'date';
var obs = f_valueaccessor();
el.addEventListener('change', function(e)
{
obs(el.value || null);
});
},
update:
function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
{
var dt = ko.unwrap(f_valueaccessor());
var djs = Date.hasValue(dt) ? dayjs(dt) : null;
el.value = djs ? djs.format('YYYY-MM-DD') : '';
}
};
// ------------------------------------------------------------------------------------------------------------------------------------------------
ko.bindingHandlers.dateFilter = {
init:
function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
{
var obs = f_valueaccessor();
var numyears = allbindings.get('dateFilterNumYears') || 10;
if (!!obs)
{
el.wrap('<div class="koa-date-filter"></div>');
const nparent = el.parentNode;
const nbtn =...