diff --git a/config/custom-fields.php b/config/custom-fields.php index 50a2417..b113d8c 100644 --- a/config/custom-fields.php +++ b/config/custom-fields.php @@ -29,6 +29,7 @@ 'select' => \Givebutter\LaravelCustomFields\FieldTypes\SelectFieldType::class, 'textarea' => \Givebutter\LaravelCustomFields\FieldTypes\TextareaFieldType::class, 'text' => \Givebutter\LaravelCustomFields\FieldTypes\TextFieldType::class, + 'multiselect' => \Givebutter\LaravelCustomFields\FieldTypes\MultiselectFieldType::class, ], /* @@ -47,6 +48,7 @@ 'select' => \Givebutter\LaravelCustomFields\ResponseTypes\SelectResponseType::class, 'textarea' => \Givebutter\LaravelCustomFields\ResponseTypes\TextareaResponseType::class, 'text' => \Givebutter\LaravelCustomFields\ResponseTypes\TextResponseType::class, + 'multiselect' => \Givebutter\LaravelCustomFields\ResponseTypes\MultiselectResponseType::class, ], /* diff --git a/database/factories/CustomFieldFactory.php b/database/factories/CustomFieldFactory.php index 35cca8a..a4f2b5a 100644 --- a/database/factories/CustomFieldFactory.php +++ b/database/factories/CustomFieldFactory.php @@ -100,6 +100,16 @@ public function withTypeTextArea() return $this; } + /** + * @return $this + */ + public function withTypeMultiselect() + { + $this->model->type = CustomFieldType::MULTISELECT; + + return $this; + } + /** * @param $defaultValue * @return $this diff --git a/src/Enums/CustomFieldType.php b/src/Enums/CustomFieldType.php index c5a67ac..f15c523 100644 --- a/src/Enums/CustomFieldType.php +++ b/src/Enums/CustomFieldType.php @@ -10,12 +10,14 @@ enum CustomFieldType: string case SELECT = 'select'; case TEXT = 'text'; case TEXTAREA = 'textarea'; + case MULTISELECT = 'multiselect'; public function requiresAnswers(): bool { return in_array($this, [ self::RADIO, self::SELECT, + self::MULTISELECT, ]); } } diff --git a/src/FieldTypes/MultiselectFieldType.php b/src/FieldTypes/MultiselectFieldType.php new file mode 100644 index 0000000..b986164 --- /dev/null +++ b/src/FieldTypes/MultiselectFieldType.php @@ -0,0 +1,25 @@ +validationPrefix.$this->field->id => [ + $this->requiredRule($attributes['required']), + 'array', + ], + $this->validationPrefix.$this->field->id.'.*' => [ + 'required', + 'distinct', + 'string', + 'max:255', + Rule::in($this->field->answers), + ], + ]; + } +} \ No newline at end of file diff --git a/src/ResponseTypes/MultiselectResponseType.php b/src/ResponseTypes/MultiselectResponseType.php new file mode 100644 index 0000000..292960d --- /dev/null +++ b/src/ResponseTypes/MultiselectResponseType.php @@ -0,0 +1,17 @@ +getValue())) { + return ''; + } + + return implode(', ', $this->getValue()); + } +} \ No newline at end of file diff --git a/tests/Feature/CustomFieldControllerTest.php b/tests/Feature/CustomFieldControllerTest.php index b8c05e1..0733e65 100644 --- a/tests/Feature/CustomFieldControllerTest.php +++ b/tests/Feature/CustomFieldControllerTest.php @@ -290,6 +290,99 @@ function (TestCase $test, SurveyResponse $surveyResponse) { ]; } + /** + * @test + */ + public function multiselect_can_pass_validation(): void + { + $survey = Survey::create(); + $survey->customfields()->save( + CustomField::factory()->make([ + 'title' => 'Favorite Album', + 'type' => 'multiselect', + 'answers' => ['Tha Carter', 'Tha Carter II', 'Tha Carter III'], + ]) + ); + + Route::post("/surveys/{$survey->id}/responses", function (Request $request) use ($survey) { + $validator = $survey->validateCustomFields($request); + + if ($validator->fails()) { + return ['errors' => $validator->errors()]; + } + + return response('All good', 200); + }); + + $fieldId = CustomField::where('title', 'Favorite Album')->value('id'); + + $this + ->post("/surveys/{$survey->id}/responses", [ + 'custom_fields' => [ + $fieldId => [ + 'Tha Carter', + 'Tha Carter III', + ], + ], + ])->assertSee('All good'); + } + + /** + * @test + */ + public function multiselect_can_overwrite_values(): void + { + $survey = Survey::create(); + $surveyResponse = SurveyResponse::create(); + $field = $survey->customfields()->save( + CustomField::factory()->make([ + 'title' => 'Favorite Album', + 'type' => 'multiselect', + 'answers' => ['Tha Carter', 'Tha Carter II', 'Tha Carter III'], + ]) + ); + + Route::post("/surveys/{$survey->id}/responses", function (Request $request) use ($survey, $surveyResponse) { + $survey->validateCustomFields($request); + + $surveyResponse->saveCustomFields($request->custom_fields); + + return response('All good', 200); + }); + + // first time + $this + ->post("/surveys/{$survey->id}/responses", [ + 'custom_fields' => [ + $field->id => [ + 'Tha Carter II', + 'Tha Carter III', + ], + ], + ])->assertOk(); + + $this->assertSame(1, $field->responses()->count()); + $this->assertSame([ + 'Tha Carter II', + 'Tha Carter III', + ], $field->responses()->first()->value); + + // second time + $this + ->post("/surveys/{$survey->id}/responses", [ + 'custom_fields' => [ + $field->id => [ + 'Tha Carter I', + ], + ], + ])->assertOk(); + + $this->assertSame(1, $field->responses()->count()); + $this->assertSame([ + 'Tha Carter I', + ], $field->responses()->first()->value); + } + /** @test */ public function fields_can_be_saved_from_request_with_convenience_method() {