Skip to content

Commit

Permalink
[5.x] Allow form fields view to be rendered with single tag (#11293)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonvarga authored Dec 20, 2024
1 parent 460ab09 commit cfbe9d8
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 10 deletions.
7 changes: 5 additions & 2 deletions resources/views/extend/forms/fields.antlers.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
<sup aria-label="{{ trans:Required }}">*</sup>
{{ /if }}
</label>
<div class="p-2">{{ field }}</div>
{{ if instructions }}
{{ if instructions && instructions_position == "above" }}
<p class="text-gray-500" id="{{ id }}-instructions">{{ instructions }}</p>
{{ /if }}
<div class="py-2">{{ field }}</div>
{{ if instructions && instructions_position == "below" }}
<p class="text-gray-500" id="{{ id }}-instructions">{{ instructions }}</p>
{{ /if }}
{{ if error }}
Expand Down
21 changes: 21 additions & 0 deletions src/Forms/FieldsVariable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Statamic\Forms;

use Statamic\Fields\ArrayableString;

class FieldsVariable extends ArrayableString
{
public function __construct(array $fields = [])
{
parent::__construct(
view('statamic::forms.fields', ['fields' => $fields])->render(),
$fields
);
}

public function toArray()
{
return $this->extra;
}
}
2 changes: 1 addition & 1 deletion src/Forms/Tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function create()

$data['sections'] = $this->getSections($this->sessionHandle(), $jsDriver);

$data['fields'] = collect($data['sections'])->flatMap->fields->all();
$data['fields'] = new FieldsVariable(collect($data['sections'])->flatMap->fields->all());

$data['honeypot'] = $form->honeypot();

Expand Down
37 changes: 30 additions & 7 deletions tests/Tags/Form/FormCreateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Storage;
use Illuminate\Testing\Assert as PHPUnit;
use Illuminate\Testing\Constraints\SeeInOrder;
use Illuminate\Validation\ValidationException;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades\AssetContainer;
use Statamic\Facades\Form;
use Statamic\Forms\FieldsVariable;
use Statamic\Statamic;

class FormCreateTest extends FormTestCase
Expand Down Expand Up @@ -74,6 +77,26 @@ public function it_dynamically_renders_fields_array()
$this->assertEquals(['Full Name', 'Email Address', 'Message'], $fieldOrder[1]);
}

#[Test]
public function it_dynamically_renders_fields_view_using_single_tag()
{
$output = $this->normalizeHtml($this->tag(<<<'EOT'
{{ form:contact }}
{{ fields }}
{{ /form:contact }}
EOT
));

PHPUnit::assertThat([
'<label for="contact-form-name-field">Full Name </label>',
'<input id="contact-form-name-field" type="text" name="name" value="">',
'<label for="contact-form-email-field">Email Address <sup aria-label="Required">*</sup></label>',
'<input id="contact-form-email-field" type="email" name="email" value="" required>',
'<label for="contact-form-message-field">Message<sup aria-label="Required">*</sup></label>',
'<textarea id="contact-form-message-field" name="message" rows="5" required></textarea>',
], new SeeInOrder($output));
}

#[Test]
public function it_dynamically_renders_with_form_handle()
{
Expand Down Expand Up @@ -504,20 +527,20 @@ public function it_dynamically_renders_sections_array()
$output = $this->normalizeHtml($this->tag(<<<'EOT'
{{ form:survey }}
{{ sections }}
<div class="section">{{ if display}}{{ display }} - {{ /if }}{{ if instructions }}{{ instructions }} - {{ /if }}{{ fields | pluck('handle') | join(',') }}</div>
<div class="section">{{ if display}}{{ display }} - {{ /if }}{{ if instructions }}{{ instructions }} - {{ /if }}{{ fields }}[{{ handle }}]{{ /fields }}</div>
{{ /sections }}
<div class="fields">{{ fields | pluck('handle') | join(',') }}</div>
<div class="fields">{{ fields }}[{{ handle }}]{{ /fields }}</div>
{{ /form:survey }}
EOT
));

$this->assertStringContainsString('<div class="section">One - One Instructions - alpha,bravo</div>', $output);
$this->assertStringContainsString('<div class="section">Two - Two Instructions - charlie,delta</div>', $output);
$this->assertStringContainsString('<div class="section">echo,fox</div>', $output);
$this->assertStringContainsString('<div class="section">One - One Instructions - [alpha][bravo]</div>', $output);
$this->assertStringContainsString('<div class="section">Two - Two Instructions - [charlie][delta]</div>', $output);
$this->assertStringContainsString('<div class="section">[echo][fox]</div>', $output);

// Even though the fields are all nested within sections,
// we should still be able to get them via `{{ fields }}` array at top level...
$this->assertStringContainsString('<div class="fields">alpha,bravo,charlie,delta,echo,fox</div>', $output);
$this->assertStringContainsString('<div class="fields">[alpha][bravo][charlie][delta][echo][fox]</div>', $output);
}

#[Test]
Expand Down Expand Up @@ -835,7 +858,7 @@ public function it_fetches_form_data()
$this->assertArrayHasKey('_token', $form['params']);

$this->assertIsArray($form['errors']);
$this->assertIsArray($form['fields']);
$this->assertInstanceOf(FieldsVariable::class, $form['fields']);

$this->assertEquals($form['honeypot'], 'winnie');
$this->assertEquals($form['js_driver'], 'alpine');
Expand Down

0 comments on commit cfbe9d8

Please sign in to comment.