Hidden field can never be required. Skip that validation (#716)
* Hidden field can never be required. Skip that validation * Refactor form logic editor UI with improved text and styling - Replace UAlert with plain text description - Update action description text - Remove help text from select input - Simplify note about hidden field requirements * Add test for form logic field visibility and validation - Implement test case for fields hidden by logic conditions - Update AnswerFormRequest to use new FormLogicPropertyResolver method for hidden field check - Ensure required fields are skipped when hidden by form logic --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
parent
a5162192b1
commit
7b942997ce
|
|
@ -87,7 +87,10 @@ class AnswerFormRequest extends FormRequest
|
||||||
$data[$field['id']] = isset($tmpop['name']) ? $tmpop['name'] : $data[$field['id']];
|
$data[$field['id']] = isset($tmpop['name']) ? $tmpop['name'] : $data[$field['id']];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (FormLogicPropertyResolver::isRequired($property, $data)) {
|
if (
|
||||||
|
FormLogicPropertyResolver::isRequired($property, $data) &&
|
||||||
|
!FormLogicPropertyResolver::isHidden($property, $data)
|
||||||
|
) {
|
||||||
$rules[] = 'required';
|
$rules[] = 'required';
|
||||||
|
|
||||||
if ($property['type'] == 'checkbox') {
|
if ($property['type'] == 'checkbox') {
|
||||||
|
|
|
||||||
|
|
@ -543,3 +543,67 @@ it('handles invalid regex patterns gracefully', function () {
|
||||||
'message' => $validationMessage,
|
'message' => $validationMessage,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('skips validation for fields hidden by logic conditions', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
$workspace = $this->createUserWorkspace($user);
|
||||||
|
$form = $this->createForm($user, $workspace, [
|
||||||
|
'properties' => [
|
||||||
|
[
|
||||||
|
'id' => 'title',
|
||||||
|
'name' => 'Name',
|
||||||
|
'type' => 'title',
|
||||||
|
'hidden' => false,
|
||||||
|
'required' => true,
|
||||||
|
'logic' => [
|
||||||
|
'conditions' => [
|
||||||
|
'operatorIdentifier' => 'and',
|
||||||
|
'children' => [
|
||||||
|
[
|
||||||
|
'identifier' => 'email',
|
||||||
|
'value' => [
|
||||||
|
'operator' => 'is_empty',
|
||||||
|
'property_meta' => [
|
||||||
|
'id' => 'email_field',
|
||||||
|
'type' => 'email',
|
||||||
|
],
|
||||||
|
'value' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'actions' => ['hide-block'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'id' => 'email_field',
|
||||||
|
'name' => 'Email',
|
||||||
|
'type' => 'email',
|
||||||
|
'hidden' => false,
|
||||||
|
'required' => false,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Test when field should be hidden (email is empty)
|
||||||
|
$formData = ['email_field' => '']; // Empty email
|
||||||
|
$this->postJson(route('forms.answer', $form->slug), $formData)
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertJson([
|
||||||
|
'type' => 'success',
|
||||||
|
'message' => 'Form submission saved.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Test when field should be visible (email is not empty)
|
||||||
|
$formData = ['email_field' => 'test@example.com'];
|
||||||
|
$this->postJson(route('forms.answer', $form->slug), $formData)
|
||||||
|
->assertStatus(422)
|
||||||
|
->assertJson([
|
||||||
|
'message' => 'The Name field is required.',
|
||||||
|
'errors' => [
|
||||||
|
'title' => [
|
||||||
|
'The Name field is required.',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,9 @@
|
||||||
<h5 class="font-medium text-gray-700 mt-3">
|
<h5 class="font-medium text-gray-700 mt-3">
|
||||||
2. Actions
|
2. Actions
|
||||||
</h5>
|
</h5>
|
||||||
|
<p class="text-gray-500 text-xs mb-3">
|
||||||
|
Action(s) triggered when above conditions are true.
|
||||||
|
</p>
|
||||||
<flat-select-input
|
<flat-select-input
|
||||||
:key="resetKey"
|
:key="resetKey"
|
||||||
v-model="logic.actions"
|
v-model="logic.actions"
|
||||||
|
|
@ -52,11 +55,14 @@
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
class="mt-1"
|
class="mt-1"
|
||||||
placeholder="Actions..."
|
placeholder="Actions..."
|
||||||
help="Action(s) triggered when above conditions are true"
|
|
||||||
:options="actionOptions"
|
:options="actionOptions"
|
||||||
@update:model-value="onActionInput"
|
@update:model-value="onActionInput"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<p class="text-gray-500 text-xs mb-3">
|
||||||
|
Note that hidden fields can never be required.
|
||||||
|
</p>
|
||||||
|
|
||||||
<modal
|
<modal
|
||||||
max-width="sm"
|
max-width="sm"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue