diff --git a/app/Http/Requests/AnswerFormRequest.php b/app/Http/Requests/AnswerFormRequest.php
index 7cd1f3b..999586f 100644
--- a/app/Http/Requests/AnswerFormRequest.php
+++ b/app/Http/Requests/AnswerFormRequest.php
@@ -152,15 +152,25 @@ class AnswerFormRequest extends FormRequest
return ['email:filter'];
case 'date':
if (isset($property['date_range']) && $property['date_range']) {
- $this->requestRules[$property['id'].'.*'] = ['date'];
- return ['array'];
+ $this->requestRules[$property['id'].'.*'] = $this->getRulesForDate($property);
+ return ['array', 'min:2'];
}
- return ['date'];
+ return $this->getRulesForDate($property);
default:
return [];
}
}
+ private function getRulesForDate($property)
+ {
+ if (isset($property['disable_past_dates']) && $property['disable_past_dates']) {
+ return ['date', 'after_or_equal:today'];
+ }else if (isset($property['disable_future_dates']) && $property['disable_future_dates']) {
+ return ['date', 'before_or_equal:today'];
+ }
+ return ['date'];
+ }
+
private function getSelectPropertyOptions($property): array
{
$type = $property['type'];
diff --git a/app/Http/Requests/UserFormRequest.php b/app/Http/Requests/UserFormRequest.php
index e5fd267..ea9a0df 100644
--- a/app/Http/Requests/UserFormRequest.php
+++ b/app/Http/Requests/UserFormRequest.php
@@ -102,6 +102,8 @@ abstract class UserFormRequest extends \Illuminate\Foundation\Http\FormRequest
'properties.*.use_am_pm' => 'boolean|nullable',
'properties.*.date_range' => 'boolean|nullable',
'properties.*.prefill_today' => 'boolean|nullable',
+ 'properties.*.disable_past_dates' => 'boolean|nullable',
+ 'properties.*.disable_future_dates' => 'boolean|nullable',
// Select / Multi Select field
'properties.*.allow_creation' => 'boolean|nullable',
diff --git a/resources/js/components/forms/DateInput.vue b/resources/js/components/forms/DateInput.vue
index abddb1c..15e0ac7 100644
--- a/resources/js/components/forms/DateInput.vue
+++ b/resources/js/components/forms/DateInput.vue
@@ -13,6 +13,7 @@
:date-format="useTime?'Z':'Y-m-d'"
:user-format="useTime ? amPm ? 'F j, Y - G:i K' : 'F j, Y - H:i' : 'F j, Y'"
:amPm="amPm"
+ :disabled-dates="disabledDates"
/>
{{ help }}
@@ -32,7 +33,9 @@ export default {
props: {
withTime: { type: Boolean, default: false },
dateRange: { type: Boolean, default: false },
- amPm: { type: Boolean, default: false }
+ amPm: { type: Boolean, default: false },
+ disablePastDates: { type: Boolean, default: false },
+ disableFutureDates: { type: Boolean, default: false }
},
data: () => ({
@@ -74,6 +77,15 @@ export default {
const dateInput = this.$refs.datepicker.$el.getElementsByTagName('input')[0]
dateInput.style.setProperty('--tw-ring-color', this.color)
}
+ },
+ disabledDates (date) {
+ const today = new Date()
+ if(this.disablePastDates){
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate()) < new Date(today.getFullYear(), today.getMonth(), today.getDate())
+ } else if(this.disableFutureDates){
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate()) > new Date(today.getFullYear(), today.getMonth(), today.getDate())
+ }
+ return false;
}
}
}
diff --git a/resources/js/components/open/forms/OpenForm.vue b/resources/js/components/open/forms/OpenForm.vue
index 16bf259..9481e92 100644
--- a/resources/js/components/open/forms/OpenForm.vue
+++ b/resources/js/components/open/forms/OpenForm.vue
@@ -378,6 +378,11 @@ export default {
if (field.use_am_pm) {
inputProperties.amPm = true
}
+ if (field.disable_past_dates) {
+ inputProperties.disablePastDates = true
+ }else if (field.disable_future_dates) {
+ inputProperties.disableFutureDates = true
+ }
} else if (field.type === 'files' || (field.type === 'url' && field.file_upload)) {
inputProperties.multiple = (field.multiple !== undefined && field.multiple)
inputProperties.mbLimit = 5
diff --git a/resources/js/components/open/forms/fields/FormFieldOptionsModal.vue b/resources/js/components/open/forms/fields/FormFieldOptionsModal.vue
index fba165a..b37cbb5 100644
--- a/resources/js/components/open/forms/fields/FormFieldOptionsModal.vue
+++ b/resources/js/components/open/forms/fields/FormFieldOptionsModal.vue
@@ -167,6 +167,20 @@
if enabled we will pre-fill this field with the current date
+
+
+ Disable past dates
+
+
+
+ Disable future dates
+
@@ -484,6 +498,8 @@ export default {
if (this.field.prefill_today) {
this.$set(this.field, 'prefill', 'Pre-filled with current date')
this.$set(this.field, 'date_range', false)
+ this.$set(this.field, 'disable_future_dates', false)
+ this.$set(this.field, 'disable_past_dates', false)
} else {
this.$set(this.field, 'prefill', null)
}
@@ -500,6 +516,20 @@ export default {
this.$set(this.field, 'allow_creation', false)
}
},
+ onFieldDisablePastDatesChange (val) {
+ this.$set(this.field, 'disable_past_dates', val)
+ if (this.field.disable_past_dates) {
+ this.$set(this.field, 'disable_future_dates', false)
+ this.$set(this.field, 'prefill_today', false)
+ }
+ },
+ onFieldDisableFutureDatesChange (val) {
+ this.$set(this.field, 'disable_future_dates', val)
+ if (this.field.disable_future_dates) {
+ this.$set(this.field, 'disable_past_dates', false)
+ this.$set(this.field, 'prefill_today', false)
+ }
+ }
}
}
diff --git a/tests/Feature/Forms/AnswerFormTest.php b/tests/Feature/Forms/AnswerFormTest.php
index b89c820..8d6d98b 100644
--- a/tests/Feature/Forms/AnswerFormTest.php
+++ b/tests/Feature/Forms/AnswerFormTest.php
@@ -83,4 +83,52 @@ it('can not submit draft form', function () {
$this->postJson(route('forms.answer', $form->slug), $formData)
->assertStatus(403);
+});
+
+it('can not submit form with past dates', function () {
+ $user = $this->actingAsUser();
+ $workspace = $this->createUserWorkspace($user);
+ $form = $this->createForm($user, $workspace);
+
+ $submissionData = [];
+ $form->properties = collect($form->properties)->map(function ($property) use (&$submissionData) {
+ if(in_array($property['type'], ['date'])){
+ $property["disable_past_dates"] = true;
+ $submissionData[$property['id']] = now()->subDays(4)->format('Y-m-d');
+ }
+ return $property;
+ })->toArray();
+ $form->update();
+
+ $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData);
+
+ $this->postJson(route('forms.answer', $form->slug), $formData)
+ ->assertStatus(422)
+ ->assertJson([
+ 'message' => 'The Date must be a date after or equal to today.'
+ ]);
+});
+
+it('can not submit form with future dates', function () {
+ $user = $this->actingAsUser();
+ $workspace = $this->createUserWorkspace($user);
+ $form = $this->createForm($user, $workspace);
+
+ $submissionData = [];
+ $form->properties = collect($form->properties)->map(function ($property) use (&$submissionData) {
+ if(in_array($property['type'], ['date'])){
+ $property["disable_future_dates"] = true;
+ $submissionData[$property['id']] = now()->addDays(4)->format('Y-m-d');
+ }
+ return $property;
+ })->toArray();
+ $form->update();
+
+ $formData = FormSubmissionDataFactory::generateSubmissionData($form, $submissionData);
+
+ $this->postJson(route('forms.answer', $form->slug), $formData)
+ ->assertStatus(422)
+ ->assertJson([
+ 'message' => 'The Date must be a date before or equal to today.'
+ ]);
});
\ No newline at end of file