Skip to content

Commit 83e5184

Browse files
committed
minor #1346 Add doc for URL binding feature (squrious)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- Add doc for URL binding feature | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | Issues | NA | License | MIT Add documentation for symfony/ux#1230 Commits ------- 4f0d3132 Add doc for URL binding feature
2 parents c629fa9 + 0bd0e8c commit 83e5184

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

doc/index.rst

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,8 @@ then render it manually after:
20832083

20842084
{{ form_widget(form.todoItems.vars.button_add, { label: '+ Add Item', attr: { class: 'btn btn-outline-primary' } }) }}
20852085

2086+
.. _validation:
2087+
20862088
Validation (without a Form)
20872089
---------------------------
20882090

@@ -2304,6 +2306,130 @@ You can also trigger a specific "action" instead of a normal re-render:
23042306
#}
23052307
>
23062308

2309+
Changing the URL when a LiveProp changes
2310+
----------------------------------------
2311+
2312+
.. versionadded:: 2.14
2313+
2314+
The ``url`` option was introduced in Live Components 2.14.
2315+
2316+
If you want the URL to update when a ``LiveProp`` changes, you can do that with the ``url`` option::
2317+
2318+
// src/Components/SearchModule.php
2319+
namespace App\Components;
2320+
2321+
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
2322+
use Symfony\UX\LiveComponent\Attribute\LiveProp;
2323+
use Symfony\UX\LiveComponent\DefaultActionTrait;
2324+
2325+
#[AsLiveComponent]
2326+
class SearchModule
2327+
{
2328+
use DefaultActionTrait;
2329+
2330+
#[LiveProp(writable: true, url: true)]
2331+
public string $query = '';
2332+
}
2333+
2334+
Now, when the user changes the value of the ``query`` prop, a query parameter in the URL will be updated to reflect the
2335+
new state of your component, for example: ``https://my.domain/search?query=my+search+string``.
2336+
2337+
If you load this URL in your browser, the ``LiveProp`` value will be initialized using the query string
2338+
(e.g. ``my search string``).
2339+
2340+
.. note::
2341+
2342+
The URL is changed via ``history.replaceState()``. So no new entry is added.
2343+
2344+
.. warning::
2345+
2346+
You can use multiple components with URL bindings in the same page, as long as bound field names don't collide.
2347+
Otherwise, you will observe unexpected behaviors.
2348+
2349+
Supported Data Types
2350+
~~~~~~~~~~~~~~~~~~~~
2351+
2352+
You can use scalars, arrays and objects in your URL bindings:
2353+
2354+
============================================ =================================================
2355+
JavaScript ``prop`` value URL representation
2356+
============================================ =================================================
2357+
``'some search string'`` ``prop=some+search+string``
2358+
``42`` ``prop=42``
2359+
``['foo', 'bar']`` ``prop[0]=foo&prop[1]=bar``
2360+
``{ foo: 'bar', baz: 42 }`` ``prop[foo]=bar&prop[baz]=42``
2361+
2362+
2363+
When a page is loaded with a query parameter that's bound to a ``LiveProp`` (e.g. ``/search?query=my+search+string``),
2364+
the value - ``my search string`` - goes through the hydration system before it's set onto the property. If a value can't
2365+
be hydrated, it will be ignored.
2366+
2367+
Multiple Query Parameter Bindings
2368+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2369+
2370+
You can use as many URL bindings as you want in your component. To ensure the state is fully represented in the URL,
2371+
all bound props will be set as query parameters, even if their values didn't change.
2372+
2373+
For example, if you declare the following bindings::
2374+
2375+
// ...
2376+
#[AsLiveComponent]
2377+
class SearchModule
2378+
{
2379+
#[LiveProp(writable: true, url: true)]
2380+
public string $query = '';
2381+
2382+
#[LiveProp(writable: true, url: true)]
2383+
public string $mode = 'fulltext';
2384+
2385+
// ...
2386+
}
2387+
2388+
2389+
And you only set the ``query`` value, then your URL will be updated to
2390+
``https://my.domain/search?query=my+query+string&mode=fulltext``.
2391+
2392+
Validating the Query Parameter Values
2393+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2394+
2395+
Like any writable ``LiveProp``, because the user can modify this value, you should consider adding
2396+
:ref:`validation <validation>`. When you bind a ``LiveProp`` to the URL, the initial value is not automatically
2397+
validated. To validate it, you have to set up a `PostMount hook`_::
2398+
2399+
// ...
2400+
use Symfony\Component\Validator\Constraints as Assert;
2401+
use Symfony\UX\LiveComponent\ValidatableComponentTrait;
2402+
use Symfony\UX\TwigComponent\Attribute\PostMount;
2403+
2404+
#[AsLiveComponent]
2405+
class SearchModule
2406+
{
2407+
use ValidatableComponentTrait;
2408+
2409+
#[LiveProp(writable: true, url: true)]
2410+
public string $query = '';
2411+
2412+
#[LiveProp(writable: true, url: true)]
2413+
#[Assert\NotBlank]
2414+
public string $mode = 'fulltext';
2415+
2416+
#[PostMount]
2417+
public function postMount(): void
2418+
{
2419+
// Validate 'mode' field without throwing an exception, so the component can be mounted anyway and a
2420+
// validation error can be shown to the user
2421+
if (!$this->validateField('mode', false)) {
2422+
// Do something when validation fails
2423+
}
2424+
}
2425+
2426+
// ...
2427+
}
2428+
2429+
.. note::
2430+
2431+
You can use `validation groups`_ if you want to use specific validation rules only in the PostMount hook.
2432+
23072433
.. _emit:
23082434

23092435
Communication Between Components: Emitting Events
@@ -3317,3 +3443,5 @@ bound to Symfony's BC policy for the moment.
33173443
.. _`Symfony's built-in form theming techniques`: https://symfony.com/doc/current/form/form_themes.html
33183444
.. _`pass content to Twig Components`: https://symfony.com/bundles/ux-twig-component/current/index.html#passing-blocks
33193445
.. _`Twig Component debug command`: https://symfony.com/bundles/ux-twig-component/current/index.html#debugging-components
3446+
.. _`PostMount hook`: https://symfony.com/bundles/ux-twig-component/current/index.html#postmount-hook
3447+
.. _`validation groups`: https://symfony.com/doc/current/form/validation_groups.html

0 commit comments

Comments
 (0)