Our server already renders Seat elements with their selection state for
full page reloads, but now that the <svg id="map"> element is
annotated with data-turbolinks-permanent, the element will persist
across Turbolinks-initiated visits.
Due to this persistence, our client is now responsible for managing some
long-lived state. When a Seat is selected, a full-page visit modifies
the HTML for the entire page, replacing the <body> element and its
contents – except for the map.
This commit extends our client-side code to progressively enhance the
application to manage changes in Seat selection state by managing the
<use> element’s xlink:href attribute with Client-side
logic.
In addition to checking setting the correct xlink:href at render-time,
the server transmits additional information for each Seat (represented
by data- attributes declared on its <use> element).
By reading data-seat-id values from the page’s Cart Summary, the Seats
Stimulus controller modifies the <use> elements’
xlink:href attributes that represents the seats’
possible states.
The map of possible transitions is encoded as data-selected-icon and
data-unselected-icon, which is made accessible through accessing
element.dataset.selectedIcon and element.dataset.unselectedIcon.
When the xlink:href attribute is assigned to a new value, the browser
will render the Seat that is referenced.
This state is managed by the seats#selectSeats function. That function
must be run:
When the page is loaded
When a Seat is added to the Cart Summary
When a Seat is removed from the Cart Summary
The first case can be covered by a direct invocation in the
seats#connect life cycle hook. The second and third depend on how our
users interact with the page’s <form> elements.
This commit passes the remote: true option to
button_to and form_with helper method
calls. This results in a data-remote="true" attribute on the resulting
<form> element, which integrates with Rails’ Unobtrusive JavaScript.
During the life cycle of a UJS-initiated AJAX request, there are several
events fired.
This commit extends the <form> elements interested in adding and
removing Seats from the page’s cart summary by declaring
data-action="ajax:complete->seats#selectSeats". This attribute
routes the <form> element’s ajax:complete events to
the seats#selectSeats action.