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:
parent
d021883f43
commit
d13985af3f
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -36,11 +36,7 @@ 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
|
||||||
|
|
|
@ -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');
|
||||||
|
|
Loading…
Reference in New Issue