Skip to content

Commit

Permalink
Implement Server-Side Price Filtering
Browse files Browse the repository at this point in the history
This commit modifies the `seats#index` HTML to take the `?maximum` query
parameter into account when deciding which `Seat` records are emphasized
or de-emphasized based on their section's price.

First, extend the price filtering `<form>` element to declare the
[`action` attribute] to the current page, and the [`method` attribute to
`GET`][get]. To declare these methods, and to integrate with Rails' CSRF
protection, declare the `<form>` using the [`form_with`
helper][form_with].

Unfortunately, Turbolinks does not support `<form>` submission redirects
for `GET` requests:

> The Turbolinks Rails engine performs this optimization automatically
> for non-GET XHR requests that redirect with the `redirect_to` helper.

To counteract that constraint, this commit passes the `local: true`
option to the `form_with` call, [opting-out of remote form submission
through unobtrusive JavaScript][local] and (transitively) Turbolinks.

Next, determine which `<input type="radio">` element to denote as
[`checked`][checked] based on whether or not its `value` attribute
matches the value of the `maximum` query parameter. If no query
parameter is provided, ensure that the last `<input type="radio">`
element is `checked`.

Render the `Section` records as a [`<g>`][g] element to group them
together. When rendering the `<g>` element, declare its
[`opacity`][opacity] based on whether its `price` is within the bounds
of the price filter.

Additionally, set [`aria-hidden="true"`][aria-hidden] for `<g>`
elements that do not match the filter criteria, so that we can exclude
them from the accessibility tree.

[action]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#Attributes
[get]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET
[form_with]: https://api.rubyonrails.org/v5.2/classes/ActionView/Helpers/FormHelper.html#method-i-form_with
[checked]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input/radio#checked
[turbolinks-get]: https://github.com/turbolinks/turbolinks/tree/v5.2.0#redirecting-after-a-form-submission
[local]: https://api.rubyonrails.org/v5.2/classes/ActionView/Helpers/FormHelper.html#method-i-form_with-label-form_with+options
[g]: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
[opacity]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/opacity
[aria-hidden]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#States_and_properties
  • Loading branch information
seanpdoyle committed Mar 22, 2020
1 parent 7b8808e commit b0ee454
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
21 changes: 16 additions & 5 deletions app/views/seats/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,14 @@
</svg>

<% sections.each do |section| %>
<g>
<g
<% if params.fetch(:maximum, Float::INFINITY).to_f >= section.price %>
opacity="1.0"
<% else %>
opacity="0.3"
aria-hidden="true"
<% end %>
>
<% section.seats.each do |seat| %>
<a
href="<%= venue_floor_seat_path(venue, floor, seat.row_number) %>"
Expand All @@ -135,7 +142,11 @@
</div>

<div class="syos-frame__sidebar">
<form>
<%= form_with(
url: venue_floor_seats_path(venue, floor),
method: :get,
local: true,
) do |form| %>
<fieldset class="syos-u-margin-bottom-6">
<legend class="syos-u-margin-bottom-2 syos-inline-stack">
<h2 class="syos-inline-stack__item">
Expand All @@ -153,7 +164,8 @@
type="radio"
name="maximum"
value="<%= maximum %>"
<% if next_maximum.nil? %>
<% if params[:maximum].to_i == maximum ||
[params[:maximum], next_maximum].none? %>
checked
<% end %>
>
Expand All @@ -177,7 +189,7 @@

<input type="submit" class="syos-button syos-u-margin-top-2" value="Apply Filters">
</fieldset>
</form>
<% end %>

<div id="cart-summary">
<h2 class="syos-u-margin-bottom-2">
Expand Down Expand Up @@ -236,4 +248,3 @@
</div>
</section>
</main>

47 changes: 47 additions & 0 deletions test/controllers/seats_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,51 @@ class SeatsControllerTest < ActionDispatch::IntegrationTest

assert_equal Cart.last.token, cookies[:cart_token]
end

test "#index when including sections when filtering by price" do
maximum = 10_00
price = maximum
venue = create(:benedum_center)
floor = create(:orchestra, venue: venue)
section = create(:section, floor: floor, price: price)
create(:seat, section: section)

get venue_floor_seats_path(venue, floor, maximum: maximum)

assert_select %{g[opacity="1.0"]}
assert_select %{g:not([aria-hidden])}
end

test "#index when excluding sections when filtering by price" do
maximum = 5_00
price = 10_00
venue = create(:benedum_center)
floor = create(:orchestra, venue: venue)
section = create(:section, floor: floor, price: price)
create(:seat, section: section)

get venue_floor_seats_path(venue, floor, maximum: maximum)

assert_select %{g[opacity="0.3"]}
assert_select %{g[aria-hidden="true"]}
end

test "#index with a ?maximum query parameter" do
venue = create(:benedum_center)
floor = create(:orchestra, venue: venue)
maximum = 10_00

get venue_floor_seats_path(venue, floor, maximum: maximum)

assert_select %{input[type="radio"][value="#{maximum}"][checked]}
end

test "#index without a ?maximum query parameter" do
venue = create(:benedum_center)
floor = create(:orchestra, venue: venue)

get venue_floor_seats_path(venue, floor)

assert_select %{input[type="radio"][value="1500"][checked]}
end
end

0 comments on commit b0ee454

Please sign in to comment.