-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<input | ||
type="{if $field->supportsTime()}datetime{else}date{/if}" | ||
id="{$field->getPrefixedId()}_from" | ||
name="{$field->getPrefixedId()}[from]" | ||
value="{$field->getFromValue()}" | ||
data-placeholder="{lang}wcf.date.period.start{/lang}" | ||
{if !$field->getFieldClasses()|empty} class="{implode from=$field->getFieldClasses() item='class' glue=' '}{$class}{/implode}"{/if} | ||
{if $field->isAutofocused()} autofocus{/if} | ||
{if $field->isRequired()} required{/if} | ||
{if $field->isImmutable()} disabled{/if} | ||
{foreach from=$field->getFieldAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach} | ||
> | ||
<input | ||
type="{if $field->supportsTime()}datetime{else}date{/if}" | ||
id="{$field->getPrefixedId()}_to" | ||
name="{$field->getPrefixedId()}[to]" | ||
value="{$field->getToValue()}" | ||
data-placeholder="{lang}wcf.date.period.end{/lang}" | ||
{if !$field->getFieldClasses()|empty} class="{implode from=$field->getFieldClasses() item='class' glue=' '}{$class}{/implode}"{/if} | ||
{if $field->isRequired()} required{/if} | ||
{if $field->isImmutable()} disabled{/if} | ||
{foreach from=$field->getFieldAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach} | ||
> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* Data handler for a date range form builder field in an Ajax form. | ||
* | ||
* @author Marcel Werk | ||
* @copyright 2001-2024 WoltLab GmbH | ||
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | ||
* @since 6.2 | ||
*/ | ||
import Field from "./Field"; | ||
import { FormBuilderData } from "../Data"; | ||
import DatePicker from "../../../Date/Picker"; | ||
|
||
class DateRange extends Field { | ||
#fromField: HTMLElement | null; | ||
#toField: HTMLElement | null; | ||
|
||
constructor(fieldId: string) { | ||
super(fieldId); | ||
|
||
this.#fromField = document.getElementById(this._fieldId + "_from"); | ||
if (this.#fromField === null) { | ||
throw new Error("Unknown field with id '" + this._fieldId + "'."); | ||
} | ||
|
||
this.#toField = document.getElementById(this._fieldId + "_to"); | ||
if (this.#toField === null) { | ||
throw new Error("Unknown field with id '" + this._fieldId + "'."); | ||
} | ||
} | ||
|
||
protected _getData(): FormBuilderData { | ||
return { | ||
[this._fieldId]: { | ||
from: DatePicker.getValue(this.#fromField as HTMLInputElement), | ||
to: DatePicker.getValue(this.#toField as HTMLInputElement), | ||
}, | ||
}; | ||
} | ||
|
||
protected _readField(): void {} | ||
} | ||
|
||
export = DateRange; |
30 changes: 30 additions & 0 deletions
30
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/DateRange.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
161 changes: 161 additions & 0 deletions
161
wcfsetup/install/files/lib/system/form/builder/field/DateRangeFormField.class.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
<?php | ||
|
||
namespace wcf\system\form\builder\field; | ||
|
||
use wcf\system\form\builder\field\validation\FormFieldValidationError; | ||
|
||
/** | ||
* Implementation of a form field for a date range (with a time). | ||
* | ||
* @author Marcel Werk | ||
* @copyright 2001-2024 WoltLab GmbH | ||
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | ||
* @since 6.2 | ||
*/ | ||
class DateRangeFormField extends AbstractFormField implements | ||
IAttributeFormField, | ||
IAutoFocusFormField, | ||
ICssClassFormField, | ||
IImmutableFormField, | ||
INullableFormField | ||
{ | ||
use TAttributeFormField; | ||
use TAutoFocusFormField; | ||
use TCssClassFormField; | ||
use TImmutableFormField; | ||
use TNullableFormField; | ||
|
||
/** | ||
* is `true` if not only the date, but also the time can be set | ||
* @var bool | ||
*/ | ||
protected $supportsTime = false; | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
protected $javaScriptDataHandlerModule = 'WoltLabSuite/Core/Form/Builder/Field/DateRange'; | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
protected $templateName = 'shared_dateRangeFormField'; | ||
|
||
const DATE_FORMAT = 'Y-m-d'; | ||
|
||
const TIME_FORMAT = 'Y-m-d\TH:i:sP'; | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function getSaveValue() | ||
{ | ||
if ($this->getValue() === null && $this->isNullable()) { | ||
return null; | ||
} | ||
|
||
return $this->getFromValue() . ';' . $this->getToValue(); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function readValue() | ||
{ | ||
if ( | ||
$this->getDocument()->hasRequestData($this->getPrefixedId()) | ||
&& \is_array($this->getDocument()->getRequestData($this->getPrefixedId())) | ||
) { | ||
$this->value = $this->getDocument()->getRequestData($this->getPrefixedId()); | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Sets if not only the date, but also the time can be set. | ||
*/ | ||
public function supportTime($supportsTime = true): static | ||
{ | ||
if ($this->value !== null) { | ||
throw new \BadFunctionCallException( | ||
"After a value has been set, time support cannot be changed for field '{$this->getId()}'." | ||
); | ||
} | ||
|
||
$this->supportsTime = $supportsTime; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Returns `true` if not only the date, but also the time can be set, and | ||
* returns `false` otherwise. | ||
* | ||
* By default, the time cannot be set. | ||
*/ | ||
public function supportsTime(): bool | ||
{ | ||
return $this->supportsTime; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function validate() | ||
{ | ||
if ($this->isRequired() && (!$this->getFromValue() || !$this->getToValue())) { | ||
$this->addValidationError(new FormFieldValidationError('empty')); | ||
} | ||
|
||
if ($this->getFromValue()) { | ||
$dateTime = \DateTime::createFromFormat( | ||
$this->supportsTime() ? self::TIME_FORMAT : self::DATE_FORMAT, | ||
$this->getFromValue() | ||
); | ||
if ($dateTime === false) { | ||
$this->addValidationError(new FormFieldValidationError('invalid')); | ||
} | ||
} | ||
|
||
if ($this->getToValue()) { | ||
$dateTime = \DateTime::createFromFormat( | ||
$this->supportsTime() ? self::TIME_FORMAT : self::DATE_FORMAT, | ||
$this->getToValue() | ||
); | ||
if ($dateTime === false) { | ||
$this->addValidationError(new FormFieldValidationError('invalid')); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function value($value) | ||
{ | ||
$values = \explode(';', $value); | ||
if (\count($values) !== 2) { | ||
throw new \InvalidArgumentException( | ||
"Given value does not match format for field '{$this->getId()}'." | ||
); | ||
} | ||
|
||
$this->value = [ | ||
'from' => $values[0], | ||
'to' => $values[1], | ||
]; | ||
|
||
return $this; | ||
} | ||
|
||
public function getFromValue(): string | ||
{ | ||
return $this->value['from'] ?? ''; | ||
} | ||
|
||
public function getToValue(): string | ||
{ | ||
return $this->value['to'] ?? ''; | ||
} | ||
} |