Skip to content

Symfony UX Live Components integration #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Form/Recaptcha3Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function buildView(FormView $view, FormInterface $form, array $options):
$view->vars['action_name'] = $options['action_name'];
$view->vars['script_nonce_csp'] = $options['script_nonce_csp'] ?? '';
$view->vars['locale'] = $options['locale'] ?? 'en';
$view->vars['attr']['data-model'] = $options['data_model'];
}

public function getParent(): string
Expand All @@ -55,6 +56,7 @@ public function configureOptions(OptionsResolver $resolver): void
'action_name' => 'homepage',
'locale' => 'en',
'script_nonce_csp' => '',
'data_model' => null,
]);
}
}
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,45 @@ services:
If you have a dependency on `symfony/http-client` in your application then it will be automatically wired
to use via `RequestMethod/SymfonyHttpClient`.

### How to integrate with Symfony UX Live Components
If you use [Symfony UX Live Components](https://symfony.com/bundles/ux-live-component/current/index.html) to render your form,
you can add `data_model` option with a value of your choice to send the captcha value to the component
```php
$builder->add('captcha', Recaptcha3Type::class, [
'data_model' => 'captcha',
...
]);
```

Then in your component you have to add a writable `LiveProp` and set the form value accordingly
```php
use Symfony\UX\LiveComponent\ComponentToolsTrait;
use Symfony\UX\LiveComponent\ComponentWithFormTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent]
class FormComponent extends AbstractController
{
use ComponentToolsTrait;
use ComponentWithFormTrait;
use DefaultActionTrait;

#[LiveProp(writable: true)]
public string|null $captcha = null;

#[LiveAction]
public function save(): void {
...
$this->formValues['captcha'] = $this->captcha;
$this->submitForm();
$this->dispatchBrowserEvent('recaptcha:reload');
...
}
}
```

You then have to use the LiveAction `save` to submit the form.

Troubleshooting checklist
-------------------------

Expand Down
15 changes: 14 additions & 1 deletion Resources/views/Form/karser_recaptcha3_widget.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,22 @@
{% set validJsId = id | replace({'-':'_'}) %}
<script type="text/javascript" {% if form.vars.script_nonce_csp is defined %}nonce="{{ form.vars.script_nonce_csp }}"{% endif %}>
var recaptchaCallback_{{ validJsId }} = function() {
const recaptchaField = document.getElementById('{{ id }}');
if (! recaptchaField) {
return;
}

grecaptcha.execute('{{ form.vars.site_key }}', {action: '{{ form.vars.action_name }}'}).then(function(token) {
document.getElementById('{{ id }}').value = token;
recaptchaField.value = token;
{% if form.vars.attr['data-model'] is defined and form.vars.attr['data-model'] is not null %}
recaptchaField.dispatchEvent(new Event('change', {bubbles: true}))
{% endif %}
});

{% if form.vars.attr['data-model'] is defined and form.vars.attr['data-model'] is not null %}
window.addEventListener('recaptcha:reload', window.recaptchaCallback_{{ validJsId }})
{% endif %}

setTimeout(recaptchaCallback_{{ validJsId }}, 100000);
};
</script>
Expand Down