PHP.GT

Updating part of the page

Once a request comes back from the server, Flux needs to know which elements on the current page should be refreshed. This is where the update directives come in.

Replace the whole element with data-flux="update"

The update directive replaces the target element itself using the matching element from the returned document. data-flux="update" is shorthand for data-flux="update-outer" (meaning update the outer HTML, including all attributes, of the element).

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

This is a good default when the element’s own attributes may change between responses.

[!NOTE] A form marked with bare data-flux is automatically registered as an outer update target too. Use data-flux="update" when the element is not already a Flux form, or when we want to be explicit about the update behaviour.

Replace only the contents with data-flux="update-inner"

If we want to keep the wrapper element in place and only swap its children, we can use update-inner instead:

<form method="post">
	<ul class="example-list" data-flux="update-inner">
		<li>First item</li>
	</ul>
	<input name="new-item" />
	<button name="do" value="add" data-flux="submit">Add</button>
</form>

This is similar to how example/02-list.php works. The form remains the target, but its contents refresh after each add or delete.

When to choose each one

  • Use update when the container itself may change.
  • Use update-inner when the outer shell should stay put.

Both patterns still rely on the returned HTML document containing the corresponding element in the same DOM position.

Matching happens by DOM position

If a Flux element has an id attribute, the matching id of subsequent responses will be used when replacing. However, flux does not require you to add an id to elements that need replacing. Instead, it records the current element’s path through the DOM and looks up the element at that same path in the new document.

That means this style of server rendering works well if:

  • the page returns the same overall document structure
  • the Flux target is still in the same place
  • the content inside that target changes normally on the server

[!IMPORTANT] If the surrounding layout moves around dramatically between requests, Flux may no longer find the intended replacement node, so an id attribute is required.

Preserving focus and custom listeners

When Flux swaps content, it also does some repair work for us:

  • it restores focus and text selection where possible
  • it reinitialises newly inserted data-flux elements
  • it reattaches event listeners that were added through addEventListener

That last point matters if we add our own JavaScript behaviour to elements inside a Flux target, because when the new response replaces the element, any event listeners that had already been added to the element will no longer be attached to the new element.

It’s important to import Flux before any other JavaScript executes on the page, so Flux can intercept the Element.addEventListener function.

Nested update targets

If an outer update target contains another update target, Flux only needs to replace the outer target. The child would already be replaced as part of the parent’s new HTML, so Flux skips that nested update.

This means it is safe for a form to update itself while also containing more specific Flux elements. When the containing form is replaced, Flux avoids doing extra work on children that have already disappeared with the old form.


With a single update target in place, we can look at pages that refresh several related elements together in coordinating multiple updates.