PHP.GT

Your first Flux form

We will begin with the smallest useful Flux interaction: a form that submits in the background and updates itself with the server-rendered result.

The repository’s first example is a session-backed counter at example/01-counter.php. The page contains a <textarea> outside the form so we can see the difference immediately: a normal page reload would cause the whole page to refresh, losing the state of the textarea - but Flux keeps the page state unchanged.

Start with plain HTML

<form method="post">
	<output>0</output>
	<button name="do" value="increment">Increment</button>
	<button name="do" value="decrement">Decrement</button>
</form>

On the server, we can handle the buttons exactly as we always would. Example 01 stores the count in the session, changes the value, and responds with a redirected full HTML page.

[!IMPORTANT] Flux is built as a standalone library, but the main intention is to be used with PHP.GT/WebEngine - Flux is shipped by default in WebEngine applications. All examples and server-side code use plain PHP, but any language or framework could be used. For more information about how WebEngine takes full advantage of Flux, see https://www.php.gt/docs/webengine/flux/

Add Flux

To make the form submit in the background, we have two options.

Option 1: mark the form as a Flux container

<form method="post" data-flux>
	<output>0</output>
	<button name="do" value="increment">Increment</button>
	<button name="do" value="decrement">Decrement</button>
</form>

On a <form>, bare data-flux tells Flux to listen for submit events on that form.

Option 2: mark individual buttons to submit, and mark just the elements to update

<form method="post">
	<output data-flux="update">0</output>
	<button name="do" value="increment" data-flux>Increment</button>
	<button name="do" value="decrement" data-flux>Decrement</button>
</form>

<textarea>Type something into this textarea - the state will be persisted after clicking the increment button above.</textarea>

[!NOTE] data-flux is a shorthand attribute on some types of element. On forms, data-flux converts the form into a Flux container. On buttons, data-flux is short for data-flux="submit" - handling the single button click instead of the whole form submission. On links, data-flux is short for `data-flux=“link” - but we haven’t got to links yet. For more information, see the list of flux attributes.

What the response should look like

Flux expects a complete HTML page in response. We do not need to return state in JSON or anything like that, and we do not need a separate partial render just for the counter element. Remember, we’re just enhancing an already-working server-first application. The server can redirect or render the normal route as usual, and Flux will do the rest.

What changes in the browser

When the button is pressed:

  1. Flux prevents the browser’s default submit.
  2. Flux gathers FormData, including the clicked button name and value.
  3. Flux sends the request using fetch, in the background (also known as “ajax”).
  4. Flux parses the returned HTML document.
  5. Flux updates whichever targets we registered on the current page with attributes like data-flux="update"

That is why the <textarea> in the example keeps its content: only the Flux target updates, not the whole page.

[!INFO] If the form has an action, Flux treats the response like navigation and also updates the browser history. If there is no action, Flux updates in place without pushing a history entry.

[!INFO] While a Flux form submission is in flight, Flux adds the class flux-form-waiting to both the submitting <form> and the page <body>. If a specific submit button triggered the request, that button also gets flux-button-waiting until the request finishes. We can use those classes to dim the interface, show a spinner, or disable pointer interactions in our own CSS.


Our form now submits in the background. Next we will decide exactly what gets replaced when updating part of the page.