diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java
index 1ed99e7d1b..2772bf25e6 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java
@@ -56,9 +56,6 @@ private FormConstants() {
/** The resource type for date picker v1 */
public static final String RT_FD_FORM_DATE_PICKER_V1 = RT_FD_FORM_PREFIX + "datepicker/v1/datepicker";
- /** The resource type for date picker v2 */
- public static final String RT_FD_FORM_DATE_PICKER_V2 = RT_FD_FORM_PREFIX + "datepicker/v2/datepicker";
-
/** The resource type for number input v1 */
public static final String RT_FD_FORM_NUMBER_INPUT_V1 = RT_FD_FORM_PREFIX + "numberinput/v1/numberinput";
diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/DatePickerImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/DatePickerImpl.java
index 69ed63840d..205cc2fead 100644
--- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/DatePickerImpl.java
+++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/DatePickerImpl.java
@@ -44,10 +44,7 @@
adaptables = { SlingHttpServletRequest.class, Resource.class },
adapters = { DatePicker.class,
ComponentExporter.class },
- resourceType = {
- FormConstants.RT_FD_FORM_DATE_PICKER_V1,
- FormConstants.RT_FD_FORM_DATE_PICKER_V2
- })
+ resourceType = { FormConstants.RT_FD_FORM_DATE_PICKER_V1 })
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class DatePickerImpl extends AbstractFieldImpl implements DatePicker {
diff --git a/it/apps/src/main/content/jcr_root/apps/forms-core-components-it/clientlibs/custom-forms-components-runtime-all/.content.xml b/it/apps/src/main/content/jcr_root/apps/forms-core-components-it/clientlibs/custom-forms-components-runtime-all/.content.xml
index 3859abc906..1b446738e2 100644
--- a/it/apps/src/main/content/jcr_root/apps/forms-core-components-it/clientlibs/custom-forms-components-runtime-all/.content.xml
+++ b/it/apps/src/main/content/jcr_root/apps/forms-core-components-it/clientlibs/custom-forms-components-runtime-all/.content.xml
@@ -5,4 +5,4 @@
cssProcessor="[default:none,min:none]"
jsProcessor="[default:none,min:none]"
categories="[core.forms.components.it.runtime.all]"
- embed="[core.forms.components.runtime.base,core.forms.components.it.container.v1.runtime,core.forms.components.datePicker.v1.runtime,core.forms.components.datePicker.v2.runtime,core.forms.components.textinput.v1.runtime,core.forms.components.numberinput.v1.runtime,core.forms.components.panelcontainer.v1.runtime,core.forms.components.radiobutton.v1.runtime,core.forms.components.text.v1.runtime,core.forms.components.checkboxgroup.v1.runtime,core.forms.components.button.v1.runtime,core.forms.components.image.v1.runtime,core.forms.components.dropdown.v1.runtime,core.forms.components.fileinput.v2.runtime,core.forms.components.accordion.v1.runtime,core.forms.components.tabs.v1.runtime,core.forms.components.wizard.v1.runtime,core.forms.components.verticaltabs.v1.runtime,core.forms.components.recaptcha.v1.runtime,core.forms.components.checkbox.v1.runtime,core.forms.components.fragment.v1.runtime,core.forms.components.switch.v1.runtime,core.forms.components.termsandconditions.v1.runtime, core.forms.components.it.textinput.v1.runtime, core.forms.components.hcaptcha.v1.runtime, core.forms.components.turnstile.v1.runtime]"/>
+ embed="[core.forms.components.runtime.base,core.forms.components.it.container.v1.runtime,core.forms.components.datePicker.v1.runtime,core.forms.components.textinput.v1.runtime,core.forms.components.numberinput.v1.runtime,core.forms.components.panelcontainer.v1.runtime,core.forms.components.radiobutton.v1.runtime,core.forms.components.text.v1.runtime,core.forms.components.checkboxgroup.v1.runtime,core.forms.components.button.v1.runtime,core.forms.components.image.v1.runtime,core.forms.components.dropdown.v1.runtime,core.forms.components.fileinput.v2.runtime,core.forms.components.accordion.v1.runtime,core.forms.components.tabs.v1.runtime,core.forms.components.wizard.v1.runtime,core.forms.components.verticaltabs.v1.runtime,core.forms.components.recaptcha.v1.runtime,core.forms.components.checkbox.v1.runtime,core.forms.components.fragment.v1.runtime,core.forms.components.switch.v1.runtime,core.forms.components.termsandconditions.v1.runtime, core.forms.components.it.textinput.v1.runtime, core.forms.components.hcaptcha.v1.runtime, core.forms.components.turnstile.v1.runtime]"/>
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js
index fcf743359f..5cb645ae95 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js
@@ -66,6 +66,7 @@ if (typeof window.DatePickerWidget === 'undefined') {
months: ["January","February","March","April","May","June","July","August","September","October","November","December"],
zero: "0",
clearText: "Clear",
+ openCalendarText: "Open calendar",
name: "en_US"
},
format: "YYYY-MM-DD",
@@ -218,6 +219,7 @@ if (typeof window.DatePickerWidget === 'undefined') {
}
});
this.prevNavWidthBtn = this.#dp.getElementsByClassName("dp-leftnav")[0];
+ this.prevNavWidthBtn.setAttribute("role", "button");
this.prevNavWidthBtn.addEventListener("click",
function (evnt) {
if (self.view && self.#curInstance) {
@@ -225,6 +227,7 @@ if (typeof window.DatePickerWidget === 'undefined') {
}
});
this.nextNavWidthBtn = this.#dp.getElementsByClassName("dp-rightnav")[0];
+ this.nextNavWidthBtn.setAttribute("role", "button");
this.nextNavWidthBtn.addEventListener("click",
function (evnt) {
if (self.view && self.#curInstance) {
@@ -232,6 +235,7 @@ if (typeof window.DatePickerWidget === 'undefined') {
}
});
this.caption = this.#dp.getElementsByClassName("dp-caption")[0];
+ this.caption.setAttribute("role", "button");
this.caption.id = "dp-caption";
this.caption.addEventListener("click",
function (evnt) {
@@ -318,6 +322,9 @@ if (typeof window.DatePickerWidget === 'undefined') {
if (this.#keyboardAccessibility) {
calendarIcon.setAttribute("tabindex", 0);
}
+ // Accessibility attributes for calendar icon button
+ calendarIcon.setAttribute("role", "button");
+ calendarIcon.setAttribute("aria-label", this.#options?.locale?.openCalendarText || "Open calendar");
calendarIcon.addEventListener(this.#getEvent(), function (evnt) {
self._iconClicked = true;
widget.click();
@@ -560,7 +567,6 @@ if (typeof window.DatePickerWidget === 'undefined') {
this.#focusedOnLi = false;
DatePickerWidget.#visible = true;
this.#position();
-
// Add document touch listener for mobile to close datepicker when tapping outside
if (this.#touchSupported && !this.#documentTouchListener) {
this.#documentTouchListener = (evt) => {
@@ -570,7 +576,6 @@ if (typeof window.DatePickerWidget === 'undefined') {
};
document.addEventListener("touchstart", this.#documentTouchListener, false);
}
-
if (this.#options.showCalendarIcon) {
this.#curInstance.$field.setAttribute('readonly', true); // when the datepicker is active, deactivate the field
}
@@ -659,8 +664,44 @@ if (typeof window.DatePickerWidget === 'undefined') {
this['$' + this.view.toLowerCase()].style.display = "none";
}
this.view = nextView;
- this.caption.classList.toggle("disabled",
- !this.#viewAction[this.view].caption);
+ let captionDisabled = !this.#viewAction[this.view].caption;
+ this.caption.classList.toggle("disabled", captionDisabled);
+ this.caption.setAttribute("aria-disabled", captionDisabled.toString());
+ let ariaLabel = "";
+ if (this.view === "Month") {
+ ariaLabel = this.#options.locale.months[this.currentMonth] + " " + this.currentYear;
+ this.prevNavWidthBtn.setAttribute(
+ "aria-label",
+ this.#options.locale.previousMonth || "Previous month"
+ );
+ this.nextNavWidthBtn.setAttribute(
+ "aria-label",
+ this.#options.locale.nextMonth || "Next month"
+ );
+ } else if (this.view === "Year") {
+ ariaLabel = this.currentYear;
+ this.prevNavWidthBtn.setAttribute(
+ "aria-label",
+ this.#options.locale.previousYear || "Previous year"
+ );
+ this.nextNavWidthBtn.setAttribute(
+ "aria-label",
+ this.#options.locale.nextYear || "Next year"
+ );
+ } else if (this.view === "Yearset") {
+ const startYear = this.currentYear - this.#options.yearsPerView / 2;
+ const endYear = startYear + this.#options.yearsPerView - 1;
+ ariaLabel = startYear + "-" + endYear;
+ this.prevNavWidthBtn.setAttribute(
+ "aria-label",
+ this.#options.locale.previousSetOfYears || "Previous set of years"
+ );
+ this.nextNavWidthBtn.setAttribute(
+ "aria-label",
+ this.#options.locale.nextSetOfYears || "Next set of years"
+ );
+ }
+ this.caption.setAttribute("aria-label", ariaLabel.toString());
this['$' + this.view.toLowerCase()].style.display = "block";
this["show" + this.view]();
}
@@ -1155,10 +1196,38 @@ if (typeof window.DatePickerWidget === 'undefined') {
if (clearText) {
defaultOptions.locale.clearText = clearText;
}
+ var openCalendarText = FormView.LanguageUtils.getTranslatedString(locale, "openCalendarText");
+ if (openCalendarText) {
+ defaultOptions.locale.openCalendarText = openCalendarText;
+ }
var zero = FormView.LanguageUtils.getTranslatedString(locale, "0");
if (zero) {
defaultOptions.locale.zero = zero;
}
+ var previousMonth = FormView.LanguageUtils.getTranslatedString(locale, "previousMonth");
+ if (previousMonth) {
+ defaultOptions.locale.previousMonth = previousMonth;
+ }
+ var nextMonth = FormView.LanguageUtils.getTranslatedString(locale, "nextMonth");
+ if (nextMonth) {
+ defaultOptions.locale.nextMonth = nextMonth;
+ }
+ var previousYear = FormView.LanguageUtils.getTranslatedString(locale, "previousYear");
+ if (previousYear) {
+ defaultOptions.locale.previousYear = previousYear;
+ }
+ var nextYear = FormView.LanguageUtils.getTranslatedString(locale, "nextYear");
+ if (nextYear) {
+ defaultOptions.locale.nextYear = nextYear;
+ }
+ var previousSetOfYears = FormView.LanguageUtils.getTranslatedString(locale, "previousSetOfYears");
+ if (previousSetOfYears) {
+ defaultOptions.locale.previousSetOfYears = previousSetOfYears;
+ }
+ var nextSetOfYears = FormView.LanguageUtils.getTranslatedString(locale, "nextSetOfYears");
+ if (nextSetOfYears) {
+ defaultOptions.locale.nextSetOfYears = nextSetOfYears;
+ }
}
#isEditValueOrDisplayValue(value) {
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/.content.xml
deleted file mode 100644
index f75e671c00..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/.content.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/.content.xml
deleted file mode 100644
index 8d9a662fbb..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/.content.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/README.md b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/README.md
deleted file mode 100644
index 1823b9aa8e..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/README.md
+++ /dev/null
@@ -1,98 +0,0 @@
-
-Adaptive Form Date Picker (v2)
-====
-Adaptive Form Date Picker field component written in HTL.
-
-## Features
-
-* Provides the following type of input:
- * date
-* Allows replacing this component with other component (as mentioned below).
-
-### Use Object
-The Form Date Picker component uses the `com.adobe.cq.forms.core.components.models.form.DatePicker` Sling Model for its Use-object.
-
-### Edit Dialog Properties
-The following properties are written to JCR for this Form Date component and are expected to be available as `Resource` properties:
-
-1. `./jcr:title` - defines the label to use for this field
-2. `./hideTitle` - if set to `true`, the label of this field will be hidden
-3. `./name` - defines the name of the field, which will be submitted with the form data
-4. `./default` - defines the default value of the field
-5. `./description` - defines a help message that can be rendered in the field as a hint for the user
-6. `./required` - if set to `true`, this field will be marked as required, not allowing the form to be submitted until the field has a value
-7. `./requiredMessage` - defines the message displayed as tooltip when submitting the form if the value is left empty
-8. `./readOnly` - if set to `true`, the filed will be read only
-9. `./dataFormat` - defines the format in which the value exported/submitted
-10. `./editFormat` - defines the format in which the value will be edited by the user
-11. `./minimumDate` - define the minimum date input allowed for the field
-12. `./maximumDate` - define the maximum date input allowed for the field
-13. `./displayFormat` - define the template for display pattern (Reference can be found [here](https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns)).
-
-## Client Libraries
-The component provides a `core.forms.components.datePicker.v2.runtime` client library category that contains the Javascript runtime for the component.
-It should be added to a relevant site client library using the `embed` property.
-
-## BEM Description
-```
-BLOCK cmp-adaptiveform-datepicker
- ELEMENT cmp-adaptiveform-datepicker__label
- ELEMENT cmp-adaptiveform-datepicker__label-container
- ELEMENT cmp-adaptiveform-datepicker__widget
- ELEMENT cmp-adaptiveform-datepicker__questionmark
- ELEMENT cmp-adaptiveform-datepicker__shortdescription
- ELEMENT cmp-adaptiveform-datepicker__longdescription
- ELEMENT cmp-adaptiveform-datepicker__errormessage
-```
-
-### Note
-By placing the class names `cmp-adaptiveform-datepicker__label` and `cmp-adaptiveform-datepicker__questionmark` within the `cmp-adaptiveform-datepicker__label-container` class, you create a logical grouping of the label and question mark elements. This approach simplifies the process of maintaining a consistent styling for both elements.
-
-## JavaScript Data Attribute Bindings
-
-The following attributes must be added for the initialization of the date-picker component in the form view:
- 1. `data-cmp-is="adaptiveFormDatePicker"`
- 2. `data-cmp-adaptiveformcontainer-path="${formstructparser.formContainerPath}"`
-
-
-The following are optional attributes that can be added to the component in the form view:
-1. `data-cmp-valid` having a boolean value to indicate whether the field is currently valid or not
-2. `data-cmp-required` having a boolean value to indicate whether the field is currently required or not
-3. `data-cmp-readonly` having a boolean value to indicate whether the field is currently readonly or not
-4. `data-cmp-active` having a boolean value to indicate whether the field is currently active or not
-5. `data-cmp-visible` having a boolean value to indicate whether the field is currently visible or not
-6. `data-cmp-enabled` having a boolean value to indicate whether the field is currently enabled or not
-
-## Replace feature:
-We support replace feature that allows replacing Reset Button component to any of the below components:
-
-* Button
-* Email Input
-* Number Input
-* Reset Button
-* Submit Button
-* Telephone Input
-* Text Box
-* Text Input
-
-
-## Information
-* **Vendor**: Adobe
-* **Version**: v2
-* **Compatibility**: Cloud
-* **Status**: production-ready
-
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/.content.xml
deleted file mode 100644
index 491392d539..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/.content.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/.content.xml
deleted file mode 100644
index 5a6d805da1..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/.content.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css.txt
deleted file mode 100644
index 4eb7cf1e0d..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-###############################################################################
-# Copyright 2026 Adobe
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-###############################################################################
-
-#base=css
-datepickerview.css
-datepickerwidget.css
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css/datepickerview.css b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css/datepickerview.css
deleted file mode 100644
index 29bd2ce6f0..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css/datepickerview.css
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
- * Copyright 2026 Adobe
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-.cmp-adaptiveform-datepicker {
-
-}
-
-.cmp-adaptiveform-datepicker__widget {
-
-}
-
-.cmp-adaptiveform-datepicker__label {
-
-}
-.cmp-adaptiveform-datepicker__label-container{
-
-}
-
-.cmp-adaptiveform-datepicker__longdescription {
-
-}
-
-.cmp-adaptiveform-datepicker__shortdescription {
-
-}
-
-.cmp-adaptiveform-datepicker__questionmark {
-
-}
-
-.cmp-adaptiveform-datepicker__questionmark {
-
-}
\ No newline at end of file
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css/datepickerwidget.css b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css/datepickerwidget.css
deleted file mode 100644
index 44d9e25e85..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/css/datepickerwidget.css
+++ /dev/null
@@ -1,168 +0,0 @@
-/*******************************************************************************
- * Copyright 2026 Adobe
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-.datetimepicker {
- border: none;
- background-color: #FFF;
- display: none;
- position: absolute;
- cursor: default;
- z-index: 100;
- outline: solid #CCCCCC 2px;
- flex-direction: column;
- width: 433px;
-}
-
-.datetimepicker .dp-clear {
- overflow: auto;
- background-color: #F5F5F5;
- text-align: center;
-}
-
-.datetimepicker .dp-clear a {
- cursor: pointer;
- height: 40px;
- line-height: 40px;
- padding: 0px 5px 0px 5px;
- text-align: center;
- display: inline-block;
- font-size: 0.875rem;
- color: #6d6d6d;
-}
-
-.datetimepicker-notouch .dp-close a:hover {
- color: #c8bbff;
-}
-
-.datetimepicker .dp-header {
- height: 40px;
- line-height: 40px;
- color: #555555;
- margin-bottom: 5px;
- background-color: #E6E6E6;
- display: flex;
- justify-content: space-between;
-}
-
-.datetimepicker .dp-header .dp-leftnav,
-.datetimepicker .dp-header .dp-rightnav,
-.datetimepicker .dp-header .dp-caption {
- float: left;
- text-align: center;
- cursor: pointer;
- height: 40px;
-}
-
-.datetimepicker-notouch .dp-header .dp-caption:not(.disabled):hover {
- color: #969696;
-}
-
-.datetimepicker .dp-header .dp-rightnav {
- float: right;
- background: url("/etc.clientlibs/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/resources/rightnav.png") no-repeat center center;
- width: 40px;
-}
-
-.datetimepicker .dp-header .dp-leftnav {
- width: 40px;
- background: url("/etc.clientlibs/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/resources/leftnav.png") no-repeat center center;
-}
-
-.datetimepicker .dp-header .dp-rightnav:hover {
- background: url("/etc.clientlibs/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/resources/rightnav_hover.png") no-repeat center center;
-}
-
-.datetimepicker .dp-header .dp-leftnav:hover {
- background: url("/etc.clientlibs/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/resources/leftnav_hover.png") no-repeat center center;
-}
-
-.datetimepicker .view {
- display: none;
-}
-
-.datetimepicker .view ul {
- display: flex;
- justify-content: space-around;
- list-style: none;
- margin: 0;
- padding: 5px;
- overflow: hidden;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
-}
-
-.datetimepicker .view ul li {
- float: left;
- padding: 5px;
- text-align: center;
- border: none;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- color: #666666;
- min-width:40px;
-}
-
-.datetimepicker .view ul.header li {
- color: #555555;
-}
-
-.datetimepicker .view ul:not(.header) li:not(.disabled) {
- cursor: pointer;
-}
-
-.datetimepicker .view ul.header {
- color: #000;
- background-color: #FFF;
- border-bottom: #E6E6E6 1px solid;
- display: flex;
- justify-content: space-around;
-}
-
-.datetimepicker-notouch .view ul:not(.header) li:not(.disabled):hover {
- color: black;
- background-color: #E6E6E6;
- opacity: 0.5;
-}
-
-.datetimepicker .view ul li.disabled {
- color: #CCCCCC;
-}
-
-.datetimepicker .view ul li.dp-selected {
- outline: none;
- background-color: #666666;
- color: #FFFFFF;
- opacity: 1.0;
-}
-
-.datetimepicker .view ul li.dp-focus {
- border: 1px dashed black;
-}
-
-.cmp-adaptiveform-datepicker__calendar-icon {
- position: absolute;
- top: 41px;
- right: 30px;
- z-index: 10;
- background: url("/etc.clientlibs/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/resources/calendar.png") no-repeat center center;
- background-size: contain;
- width: 24px;
- height: 24px;
-}
-
-.datefieldwidget.widgetreadonly .cmp-adaptiveform-datepicker__calendar-icon {
- display: none;
-}
\ No newline at end of file
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js.txt
deleted file mode 100644
index cef55fd8bf..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-###############################################################################
-# Copyright 2026 Adobe
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-###############################################################################
-
-#base=js
-cache.js
-datepickerview.js
-datepickerwidget.js
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/cache.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/cache.js
deleted file mode 100644
index bf938cd65d..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/cache.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * Copyright 2026 Adobe
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-(function() {
-
- "use strict";
- class Cache {
-
- store = {};
-
- put(el, key, value) {
- this.store[el.id ] = {};
- this.store[el.id][key] = value;
- }
-
- get(el, key) {
- return this.store[el.id][key];
- }
- }
- window.afCache = new Cache();
-})();
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/datepickerview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/datepickerview.js
deleted file mode 100644
index eef6a5d173..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/datepickerview.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/*******************************************************************************
- * Copyright 2026 Adobe
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-(function() {
-
- "use strict";
- class DatePicker extends FormView.FormFieldBase {
-
- static NS = FormView.Constants.NS;
- static IS = "adaptiveFormDatePicker";
- static bemBlock = 'cmp-adaptiveform-datepicker';
- static selectors = {
- self: "[data-" + this.NS + '-is="' + this.IS + '"]',
- widget: `.${DatePicker.bemBlock}__widget`,
- label: `.${DatePicker.bemBlock}__label`,
- description: `.${DatePicker.bemBlock}__longdescription`,
- qm: `.${DatePicker.bemBlock}__questionmark`,
- errorDiv: `.${DatePicker.bemBlock}__errormessage`,
- tooltipDiv: `.${DatePicker.bemBlock}__shortdescription`
- };
-
- constructor(params) {
- super(params);
- }
-
- getWidget() {
- return this.element.querySelector(DatePicker.selectors.widget);
- }
-
- getDescription() {
- return this.element.querySelector(DatePicker.selectors.description);
- }
-
- getLabel() {
- return this.element.querySelector(DatePicker.selectors.label);
- }
-
- getErrorDiv() {
- return this.element.querySelector(DatePicker.selectors.errorDiv);
- }
-
- getQuestionMarkDiv() {
- return this.element.querySelector(DatePicker.selectors.qm);
- }
-
- getTooltipDiv() {
- return this.element.querySelector(DatePicker.selectors.tooltipDiv);
- }
-
- updateValue(value) {
- if (this.widgetObject) {
- if (this.isActive()) {
- // Replacing undefined / null with empty string on reset
- this.widgetObject.setValue(value || '');
- } else {
- // Replacing undefined / null with empty string on reset
- this.widgetObject.setDisplayValue(value || '');
- }
- } else {
- // Replacing undefined / null with empty string on reset
- super.updateValue(value || '');
- }
- }
-
- updateReadOnly(readOnly, state) {
- super.updateReadOnly(readOnly, state);
- if (this.widgetObject != null) {
- this.widgetObject.markAsReadOnly(readOnly);
- }
- }
-
-
- setModel(model) {
- super.setModel(model);
- if (!this.#noFormats()) {
- if (this.widgetObject == null) {
- this.widgetObject = new DatePickerWidget(this, this.getWidget(), model);
- }
- if (this.isActive()) {
- this.widgetObject.setValue(model.value);
- } else {
- this.widgetObject.setDisplayValue(model.value);
- }
- this.widgetObject.addEventListener('blur', (e) => {
- this.setModelValue(this.widgetObject.getValue())
- //setDisplayValue is required for cases where value remains same while focussing in and out.
- this.widgetObject.setDisplayValue(this._model.value);
- this.widgetObject.setCalendarWidgetValue(this._model.value);
- this.setInactive();
- this.triggerExit();
- }, this.getWidget());
- this.widgetObject.addEventListener('focus', (e) => {
- this.widgetObject.setValue(e.target.value);
- this.setActive();
- this.triggerEnter();
- }, this.getWidget());
- this.widgetObject.addEventListener('input', (e) => {
- if( e.target.value === '') {
- // clear the value if user manually empties the value in date input box
- this.setModelValue("");
- }
- }, this.getWidget());
- } else {
- if (this.widget.value !== '') {
- this.setModelValue(this.widget.value);
- }
- this.widget.addEventListener('blur', (e) => {
- this.setModelValue(e.target.value);
- this.setInactive();
- this.triggerExit();
- });
- this.widget.addEventListener('focus', (e) => {
- this.setActive();
- this.triggerEnter();
- });
- }
- }
-
- #noFormats() {
- return (this._model.editFormat == null || this._model.editFormat === 'date|short') &&
- (this._model.displayFormat == null || this._model.displayFormat === 'date|short') && (this._model.displayValueExpression == null)
- }
- }
-
- FormView.Utils.setupField(({element, formContainer}) => {
- return new DatePicker({element, formContainer})
- }, DatePicker.selectors.self);
-})();
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/datepickerwidget.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/datepickerwidget.js
deleted file mode 100644
index 0a6ccfa02c..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/clientlibs/site/js/datepickerwidget.js
+++ /dev/null
@@ -1,1345 +0,0 @@
-/*******************************************************************************
- * Copyright 2026 Adobe
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-if (typeof window.DatePickerWidget === 'undefined') {
-
- window.DatePickerWidget = class {
-
- #widget = null;
- #model = null // passed by reference
- #options = null
-
- #lang = "en";
-
- #dp = null;
- #curInstance = null;
- #calendarIcon = null;
- #documentTouchListener = null;
- static #visible = false;
- static #clickedWindow;
-
- /** default configuration options
- *
- * yearsPerView: number of years to show in the yearset view
- *
- * width: with of the widget
- *
- * viewHeight: Height of the month,year and yearset view. This doesn't include
- * the height of the header
- *
- * locale: locale information for the locale in which to show the datepicker which comprises of
- * days: day names to display in the monthview
- * months: month names to display in the yearview
- * zero: string representation of zero in the locale. Numbers will be
- * displayed in that locale only
- * clearText: Text to display for the reset button
- * name: name of the locale
- *
- * format: input format for the datepicker (not implemented)
- *
- * pickerType: type of the datetimepicker (date, datetime and time)
- *
- * positioning: element around which datepicker will be displayed. if null then it
- * will be displayed around the input element
- *
- * showCalendarIcon: to show the Calendar on the right of the text field or not
- */
- #defaultOptions = {
- yearsPerView: 16,
- width: 340,
- viewHeight: 248,
- locale: {
- days: ["S","M","T","W","T","F","S"],
- months: ["January","February","March","April","May","June","July","August","September","October","November","December"],
- zero: "0",
- clearText: "Clear",
- openCalendarText: "Open calendar",
- name: "en_US"
- },
- format: "YYYY-MM-DD",
- pickerType: "date",
- positioning: null,
- showCalendarIcon: true
- }
-
- #dates = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
- /*
- * Actions to perform when clicked on the datepicker buttons
- * for different views
- * caption: view to show when clicked on caption
- * (Year/YearSet/Month/null) null means don't change the view
- * li: view to show when clicked on date, month or year element
- * upDown: add(up key) or subtract(down key) current date (for monthview),
- * month(Year View) or year(YearSetView) with the number provided
- * key: identifies the key that needs to be changed for that view
- */
- #viewAction = {
- Month: {
- caption: 'Year',
- li: null,
- key: "day",
- upDown: 7
- },
- Year: {
- caption: "Yearset",
- li: "Month",
- key: "month",
- upDown: 3
- },
- Yearset: {
- caption: null,
- li: "Year",
- key: "year",
- upDown: 4
- }
- }
-
- selectedDay = 0;
- selectedMonth = 0;
- selectedYear = 0;
- currentDay = 0;
- currentMonth = 0;
- currentYear = 0;
- //view="Month";
- #touchSupported = !!("ontouchstart" in window || window.DocumentTouch
- && document instanceof DocumentTouch);
- #defaultView = "Month";
- #keysEnabled = false;
- #focusedOnLi = false;
- #keyboardAccessibility = true;
- #scriptFocus;
-
- /* template for the clear Button */
- #clearButtonTemplate = '
';
-
- /* template for the calendar
- * header contains the navigation icons (left and right arrows)
- * and the current caption (which can be date, year or month)
- *
- * monthview displays the grid for showing the dates for a particular
- * month
- *
- * yearview displays all the months of that year
- *
- * yearsetview displays a grid of 16 years. This can be configured
- * through the option: yearsPerView
- *
- */
- #calendarTemplate = '' +
- '' +
- '' +
- '';
-
- constructor(view, widget, model) {
- this.#model = model;
- this.#lang = view.getModel().lang;
- let editValFn = () => {
- return model.editValue;
- };
- let displayValueFn = () => {
- return model.displayValue;
- };
- this.#localizeDateElements(this.#defaultOptions, this.#lang);
- this.#options = Object.assign(
- {editValue: editValFn, displayValue: displayValueFn},
- this.#defaultOptions, this.#model._jsonModel);
-
- this.#initialiseCalenderElement();
-
- //update widget markup to have input type=text element.
- let newDatePickerElement = widget.cloneNode(true);
- newDatePickerElement.setAttribute("type", "text");
- newDatePickerElement.id = model.id + '-widget';
-
- widget.parentNode.replaceChild(newDatePickerElement, widget);
- this.#widget = view.getWidget();
- this.#attachField(view.getWidget(), this.#options);
- }
-
- #initialiseCalenderElement() {
- let self = this,
- html = "";
- if (this.#options.pickerType.match(/date/)) {
- html += this.#calendarTemplate;
- }
- html += this.#clearButtonTemplate;
-
- if (!this.#dp) {
- this.#dp = document.createElement("div");
- this.#dp.classList.add("datetimepicker", "datePickerTarget");
- this.#dp.innerHTML = html;
- //Always inserting it in body
- document.body.appendChild(this.#dp);
- }
- // attach click event on entire datePicker popup
- this.#dp.addEventListener("click",
- function (evnt) {
- //focus only if the device doesn't support touch
- // input otherwise on screen keyboard will popup
- if (!self.#touchSupported) {
- if (self.#curInstance) {
- self.#curInstance.$field.focus();
- }
- }
- }, false);
- "touchstart mousedown".split(" ").forEach(function (e) {
- self.#dp.addEventListener(e, function (evt) {
- self.#checkWindowClicked(evt)
- }, false);
- });
-
- this.$month = this.#dp.getElementsByClassName("dp-monthview")[0];
- this.$year = this.#dp.getElementsByClassName("dp-yearview")[0];
- this.$yearset = this.#dp.getElementsByClassName("dp-yearsetview")[0];
-
- this.clear = this.#dp.getElementsByClassName(
- "dp-clear")[0].getElementsByTagName("a")[0];
- this.clear.addEventListener("click", function (evnt) {
- if (self.view && self.#curInstance) {
- self.#clearDate(self.view);
- }
- });
- this.prevNavWidthBtn = this.#dp.getElementsByClassName("dp-leftnav")[0];
- this.prevNavWidthBtn.setAttribute("role", "button");
- this.prevNavWidthBtn.addEventListener("click",
- function (evnt) {
- if (self.view && self.#curInstance) {
- self.#adjustDate(-1, self.view, false)
- }
- });
- this.nextNavWidthBtn = this.#dp.getElementsByClassName("dp-rightnav")[0];
- this.nextNavWidthBtn.setAttribute("role", "button");
- this.nextNavWidthBtn.addEventListener("click",
- function (evnt) {
- if (self.view && self.#curInstance) {
- self.#adjustDate(1, self.view, false)
- }
- });
- this.caption = this.#dp.getElementsByClassName("dp-caption")[0];
- this.caption.setAttribute("role", "button");
- this.caption.id = "dp-caption";
- this.caption.addEventListener("click",
- function (evnt) {
- if (self.view && self.#curInstance) {
- if (!self.caption.classList.contains("disabled")) {
- self.#layout(self.#viewAction[self.view].caption);
- }
- }
- });
- if (this.#keyboardAccessibility) {
- [this.prevNavWidthBtn, this.caption, this.nextNavWidthBtn,
- this.clear].forEach(function (elem, i) {
- elem.setAttribute("tabIndex", i + 1);
- });
- }
-
- }
-
- /*
- * attaches the date picker to the field. This is a one time operation
- * First creates a configuration object and stores it in the field data attributes
- * then attaches event handlers on click, focus (to show the picker) and blur (to hide) events
- */
- #attachField(widget, options) {
- let inst = this.#newInst(widget, options),
- self = this,
- activateField = function (evnt) {
- if (!self.#curInstance) {
- self.#activateField(evnt);
- }
-
- if (self.#options.showCalendarIcon) {
- if (evnt.type === self.#getEvent()) {
- if (self._iconClicked) {
- self._iconClicked = false;
- if (DatePickerWidget.#visible) {
- self.#hide(); // hide the calendar popup if visible when calendar icon is clicked
- self.#curInstance.$field.focus(); // bring back focus in field
- } else {
- self.#show(); //// show the calendar popup if not visible when calendar icon is clicked
- }
- }
- }
- } else {
- /*show the popup only if
- 1. click/touch event
- 2. focus event in case of non-touch devices and focus is not done using script
- */
- if (evnt.type === self.#getEvent() || (evnt.type === "focus"
- && !self.#touchSupported && !self.#scriptFocus)) {
- self.#show(evnt);
- }
- }
-
- DatePickerWidget.#clickedWindow = true;
- self.#scriptFocus = false;
- },
- deactivateField = function (evnt) {
- //deactivate only if clicked outside window
- // on touch devices only keyboard or calendar should be active at once, touching keyboard should deactivate calendar
- if ((DatePickerWidget.#clickedWindow && !self.#focusedOnLi)
- && (self.#options.showCalendarIcon || !self.#touchSupported)) {
- self.#hide();
- self.#deactivateField();
- DatePickerWidget.#clickedWindow = true;
- }
- };
-
- window.afCache.put(widget, "datetimepicker", inst);
-
- widget.addEventListener(this.#getEvent(), activateField);
- widget.onfocus = activateField;
- widget.onblur = deactivateField;
-
- if (options.showCalendarIcon) {
- let existingCalendarIcons = widget.parentNode.querySelectorAll('.cmp-adaptiveform-datepicker__calendar-icon');
- existingCalendarIcons.forEach(icon => icon.remove());
-
- let calendarIcon = document.createElement("div");
- calendarIcon.classList.add("cmp-adaptiveform-datepicker__calendar-icon");
-
- widget.parentNode.insertBefore(calendarIcon, widget.nextSibling);
-
- if (this.#keyboardAccessibility) {
- calendarIcon.setAttribute("tabindex", 0);
- }
- // Accessibility attributes for calendar icon button
- calendarIcon.setAttribute("role", "button");
- calendarIcon.setAttribute("aria-label", this.#options?.locale?.openCalendarText || "Open calendar");
- calendarIcon.addEventListener(this.#getEvent(), function (evnt) {
- self._iconClicked = true;
- widget.click();
- });
- calendarIcon.addEventListener("keydown", function (event) {
- if (event.keyCode === 32 || event.keyCode === 13) {
- event.preventDefault();
- event.stopPropagation();
- self._iconClicked = true;
- widget.click();
- }
- });
- this.#calendarIcon = calendarIcon;
- if (options.readOnly) {
- this.markAsReadOnly(true)
- }
- }
- }
-
- markAsReadOnly(readonly) {
- if (readonly) {
- this.#calendarIcon.style.display = "none";
- } else {
- this.#calendarIcon.style.display = "";
- }
- }
-
- #newInst(widget, options) {
- return {
- $field: widget,
- locale: options.locale,
- positioning: options.positioning || widget,
- access: options.access,
- selectedDate: options.value,
- editValue: options.editValue,
- displayValue: options.displayValue,
- minValidDate: options.minimum,
- maxValidDate: options.maximum,
- exclMinDate: options.exclusiveMinimum,
- exclMaxDate: options.exclusiveMaximum
- }
- }
-
- /*
- * To check where the click happened, if happened outside the datepicker
- * then hide the picker. This is checked whether any ancestor of clicked target
- * has a class datePickerTarget. This class is added to the attached element as well
- */
- #checkWindowClicked(evnt) {
- let self = this;
- if (self.#curInstance) {
- // datepickerTarget class depicts that the component is a part of the Date Field
- // and on click of that class, we should not hide the datepicker or fire exit events.
- if (!evnt.target.closest(".datePickerTarget")) {
- //non-touch devices do not deactivate on blur. Hence needs to be done here
- if (self.#touchSupported) {
- self.#hide();
- //clicking outside a field doesn't blur the field in IPad. Doing it by script
- self.#curInstance.$field.blur();
- self.#deactivateField();
- } else {
- DatePickerWidget.#clickedWindow = true;
- }
- } else {
- DatePickerWidget.#clickedWindow = false;
- }
- }
- }
-
- /*
- * handling of key strokes. All the key strokes prevent the default browser action
- * unless specified otherwise
- * tab: set focus on calendar icon when dateinput field is active, navigates through date picker buttons when datepicker is open,
- * otherwise perform default browser action
- * escape: hides the datepicker
- * down arrow key: navigate the picker downwards by the number specified in actionView.upDown of the current View
- * up arrow key: navigate the picker upwards by the number specified in actionView.upDown of the current View
- * left arrow key: navigate the picker one unit of that view backward
- * right arrow key: navigate the picker one unit of that view forward
- * shift + up: perform the action that happens on clicking the caption (as specified in actionView.caption)
- * shift + left: perform the action that happens on clicking the left navigation button
- * shift + right: perform the action that happens on clicking the right navigation button
- * space/enter: triggers the click event for the current focused element from datepicker/ opens datepicker when calendar icon is focused.
- */
- #hotKeys(evnt) {
- var handled = false, date;
- switch (evnt.keyCode) {
- case 9: //tab
- // CQ-4239352 : Setting clickedWindow property to true on tabbing so that deactivateField logic gets executed
- // When clicking on "x" on input field in in IE and when selecting the content and releasing the mouse select outside the field
- // the click event is not trigerred on the field and hence activateField is not executed, so clickedWindow remains as false
- DatePickerWidget.#clickedWindow = true;
- handled = false;
- break;
- case 27://escape
- if (DatePickerWidget.#visible) {
- this.#hide();
- this.#curInstance.$field.focus();
- this.#deactivateField();
- handled = true;
- }
- break;
- case 32: //space
- case 13: // enter
- if (evnt.target.classList.contains("cmp-adaptiveform-datepicker__calendar-icon")) {
- if (!DatePickerWidget.#visible) {
- this.#show();
- handled = true;
- } else {
- this.$focusedDate.classList.add("dp-focus");
- handled = true;
- }
- }
- break;
- case 40: //down arrow key
- if (!DatePickerWidget.#visible) {
- this.#show();
- return;
- }
- this.$focusedDate.classList.add("dp-focus");
- break;
- }
-
- if (DatePickerWidget.#visible && this.#keysEnabled) {
- var v = this.#viewAction[this.view].key,
- updown = this.#viewAction[this.view].upDown;
- switch (evnt.keyCode) {
- case 9: // tab
- if (evnt.shiftKey) {
- if (evnt.target.classList.contains("dp-leftnav")
- || evnt.target.classList.contains("dp-focus")) {
- this.#hide();
- this.#curInstance.$field.focus();
- handled = true;
- } else {
- handled = false;
- }
- } else {
- const buttonTabindex = evnt.target.getAttribute("tabindex");
- if (buttonTabindex === '0') {
- if (evnt.target.tagName.toLocaleLowerCase() === "input") {
- this.#hide();
- handled = false;
- } else {
- this.prevNavWidthBtn.focus();
- handled = true;
- }
- } else if (buttonTabindex === '4') {
- this.#hide();
- this.#curInstance.$field.focus();
- handled = true;
- } else {
- handled = false;
- }
- }
- break;
- case 32: //select on space
- case 13: // select on enter
- this.hotKeyPressed = true;
- this.#focusedOnLi = false;
- if (!this.#focusedOnLi) {
- evnt.target.click();
- } else {
- if (this.$focusedDate) {
- this.$focusedDate.click() //todo
- }
- }
- this.hotKeyPressed = false;
- handled = true;
- break;
- case 37: //left arrow key
- if (evnt.shiftKey) {
- this.prevNavWidthBtn.click();
- } else {
- this.#adjustDate(-1, v, true);
- }
- handled = true;
- break;
- case 38: //up arrow key
- if (evnt.shiftKey) {
- this.caption.click();
- } else {
- this.#adjustDate(-updown, v, true);
- }
- handled = true;
- break;
- case 39: //right arrow key
- if (evnt.shiftKey) {
- this.nextNavWidthBtn.click();
- } else {
- this.#adjustDate(+1, v, true);
- }
- handled = true;
- break;
- case 40: //down arrow key
- this.#adjustDate(updown, v, true);
- handled = true;
- break;
- default:
- }
- }
- if (handled) {
- evnt.preventDefault();
- }
- }
-
- /*
- * show the datepicker. //TODO: migrate this to vanilla js
- */
- #show() {
- this.#options.locale = this.#curInstance.locale;
- if (!DatePickerWidget.#visible) {
- let date = new Date(),
- validDate,
- parsedDate;
- if (this.#curInstance.selectedDate) {
- validDate = this.#curInstance.selectedDate;
- } else if (this.#model.valid) {
- validDate = this.#model.value;
- }
- if (validDate) {
- parsedDate = validDate ? new Date(validDate) : null;
- date = (parsedDate == null || parsedDate == 'Invalid Date') ? date : parsedDate;
- }
- const timezoneOffset = date.getTimezoneOffset();
- date.setMinutes(date.getMinutes() + timezoneOffset);
- this.selectedDay = this.currentDay = date.getDate();
- this.selectedMonth = this.currentMonth = date.getMonth();
- this.selectedYear = this.currentYear = date.getFullYear();
- this.maxValidDate = this.#options.maximum ? new Date(
- this.#curInstance.maxValidDate) : null;
- this.minValidDate = this.#options.minimum ? new Date(
- this.#curInstance.minValidDate) : null;
- this.exclMaxDate = this.#curInstance.exclMaxDate;
- this.exclMinDate = this.#curInstance.exclMinDate;
- this.#dp.getElementsByClassName("dp-clear")[0].getElementsByTagName(
- "a")[0].innerText = this.#options.locale.clearText;
- this.#layout(this.#defaultView);
- this.#dp.style.display = "flex";
- this.#focusedOnLi = false;
- DatePickerWidget.#visible = true;
- this.#position();
- // Add document touch listener for mobile to close datepicker when tapping outside
- if (this.#touchSupported && !this.#documentTouchListener) {
- this.#documentTouchListener = (evt) => {
- if (DatePickerWidget.#visible && this.#curInstance) {
- this.#checkWindowClicked(evt);
- }
- };
- document.addEventListener("touchstart", this.#documentTouchListener, false);
- }
- if (this.#options.showCalendarIcon) {
- this.#curInstance.$field.setAttribute('readonly', true); // when the datepicker is active, deactivate the field
- }
- }
-
- // Disabling the focus on ipad due to a bug where value of
- // date picker is not being set
- // Removing this code will only hamper one use case
- // where on ipad if you click on the calander then
- // the field becomes read only so
- // there is no indication where the current focus is
- // And if you remove this foucs code all together
- // then what happens is that on desktop MF in iframe the exit event
- // is not getting called hence calander getting remained open even
- // when you click somewhere on window or focus into some other field
- if (this.#options.showCalendarIcon && !this.#touchSupported) {
- this.#curInstance.$field.focus(); // field loses focus after being marked readonly, causing blur event not to be fired later
- }
- }
-
- /*
- * position the datepicker around the positioning element //TODO: migrate this to vanilla js
- * provided in the options
- */
- #position() {
- let $elem = this.#curInstance.positioning,
- windowScrollX = window.scrollX,
- windowScrollY = window.scrollY,
- windowInnerHeight = window.innerHeight,
- windowInnerWidth = window.innerWidth,
- inputRect = $elem.getBoundingClientRect(),
- height = $elem.offsetHeight,
- top = this.#getOffset($elem).top + height,
- left = this.#getOffset($elem).left,
- styles = {"top": (top + "px"), "left": (left + "px")},
- diffBottom = top + this.#dp.offsetHeight - windowInnerHeight - windowScrollY, //this.#dp.offsetHeight is the widget's height
- newLeft,
- newTop;
- if (diffBottom > 0) {
- //can't appear at the bottom
- //check top
- newTop = top - height - this.#dp.offsetHeight - 20;
- if (newTop < windowScrollY) {
- //can't appear at the top as well ... the datePicker pop up overlaps the date field
- newTop = top - diffBottom;
- }
- styles.top = newTop + "px";
- }
- if (left + this.#dp.offsetWidth > windowScrollX + windowInnerWidth) {
- //align with the right edge
- newLeft = windowScrollX + windowInnerWidth - this.#dp.offsetWidth - 20;
- styles.left = newLeft + "px";
- }
- this.#dp.style.top = styles.top;
- this.#dp.style.left = styles.left;
- const localeObj = new Intl.Locale(this.#lang);
- if(localeObj?.textInfo?.direction == "rtl") {
- let right = windowInnerWidth - (left + inputRect.width); // Calculate right offset
- if (right + this.#dp.offsetWidth > windowInnerWidth) { // this.#dp.offsetWidth is the widget's width
- // Align with the right edge of the viewport
- right = windowScrollX + windowInnerWidth - this.#dp.offsetWidth - 20; // Adjust with a 20px margin
- }
- this.#dp.style.right = right + "px";
- this.#dp.style.left = "unset"
- }
- return this;
- }
-
- #getOffset(elem) {
- let box = elem.getBoundingClientRect();
- return {
- top: box.top + window.scrollY,
- left: box.left + window.scrollX
- };
- }
-
- /*
- * layout the nextView. if nextView is null return
- *
- */
- #layout(nextView) {
- if (nextView == null) {
- this.#hide();
- } else {
- if (this.view) {
- this['$' + this.view.toLowerCase()].style.display = "none";
- }
- this.view = nextView;
- this.caption.classList.toggle("disabled",
- !this.#viewAction[this.view].caption);
- let ariaLabel = "";
- if (this.view === "Month") {
- ariaLabel = this.#options.locale.months[this.currentMonth] + " " + this.currentYear;
- this.prevNavWidthBtn.setAttribute(
- "aria-label",
- this.#options.locale.previousMonth || "Previous month"
- );
- this.nextNavWidthBtn.setAttribute(
- "aria-label",
- this.#options.locale.nextMonth || "Next month"
- );
- } else if (this.view === "Year") {
- ariaLabel = this.currentYear;
- this.prevNavWidthBtn.setAttribute(
- "aria-label",
- this.#options.locale.previousYear || "Previous year"
- );
- this.nextNavWidthBtn.setAttribute(
- "aria-label",
- this.#options.locale.nextYear || "Next year"
- );
- } else if (this.view === "Yearset") {
- const startYear = this.currentYear - this.#options.yearsPerView / 2;
- const endYear = startYear + this.#options.yearsPerView - 1;
- ariaLabel = startYear + "-" + endYear;
- this.prevNavWidthBtn.setAttribute(
- "aria-label",
- this.#options.locale.previousSetOfYears || "Previous set of years"
- );
- this.nextNavWidthBtn.setAttribute(
- "aria-label",
- this.#options.locale.nextSetOfYears || "Next set of years"
- );
- }
- this['$' + this.view.toLowerCase()].style.display = "block";
- this["show" + this.view]();
- }
- return this;
- }
-
- /*
- * show the month view
- */
- showMonth() {
- var self = this,
- curDate = new Date(this.currentYear, this.currentMonth),
- maxDay = this.#maxDate(this.currentMonth),
- prevMaxDay = this.#maxDate((this.currentMonth + 11) % 12),
- day1 = new Date(this.currentYear, this.currentMonth, 1).getDay(),
- data, display;
- var localizedYear = this.#getLocalizedYear(curDate);
-
- this.#tabulateView(
- {
- caption: this.#options.locale.months[this.currentMonth] + ", "
- + this.#convertNumberToLocale(localizedYear),
- header: this.#options.locale.days,
- numRows: 7,
- numColumns: 7,
- elementAt: function (row, col) {
- var day = (row - 1) * 7 + col - day1 + 1;
- var monthVal = self.currentMonth + 1;
- let gridId = "day-" + day;
- display = self.#convertNumberToLocale(day);
- data = day;
- if (day < 1) {
- display = self.#convertNumberToLocale(prevMaxDay + day);
- data = -1;
- monthVal = self.currentMonth;
- } else if (day > maxDay) {
- display = self.#convertNumberToLocale(day - maxDay);
- data = -1;
- monthVal = self.currentMonth + 2;
- } else {
- curDate.setDate(day);
- // check if the currentdate is valid based on max and min valid date
- if (self.#compareVal(curDate, self.maxValidDate,
- self.exclMaxDate) || self.#compareVal(self.minValidDate,
- curDate, self.exclMinDate)) {
- data = -1;
- }
- }
- return {
- data: data,
- gridId: gridId,
- display: display,
- ariaLabel: self.#options.editValue(
- self.currentYear + "-" + self.#pad2(monthVal)
- + "-" + self.#pad2(display))
- };
- }
- });
- }
-
- /**
- * returns boolean based on val1, val2, checkEqual
- * For comparing date, use date object
- */
- #compareVal(val1, val2, checkEqual) {
- if (!val1 || !val2) {
- return false;
- }
-
- if (checkEqual) {
- return val1 >= val2;
- } else {
- return val1 > val2;
- }
- }
-
- /*
- * show the year view
- */
- showYear() {
- var self = this,
- minDate = this.minValidDate ? new Date(
- this.minValidDate.getFullYear(), this.minValidDate.getMonth())
- : null,
- maxDate = this.maxValidDate ? new Date(
- this.maxValidDate.getFullYear(), this.maxValidDate.getMonth())
- : null,
- curDate = new Date(this.currentYear, 0), //can't omit month, if only one param present it is treated as millisecond
- data,
- month;
- var localizedYear = this.#getLocalizedYear(curDate);
- this.#tabulateView(
- {
- caption: this.#convertNumberToLocale(localizedYear),
- numRows: 4,
- numColumns: 3,
- elementAt: function (row, col) {
- data = month = row * 3 + col;
- let gridId = "month-" + data;
- curDate.setMonth(month);
- if ((minDate && curDate < minDate) || (maxDate && curDate
- > maxDate)) {
- data = -1;
- }
- return {
- data: data,
- gridId: gridId,
- display: self.#options.locale.months[month],
- ariaLabel: self.#options.locale.months[month] + " "
- + self.currentYear
- };
- }
- });
- }
-
- #getLocalizedYear(date) {
- /*
- // Only Thai language return year according to Buddhist calendar, rest all languages follows gregorian calendar in practice.
- // The Buddhist Year in 2024 = 543 + 2024 = B.E. 2567 (reference https://wesak.org.my/calculating-b-e/)
- // Intl.DateTimeFormat#formatToParts returns number (2024) for all languages except for Thai (2567) & for Persian ('۱۴۰۳')
- // For Persian ('۱۴۰۳'), returned year is not in numbers that is breaking next flow.
- */
- if(this.#lang === 'th') {
- const dateFormat = new Intl.DateTimeFormat(this.#lang, {
- year: 'numeric'
- });
- const dateParts = dateFormat.formatToParts(date);
- const yearObject = dateParts.find(yearObject => yearObject.type === "year");
- const localizedYear = yearObject.value;
- return Number(localizedYear);
- }
- else {
- return Number(date.getFullYear());
- }
- }
-
- /*
- * show the year set view
- */
- showYearset() {
- var year,
- minDate = this.minValidDate ? new Date(
- this.minValidDate.getFullYear(), 0) : null,
- maxDate = this.maxValidDate ? new Date(
- this.maxValidDate.getFullYear() + 1, 0) : null,
- curDate = new Date(),
- data,
- self = this;
- var localizedYear = this.#getLocalizedYear(new Date(this.currentYear, 0)),
- localizedYearSet = this.#getLocalizedYear(new Date(self.currentYear, 0));
-
- this.#tabulateView(
- {
- caption: this.#convertNumberToLocale(
- localizedYear - this.#options.yearsPerView / 2) + "-"
- + this.#convertNumberToLocale(
- localizedYear - this.#options.yearsPerView / 2
- + this.#options.yearsPerView - 1),
- numRows: 4,
- numColumns: 4,
- elementAt: function (row, col) {
- data = year = localizedYearSet - 8 + (row * 4 + col);
- let gridId = "year-" + data;
- curDate.setFullYear(year);
- if ((minDate && curDate < minDate) || (maxDate && curDate
- > maxDate)) {
- data = -1;
- }
- return {
- "data": data,
- "gridId": gridId,
- "display": self.#convertNumberToLocale(year),
- ariaLabel: year
- };
- }
- });
- }
-
- insertRow(rowNum, rowArray, isHeader, elementAt) {
- let $view = this["$" + this.view.toLowerCase()],
- $row = $view.getElementsByTagName("ul")[rowNum],
- items, $li, element, $tmp,
- self = this;
- if (!$row) {
- let rowEl = document.createElement("ul");
- rowEl.removeAttribute("aria-label");
- rowEl.classList.toggle("header", isHeader);
- rowEl.setAttribute("role", "row");
- $row = $view.appendChild(rowEl);
- }
- items = $row.getElementsByTagName("li").length;
- while (items++ < rowArray.length) {
- let listItemEl = document.createElement("li");
- listItemEl.id = "li-" + elementAt(rowNum, items).gridId;
- listItemEl.setAttribute("role", isHeader ? "columnheader" : "gridcell");
- $tmp = $row.appendChild(listItemEl);
- if (!isHeader) {
- let cb = function (evnt) {
- self.#selectDate(evnt);
- };
- $tmp.addEventListener("click", cb);
- }
- }
-
- rowArray.forEach(function (el, index) {
- $li = $row.getElementsByTagName("li")[index];
- if (isHeader) {
- $li.innerText = rowArray[index];
- } else {
- element = rowArray[index];
- window.afCache.put($li, "value", element.data);
- if (self.#checkDateIsFocussed(element.data)) {
- if (self.$focusedDate) {
- self.$focusedDate.classList.remove("dp-focus");
- self.$focusedDate.setAttribute("tabindex", "-1");
- }
- self.$focusedDate = $li;
- if (self.#keysEnabled) {
- self.$focusedDate.classList.add("dp-focus")
- }
- }
- $li.setAttribute("title", element.ariaLabel);
- $li.setAttribute("aria-label", element.ariaLabel);
- $li.setAttribute("tabindex", -1);
- $li.classList.toggle("dp-selected",
- self.#checkDateIsSelected(element.data));
- $li.classList.toggle("disabled", element.data === -1);
- $li.innerText = element.display;
- }
- });
- return $row;
- }
-
- /*
- * creates a tabular view based on the options provided. The options that can be passed are
- * numRows: number of rows that needs rendering
- * numCols: number of columns that needs rendering
- * caption: text for the datepickers caption element
- * header: an array of elements that identifies the header row
- * elementAt: a function(row, column) that returns an object (data: , display: ) where
- * is the value to set for that view when the element at (row,column) is clicked and
- * is the value that will be visible to the user
- */
- #tabulateView(options) {
- var r = 0, rows = 0,
- row = [],
- c;
- this.caption.innerHTML = options.caption;
- if (options.header) {
- this.insertRow(r++, options.header, true, options.elementAt);
- }
- while (r < options.numRows) {
- c = 0;
- while (c < options.numColumns) {
- row[c] = options.elementAt(r, c);
- c++;
- }
- this.insertRow(r++, row, false, options.elementAt);
- }
- }
-
- #hotKeysCallBack = this.#hotKeys.bind(this);
-
- #activateField(evnt) {
- let self = this;
- this.#curInstance = window.afCache.get(evnt.target, "datetimepicker");
- // Issue LC-7049:
- // datepickerTarget should be added when activate the field and should be removed
- // after the fields gets deactivated.
- if (this.#options.showCalendarIcon) {
- this.#curInstance.$field.parentNode.classList.add("datePickerTarget");
- }
- //enable hot keys only for non touch devices
- if (!this.#touchSupported && !this.#keysEnabled) {
- document.addEventListener("keydown", self.#hotKeysCallBack);
- this.#keysEnabled = true;
- }
- }
-
- #deactivateField() {
- let self = this;
- if (self.#curInstance) {
- if (this.#keysEnabled) {
- document.removeEventListener("keydown", self.#hotKeysCallBack);
- this.#keysEnabled = false;
- }
- // Remove document touch listener if it exists
- if (this.#documentTouchListener) {
- document.removeEventListener("touchstart", this.#documentTouchListener);
- this.#documentTouchListener = null;
- }
- // Issue LC-7049:
- // datepickerTarget should be added when activate the field and should be removed
- // after the fields gets deactivated. Otherwise clicking on any other datefield
- // will not hide the existing datepicker
- if (this.#options.showCalendarIcon) {
- self.#curInstance.$field.parentNode.classList.remove(
- "datePickerTarget");
- }
- self.#curInstance = null;
- this.#hideAllViews();
- }
- }
-
- #hide() {
- if (DatePickerWidget.#visible) {
- this.#dp.style.display = "none";
- this.#hideAllViews();
- DatePickerWidget.#visible = false;
- if (this.#options.showCalendarIcon) {
- this.#curInstance.$field.removeAttribute('readonly'); // when the datepicker is deactivated, activate the field
- }
- }
- }
-
- #hideAllViews() {
- this['$month'].replaceChildren();
- this['$year'].replaceChildren();
- this['$yearset'].replaceChildren();
- this['$month'].style.display = "none";
- this['$year'].style.display = "none";
- this['$yearset'].style.display = "none";
- }
-
- #adjustDate(step, view, focus) {
- let maxDate, prevMaxDate;
- let _focus = focus || false;
- switch (view.toLowerCase()) {
- case "day":
- this.currentDay += step;
- maxDate = this.#maxDate(this.currentMonth)
- if (this.currentDay < 1) {
- prevMaxDate = this.#maxDate((this.currentMonth - 1 + 12) % 12);
- this.currentDay = prevMaxDate + this.currentDay;
- return this.#adjustDate(-1, "month", _focus);
- }
- if (this.currentDay > maxDate) {
- this.currentDay -= maxDate;
- return this.#adjustDate(+1, "month", _focus);
- }
- break;
- case "month":
- this.currentMonth += step;
- if (this.currentMonth > 11) {
- this.currentYear++;
- this.currentMonth = 0;
- }
- if (this.currentMonth < 0) {
- this.currentYear--;
- this.currentMonth = 11;
- }
- break;
- case "year":
- this.currentYear += step;
- break;
- case "yearset":
- this.currentYear += step * this.#options.yearsPerView;
- break;
- }
- this.#layout(this.view);
- if (_focus) {
- this.#focusedOnLi = true;
- this.$focusedDate.setAttribute("tabindex", 0);
- this.$focusedDate.focus();
- }
- }
-
- #checkDateIsSelected(data) {
- switch (this.view.toLowerCase()) {
- case "month":
- return this.currentYear === this.selectedYear && this.currentMonth
- === this.selectedMonth && data === this.selectedDay;
- case "year":
- return this.currentYear === this.selectedYear && this.selectedMonth
- === data;
- case "yearset":
- return this.selectedYear === data;
- }
- }
-
- #checkDateIsFocussed(data) {
- switch (this.view.toLowerCase()) {
- case "month":
- return data === this.currentDay;
- case "year":
- return this.currentMonth === data;
- case "yearset":
- return this.currentYear === data;
- }
- }
-
- #convertNumberToLocale(number) {
- const zeroCode = this.#options.locale.zero.charCodeAt(0);
- number += "";
- let newNumber = [];
- for (let i = 0; i < number.length; i++) {
- newNumber.push(
- String.fromCharCode(zeroCode + parseInt(number.charAt(i))));
- }
- return newNumber.join("");
- }
-
- #clearDate(view) {
- this.#model.dispatch(new FormView.Actions.UIChange({'value': ''}));
- let existingSelectedItem = this['$' + view.toLowerCase()].getElementsByClassName("dp-selected")[0];
- if (existingSelectedItem) {
- existingSelectedItem.classList.remove("dp-selected");
- }
- }
-
- #getEvent() {
- return "click";//this.#touchSupported ? "touchstart" : "click";
- }
-
- #pad2(m) {
- return m = m < 10 ? "0" + m : m;
- }
-
- toString() {
- if(this.selectedYear === -1 || this.selectedMonth === -1 || this.selectedDay === -1){
- return "";
- }
- const formattedDate = `${this.selectedYear}-${this.#pad2(this.selectedMonth + 1)}-${this.#pad2(this.selectedDay)}`;
- return formattedDate;
- }
-
- #selectDate(evnt) {
- let val = window.afCache.get(evnt.target, "value"),
- nextView = this.#viewAction[this.view].li;
-
- //disabled dates have a value of -1. Do nothing in that case
- if (val === -1) {
- return;
- }
- switch (this.view.toLowerCase()) {
- case "month":
- this.selectedMonth = this.currentMonth;
- this.selectedYear = this.currentYear;
- this.selectedDay = val;
- this.setValue(this.toString());
- this.#model.dispatch(new FormView.Actions.UIChange({'value': this.toString()})); // updating model value to the latest when calender is changed
- this.#curInstance.$field.focus();
- let existingSelectedElement = this['$'
- + this.view.toLowerCase()].getElementsByClassName("dp-selected")[0];
- if (existingSelectedElement) {
- existingSelectedElement.classList.remove("dp-selected");
- }
- evnt.target.classList.add("dp-selected");
- break;
- case "year":
- this.currentMonth = val;
- break;
- case "yearset":
- this.currentYear = val;
- break;
- }
- this.#layout(nextView);
- //manually focus on the field if clicked on the popup buttons for non-touch device
- if (!this.#touchSupported) {
- //No need to focus if selection is made by pressing space.
- if (!this.hotKeyPressed) {
- this.#scriptFocus = true;
- }
- } else if (nextView == null) {
- //For touch devices, deactivate the field if a selection is made
- this.#deactivateField()
- }
- }
-
- #leapYear() {
- return this.currentYear % 400 === 0 || (this.currentYear % 100 !== 0
- && this.currentYear % 4 === 0);
- }
-
- #maxDate(m) {
- if (this.#leapYear() && m === 1) {
- return 29;
- } else {
- return this.#dates[m];
- }
- }
-
- #localizeDateElements(defaultOptions, locale) {
- var calendarSymbols = FormView.LanguageUtils.getTranslatedString(locale, "calendarSymbols");
- if (calendarSymbols && calendarSymbols.abbrdayNames) {
- defaultOptions.locale.days = calendarSymbols.abbrdayNames;
- }
- if (calendarSymbols && calendarSymbols.abbrdayNames) {
- defaultOptions.locale.months = calendarSymbols.monthNames;
- }
- var clearText = FormView.LanguageUtils.getTranslatedString(locale, "clearText");
- if (clearText) {
- defaultOptions.locale.clearText = clearText;
- }
- var openCalendarText = FormView.LanguageUtils.getTranslatedString(locale, "openCalendarText");
- if (openCalendarText) {
- defaultOptions.locale.openCalendarText = openCalendarText;
- }
- var zero = FormView.LanguageUtils.getTranslatedString(locale, "0");
- if (zero) {
- defaultOptions.locale.zero = zero;
- }
- var previousMonth = FormView.LanguageUtils.getTranslatedString(locale, "previousMonth");
- if (previousMonth) {
- defaultOptions.locale.previousMonth = previousMonth;
- }
- var nextMonth = FormView.LanguageUtils.getTranslatedString(locale, "nextMonth");
- if (nextMonth) {
- defaultOptions.locale.nextMonth = nextMonth;
- }
- var previousYear = FormView.LanguageUtils.getTranslatedString(locale, "previousYear");
- if (previousYear) {
- defaultOptions.locale.previousYear = previousYear;
- }
- var nextYear = FormView.LanguageUtils.getTranslatedString(locale, "nextYear");
- if (nextYear) {
- defaultOptions.locale.nextYear = nextYear;
- }
- var previousSetOfYears = FormView.LanguageUtils.getTranslatedString(locale, "previousSetOfYears");
- if (previousSetOfYears) {
- defaultOptions.locale.previousSetOfYears = previousSetOfYears;
- }
- var nextSetOfYears = FormView.LanguageUtils.getTranslatedString(locale, "nextSetOfYears");
- if (nextSetOfYears) {
- defaultOptions.locale.nextSetOfYears = nextSetOfYears;
- }
- }
-
- #isEditValueOrDisplayValue(value) {
- return (this.#model.editValue === value || this.#model.displayValue
- === value);
- }
-
- /**
- * returns the original value of format YYYY-MM-DD
- * @returns {*|string}
- */
- getValue() {
- if (this.#isEditValueOrDisplayValue(this.#widget.value)) {
- return this.#model.value; // if the widget has edit/display value thiss method should return model value
- }
- return this.#widget.value;
- }
-
- /**
- * Sets the formatted display value on the widget.
- * value should be in YYYY-MM-DD format
- * @param value
- */
- setDisplayValue(value) {
- if (this.#curInstance != null) {
- this.#curInstance.$field.value = this.#curInstance.displayValue(
- this.toString()) || value;
- } else {
- this.#widget.value = this.#model.displayValue || value;
- }
- }
-
- setCalendarWidgetValue(value) {
- if (this.#curInstance === null && this.#widget != null) {
- this.#curInstance = window.afCache.get(this.#widget, "datetimepicker");
- }
- if (this.#curInstance != null) {
- // also change the date of the calendar widget
- this.#curInstance.selectedDate = value;
- }
- }
-
- /**
- * Sets the formatted edit value on the widget
- * @param value
- */
-
- setValue(value) {
- let currDate;
- if (value instanceof Date && !isNaN(value)) {
- // If value is already a Date object and it's valid, use it as is
- currDate = value;
- } else {
- // Check if value is empty
- if (!value || value.trim() === '') {
- currDate = new Date();
- } else {
- let displayFormat = this.#model._jsonModel?.displayFormat;
- // If displayFormat is null/undefined, use default parsing
- if (!displayFormat) {
- currDate = new Date(value);
- } else {
- // Use FormView.Formatters.parseDate for custom formats
- currDate = FormView.Formatters.parseDate(value, this.#lang || 'en', displayFormat);
- // If parseDate failed (returned null), fallback to default parsing
- if (currDate === null) {
- currDate = new Date(value);
- }
- const timezoneOffset = currDate.getTimezoneOffset();
- currDate.setMinutes(currDate.getMinutes() + timezoneOffset);
- }
- }
- }
-
- if (!isNaN(currDate) && value != null) {
- //in case the value is directly updated from the field without using calendar widget
- this.selectedMonth = currDate.getMonth();
- this.selectedYear = currDate.getFullYear();
- this.selectedDay = currDate.getDate();
- } else {
- this.selectedYear
- = this.selectedMonth
- = this.selectedDay
- = -1;
- }
- if (this.#curInstance != null) {
- if (!this.#isEditValueOrDisplayValue(value)) {
- this.#curInstance.selectedDate = value; // prevent edit/display value from getting set in calender
- }
- this.#curInstance.$field.value = this.#curInstance.editValue() || value;
- } else {
- this.#widget.value = value;
- }
- }
-
- addEventListener(event, handler, widget) {
- let inst = window.afCache.get(widget, "datetimepicker");
- inst.$field.addEventListener(event, function (e) {
- switch (e.type) {
- case 'blur':
- if (!DatePickerWidget.#visible) {
- handler(e);
- }
- break;
- case 'focus':
- handler(e);
- break;
- case 'input':
- handler(e);
- break;
-
- }
- });
- }
-
- }
-}
\ No newline at end of file
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/datepicker.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/datepicker.html
deleted file mode 100644
index 56adb894d3..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/datepicker.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/datepicker.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/datepicker.js
deleted file mode 100644
index 38ab6b3dd1..0000000000
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v2/datepicker/datepicker.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*******************************************************************************
- * Copyright 2026 Adobe
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-use(function () {
- var clientlibsArr = ['core.forms.components.base.v1.editor'];
- var labelPath = 'core/fd/components/af-commons/v1/fieldTemplates/label.html';
- var shortDescriptionPath = "core/fd/components/af-commons/v1/fieldTemplates/shortDescription.html";
- var longDescriptionPath = "core/fd/components/af-commons/v1/fieldTemplates/longDescription.html";
- var questionMarkPath = "core/fd/components/af-commons/v1/fieldTemplates/questionMark.html"
- var errorMessagePath = "core/fd/components/af-commons/v1/fieldTemplates/errorMessage.html";
- return {
- labelPath: labelPath,
- shortDescriptionPath: shortDescriptionPath,
- longDescriptionPath: longDescriptionPath,
- questionMarkPath: questionMarkPath,
- errorMessagePath: errorMessagePath,
- clientlibs: clientlibsArr
- }
-});
\ No newline at end of file
diff --git a/ui.tests/test-module/specs/datepicker/datepickerv2.runtime.cy.js b/ui.tests/test-module/specs/datepicker/datepickerv2.runtime.cy.js
deleted file mode 100644
index 371fab3a19..0000000000
--- a/ui.tests/test-module/specs/datepicker/datepickerv2.runtime.cy.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright 2026 Adobe
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-describe("Form Runtime with Date Picker v2", () => {
-
- const pagePath = "content/forms/af/core-components-it/samples/datepicker/basic.html";
- const bemBlock = "cmp-adaptiveform-datepicker";
- let formContainer = null;
-
- beforeEach(() => {
- cy.previewForm(pagePath).then(p => {
- formContainer = p;
- });
- });
-
- const openFirstDatepickerCalendar = () => {
- cy.get(`.${bemBlock}__calendar-icon`).first().as("calendarIcon");
- cy.get("@calendarIcon").should("exist").click({ force: true });
- cy.get(".datetimepicker").should("be.visible");
- cy.get(".dp-monthview").should("exist");
- };
-
- it("should open calendar with keyboard on calendar icon (Space/Enter)", () => {
- expect(formContainer, "formcontainer is initialized").to.not.be.null;
- cy.get(`.${bemBlock}__calendar-icon`).first().as("calendarIcon");
- cy.get("@calendarIcon").should("exist").focus();
-
- cy.get("@calendarIcon").type(" ", { force: true });
- cy.get(".datetimepicker").should("be.visible");
- cy.get(".dp-monthview").should("exist");
-
- cy.get("body").click(0, 0, { force: true });
- cy.get(".datetimepicker").should("not.be.visible");
-
- cy.get("@calendarIcon").focus().type("{enter}", { force: true });
- cy.get(".datetimepicker").should("be.visible");
- cy.get(".dp-monthview").should("exist");
- });
-});
-
-