Fix for #3758 - updating the datetime cell renderer and form component to be capable of display time only formats, as well as adding an option to only select the time component for a date time form field.

This commit is contained in:
mike12345567 2022-02-08 16:15:08 +00:00
parent d021883f43
commit d13985af3f
7 changed files with 100 additions and 64 deletions

View File

@ -14,16 +14,20 @@
export let value = null export let value = null
export let placeholder = null export let placeholder = null
export let appendTo = undefined export let appendTo = undefined
export let timeOnly = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const flatpickrId = `${generateID()}-wrapper` const flatpickrId = `${generateID()}-wrapper`
let open = false let open = false
let flatpickr let flatpickr, flatpickrOptions, isTimeOnly
$: isTimeOnly = !timeOnly && value ? !isNaN(new Date(`0-${value}`)) : timeOnly
$: flatpickrOptions = { $: flatpickrOptions = {
element: `#${flatpickrId}`, element: `#${flatpickrId}`,
enableTime: enableTime || false, enableTime: isTimeOnly || enableTime || false,
noCalendar: isTimeOnly || false,
altInput: true, altInput: true,
altFormat: enableTime ? "F j Y, H:i" : "F j, Y", altFormat: isTimeOnly ? "H:i" : enableTime ? "F j Y, H:i" : "F j, Y",
wrap: true, wrap: true,
appendTo, appendTo,
disableMobile: "true", disableMobile: "true",
@ -35,6 +39,11 @@
if (newValue) { if (newValue) {
newValue = newValue.toISOString() newValue = newValue.toISOString()
} }
// if time only set date component to today
if (timeOnly) {
const todayDate = new Date().toISOString().split("T")[0]
newValue = `${todayDate}T${newValue.split("T")[1]}`
}
dispatch("change", newValue) dispatch("change", newValue)
} }
@ -67,7 +76,11 @@
return null return null
} }
let date let date
if (val instanceof Date) { let time = new Date(`0-${val}`)
// it is a string like 00:00:00, just time
if (timeOnly || (typeof val === "string" && !isNaN(time))) {
date = time
} else if (val instanceof Date) {
// Use real date obj if already parsed // Use real date obj if already parsed
date = val date = val
} else if (isNaN(val)) { } else if (isNaN(val)) {
@ -77,7 +90,7 @@
// Treat as numerical timestamp // Treat as numerical timestamp
date = new Date(parseInt(val)) date = new Date(parseInt(val))
} }
const time = date.getTime() time = date.getTime()
if (isNaN(time)) { if (isNaN(time)) {
return null return null
} }
@ -88,69 +101,71 @@
} }
</script> </script>
<Flatpickr {#key isTimeOnly}
bind:flatpickr <Flatpickr
value={parseDate(value)} bind:flatpickr
on:open={onOpen} value={parseDate(value)}
on:close={onClose} on:open={onOpen}
options={flatpickrOptions} on:close={onClose}
on:change={handleChange} options={flatpickrOptions}
element={`#${flatpickrId}`} on:change={handleChange}
> element={`#${flatpickrId}`}
<div
id={flatpickrId}
class:is-disabled={disabled}
class:is-invalid={!!error}
class="flatpickr spectrum-InputGroup spectrum-Datepicker"
class:is-focused={open}
aria-readonly="false"
aria-required="false"
aria-haspopup="true"
> >
<div <div
on:click={flatpickr?.open} id={flatpickrId}
class="spectrum-Textfield spectrum-InputGroup-textfield"
class:is-disabled={disabled} class:is-disabled={disabled}
class:is-invalid={!!error} class:is-invalid={!!error}
class="flatpickr spectrum-InputGroup spectrum-Datepicker"
class:is-focused={open}
aria-readonly="false"
aria-required="false"
aria-haspopup="true"
> >
{#if !!error} <div
on:click={flatpickr?.open}
class="spectrum-Textfield spectrum-InputGroup-textfield"
class:is-disabled={disabled}
class:is-invalid={!!error}
>
{#if !!error}
<svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
focusable="false"
aria-hidden="true"
>
<use xlink:href="#spectrum-icon-18-Alert" />
</svg>
{/if}
<input
data-input
type="text"
{disabled}
class="spectrum-Textfield-input spectrum-InputGroup-input"
{placeholder}
{id}
{value}
/>
</div>
<button
type="button"
class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button"
tabindex="-1"
{disabled}
class:is-invalid={!!error}
on:click={flatpickr?.open}
>
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon" class="spectrum-Icon spectrum-Icon--sizeM"
focusable="false" focusable="false"
aria-hidden="true" aria-hidden="true"
aria-label="Calendar"
> >
<use xlink:href="#spectrum-icon-18-Alert" /> <use xlink:href="#spectrum-icon-18-Calendar" />
</svg> </svg>
{/if} </button>
<input
data-input
type="text"
{disabled}
class="spectrum-Textfield-input spectrum-InputGroup-input"
{placeholder}
{id}
{value}
/>
</div> </div>
<button </Flatpickr>
type="button" {/key}
class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button"
tabindex="-1"
{disabled}
class:is-invalid={!!error}
on:click={flatpickr?.open}
>
<svg
class="spectrum-Icon spectrum-Icon--sizeM"
focusable="false"
aria-hidden="true"
aria-label="Calendar"
>
<use xlink:href="#spectrum-icon-18-Calendar" />
</svg>
</button>
</div>
</Flatpickr>
{#if open} {#if open}
<div class="overlay" on:mousedown|self={flatpickr?.close} /> <div class="overlay" on:mousedown|self={flatpickr?.close} />
{/if} {/if}

View File

@ -9,6 +9,7 @@
export let disabled = false export let disabled = false
export let error = null export let error = null
export let enableTime = true export let enableTime = true
export let timeOnly = false
export let placeholder = null export let placeholder = null
export let appendTo = undefined export let appendTo = undefined
@ -27,6 +28,7 @@
{value} {value}
{placeholder} {placeholder}
{enableTime} {enableTime}
{timeOnly}
{appendTo} {appendTo}
on:change={onChange} on:change={onChange}
/> />

View File

@ -2,9 +2,18 @@
import dayjs from "dayjs" import dayjs from "dayjs"
export let value export let value
// adding the 0- will turn a string like 00:00:00 into a valid ISO
// date, but will make actual ISO dates invalid
$: time = new Date(`0-${value}`)
$: isTime = !isNaN(time)
</script> </script>
<div>{dayjs(value).format("MMMM D YYYY, HH:mm")}</div> <div>
{dayjs(isTime ? time : value).format(
isTime ? "HH:mm:ss" : "MMMM D YYYY, HH:mm"
)}
</div>
<style> <style>
div { div {

View File

@ -2453,6 +2453,12 @@
"key": "enableTime", "key": "enableTime",
"defaultValue": true "defaultValue": true
}, },
{
"type": "boolean",
"label": "Time Only",
"key": "timeOnly",
"defaultValue": false
},
{ {
"type": "text", "type": "text",
"label": "Default value", "label": "Default value",

View File

@ -7,6 +7,7 @@
export let placeholder export let placeholder
export let disabled = false export let disabled = false
export let enableTime = false export let enableTime = false
export let timeOnly = false
export let validation export let validation
export let defaultValue export let defaultValue
@ -33,6 +34,7 @@
id={fieldState.fieldId} id={fieldState.fieldId}
appendTo={document.getElementById("flatpickr-root")} appendTo={document.getElementById("flatpickr-root")}
{enableTime} {enableTime}
{timeOnly}
{placeholder} {placeholder}
/> />
{/if} {/if}

View File

@ -36,13 +36,9 @@ CREATE TABLE people
INSERT products INSERT products
(name, description) (name, description)
VALUES VALUES
('Bananas', 'Fruit thing'); ('Bananas', 'Fruit thing'),
INSERT products
(name, description)
VALUES
('Meat', 'Animal thing'); ('Meat', 'Animal thing');
INSERT tasks INSERT tasks
(taskname, productid) (taskname, productid)
VALUES VALUES

View File

@ -19,6 +19,12 @@ CREATE TABLE Tasks (
FOREIGN KEY(PersonID) FOREIGN KEY(PersonID)
REFERENCES Persons(PersonID) REFERENCES Persons(PersonID)
); );
CREATE TABLE Products (
id serial primary key,
name text,
updated time
);
INSERT INTO Persons (FirstName, LastName, Age, Address, City, CreatedAt) VALUES ('Mike', 'Hughes', 28.2, '123 Fake Street', 'Belfast', '2021-01-19 03:14:07'); INSERT INTO Persons (FirstName, LastName, Age, Address, City, CreatedAt) VALUES ('Mike', 'Hughes', 28.2, '123 Fake Street', 'Belfast', '2021-01-19 03:14:07');
INSERT INTO Tasks (PersonID, TaskName) VALUES (1, 'assembling'); INSERT INTO Tasks (PersonID, TaskName) VALUES (1, 'assembling');
INSERT INTO Tasks (PersonID, TaskName) VALUES (1, 'processing'); INSERT INTO Tasks (PersonID, TaskName) VALUES (1, 'processing');
INSERT INTO Products (name, updated) VALUES ('Meat', '11:00:22'), ('Fruit', '10:00:00');