diff --git a/src/Forms/Tags.php b/src/Forms/Tags.php index 83bf34f3b52..a5f98d47e8b 100644 --- a/src/Forms/Tags.php +++ b/src/Forms/Tags.php @@ -4,6 +4,7 @@ use DebugBar\DataCollector\ConfigCollector; use DebugBar\DebugBarException; +use Illuminate\Support\Collection; use Statamic\Contracts\Forms\Form as FormContract; use Statamic\Facades\Antlers; use Statamic\Facades\Blink; @@ -161,8 +162,20 @@ public function fields() collect($this->context['fields']) ->each(fn ($field) => $field['field']->slot($slot)); + $context = $this->context->all(); + + $fields = Arr::get($context, 'fields', []); + + if ($handle = $this->params->get('get')) { + $context['fields'] = $this->dottedContextFields($fields, recursive: true)->only($handle)->values()->all(); + } elseif ($only = $this->params->get('only')) { + $context['fields'] = $this->dottedContextFields($fields)->only(explode('|', $only))->values()->all(); + } elseif ($except = $this->params->get('except')) { + $context['fields'] = $this->dottedContextFields($fields)->except(explode('|', $except))->values()->all(); + } + if ($isBlade) { - return $this->tagRenderer->render('@foreach($fields as $field)'.$this->content.'@endforeach', $this->context->all()); + return $this->tagRenderer->render('@foreach($fields as $field)'.$this->content.'@endforeach', $context); } $params = ''; @@ -171,7 +184,7 @@ public function fields() $params = Html::attributes(['scope' => $scope]); } - return Antlers::parse('{{ fields '.$params.' }}'.$this->content.'{{ /fields }}', $this->context->all()); + return Antlers::parse('{{ fields '.$params.' }}'.$this->content.'{{ /fields }}', $context); } /** @@ -427,4 +440,17 @@ public function eventUrl($url, $relative = true) config('statamic.routes.action').'/form/'.$url ); } + + private function dottedContextFields(array $fields, $recursive = false, array &$dotted = []): Collection + { + foreach ($fields as $field) { + $dotted[$field['handle']] = $field; + + if ($recursive && $fields = Arr::get($field, 'fields')) { + $this->dottedContextFields($fields, $recursive, $dotted); + } + } + + return collect($dotted); + } } diff --git a/src/Tags/Concerns/RendersForms.php b/src/Tags/Concerns/RendersForms.php index f7809e616ff..91242bd6ef5 100644 --- a/src/Tags/Concerns/RendersForms.php +++ b/src/Tags/Concerns/RendersForms.php @@ -150,7 +150,7 @@ protected function getRenderableField($field, $errorBag = 'default', $manipulate 'id' => $this->generateFieldId($field->handle(), $formHandle), 'instructions' => $field->instructions(), 'error' => $errors->first($field->handle()) ?: null, - 'default' => $field->value() ?? $field->defaultValue(), + 'default' => $default, 'old' => old($field->handle()), 'value' => $value, ], $field->fieldtype()->extraRenderableFieldData()); diff --git a/tests/Tags/Form/FormCreateTest.php b/tests/Tags/Form/FormCreateTest.php index 987c5f2c064..cc920f0da10 100644 --- a/tests/Tags/Form/FormCreateTest.php +++ b/tests/Tags/Form/FormCreateTest.php @@ -260,6 +260,66 @@ public function it_dynamically_renders_fields_using_legacy_array() $this->assertEquals(['Full Name', 'Email Address', 'Message'], $fieldOrder[1]); } + #[Test] + public function it_dynamically_renders_specific_fields_using_params() + { + $this->createForm([ + 'tabs' => [ + 'main' => [ + 'sections' => [ + [ + 'display' => 'Section One', + 'fields' => [ + ['handle' => 'first_name', 'field' => ['type' => 'text']], + ['handle' => 'middle_name', 'field' => ['type' => 'text', 'display' => 'Middle Name']], + ['handle' => 'last_name', 'field' => ['type' => 'text', 'display' => 'Last Name']], + [ + 'handle' => 'group_one', + 'field' => [ + 'type' => 'group', + 'display' => 'Group One', + 'fields' => [ + ['handle' => 'nested_one', 'field' => ['type' => 'text', 'display' => 'Nested One']], + ['handle' => 'nested_two', 'field' => ['type' => 'text', 'display' => 'Nested Two']], + ], + ], + ], + [ + 'handle' => 'group_two', + 'field' => [ + 'type' => 'group', + 'display' => 'Group Two', + 'fields' => [ + ['handle' => 'nested_three', 'field' => ['type' => 'text', 'display' => 'Nested One']], + ['handle' => 'nested_four', 'field' => ['type' => 'text', 'display' => 'Nested Two']], + ], + ], + ], + ], + ], + ], + ], + ], + ], 'survey'); + + $output = $this->normalizeHtml($this->tag(<<<'EOT' +{{ form:survey }} +