Option to block past/future dates (#24)
This commit is contained in:
parent
8b6814c373
commit
d694c4d8ce
|
@ -152,15 +152,25 @@ class AnswerFormRequest extends FormRequest
|
||||||
return ['email:filter'];
|
return ['email:filter'];
|
||||||
case 'date':
|
case 'date':
|
||||||
if (isset($property['date_range']) && $property['date_range']) {
|
if (isset($property['date_range']) && $property['date_range']) {
|
||||||
$this->requestRules[$property['id'].'.*'] = ['date'];
|
$this->requestRules[$property['id'].'.*'] = $this->getRulesForDate($property);
|
||||||
return ['array'];
|
return ['array', 'min:2'];
|
||||||
}
|
}
|
||||||
return ['date'];
|
return $this->getRulesForDate($property);
|
||||||
default:
|
default:
|
||||||
return [];
|
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
|
private function getSelectPropertyOptions($property): array
|
||||||
{
|
{
|
||||||
$type = $property['type'];
|
$type = $property['type'];
|
||||||
|
|
|
@ -102,6 +102,8 @@ abstract class UserFormRequest extends \Illuminate\Foundation\Http\FormRequest
|
||||||
'properties.*.use_am_pm' => 'boolean|nullable',
|
'properties.*.use_am_pm' => 'boolean|nullable',
|
||||||
'properties.*.date_range' => 'boolean|nullable',
|
'properties.*.date_range' => 'boolean|nullable',
|
||||||
'properties.*.prefill_today' => 'boolean|nullable',
|
'properties.*.prefill_today' => 'boolean|nullable',
|
||||||
|
'properties.*.disable_past_dates' => 'boolean|nullable',
|
||||||
|
'properties.*.disable_future_dates' => 'boolean|nullable',
|
||||||
|
|
||||||
// Select / Multi Select field
|
// Select / Multi Select field
|
||||||
'properties.*.allow_creation' => 'boolean|nullable',
|
'properties.*.allow_creation' => 'boolean|nullable',
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
:date-format="useTime?'Z':'Y-m-d'"
|
: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'"
|
:user-format="useTime ? amPm ? 'F j, Y - G:i K' : 'F j, Y - H:i' : 'F j, Y'"
|
||||||
:amPm="amPm"
|
:amPm="amPm"
|
||||||
|
:disabled-dates="disabledDates"
|
||||||
/>
|
/>
|
||||||
<small v-if="help" :class="theme.default.help">
|
<small v-if="help" :class="theme.default.help">
|
||||||
<slot name="help">{{ help }}</slot>
|
<slot name="help">{{ help }}</slot>
|
||||||
|
@ -32,7 +33,9 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
withTime: { type: Boolean, default: false },
|
withTime: { type: Boolean, default: false },
|
||||||
dateRange: { 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: () => ({
|
data: () => ({
|
||||||
|
@ -74,6 +77,15 @@ export default {
|
||||||
const dateInput = this.$refs.datepicker.$el.getElementsByTagName('input')[0]
|
const dateInput = this.$refs.datepicker.$el.getElementsByTagName('input')[0]
|
||||||
dateInput.style.setProperty('--tw-ring-color', this.color)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,6 +378,11 @@ export default {
|
||||||
if (field.use_am_pm) {
|
if (field.use_am_pm) {
|
||||||
inputProperties.amPm = true
|
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)) {
|
} else if (field.type === 'files' || (field.type === 'url' && field.file_upload)) {
|
||||||
inputProperties.multiple = (field.multiple !== undefined && field.multiple)
|
inputProperties.multiple = (field.multiple !== undefined && field.multiple)
|
||||||
inputProperties.mbLimit = 5
|
inputProperties.mbLimit = 5
|
||||||
|
|
|
@ -167,6 +167,20 @@
|
||||||
<p class="text-gray-400 mb-5">
|
<p class="text-gray-400 mb-5">
|
||||||
if enabled we will pre-fill this field with the current date
|
if enabled we will pre-fill this field with the current date
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<v-checkbox v-model="field.disable_past_dates"
|
||||||
|
name="disable_past_dates" class="mb-3"
|
||||||
|
@input="onFieldDisablePastDatesChange"
|
||||||
|
>
|
||||||
|
Disable past dates
|
||||||
|
</v-checkbox>
|
||||||
|
|
||||||
|
<v-checkbox v-model="field.disable_future_dates"
|
||||||
|
name="disable_future_dates" class="mb-3"
|
||||||
|
@input="onFieldDisableFutureDatesChange"
|
||||||
|
>
|
||||||
|
Disable future dates
|
||||||
|
</v-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- select/multiselect Options -->
|
<!-- select/multiselect Options -->
|
||||||
|
@ -484,6 +498,8 @@ export default {
|
||||||
if (this.field.prefill_today) {
|
if (this.field.prefill_today) {
|
||||||
this.$set(this.field, 'prefill', 'Pre-filled with current date')
|
this.$set(this.field, 'prefill', 'Pre-filled with current date')
|
||||||
this.$set(this.field, 'date_range', false)
|
this.$set(this.field, 'date_range', false)
|
||||||
|
this.$set(this.field, 'disable_future_dates', false)
|
||||||
|
this.$set(this.field, 'disable_past_dates', false)
|
||||||
} else {
|
} else {
|
||||||
this.$set(this.field, 'prefill', null)
|
this.$set(this.field, 'prefill', null)
|
||||||
}
|
}
|
||||||
|
@ -500,6 +516,20 @@ export default {
|
||||||
this.$set(this.field, 'allow_creation', false)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -83,4 +83,52 @@ it('can not submit draft form', function () {
|
||||||
|
|
||||||
$this->postJson(route('forms.answer', $form->slug), $formData)
|
$this->postJson(route('forms.answer', $form->slug), $formData)
|
||||||
->assertStatus(403);
|
->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.'
|
||||||
|
]);
|
||||||
});
|
});
|
Loading…
Reference in New Issue