x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<p> When two forms on the same page share a field with the same name, they would normally share a single Alpine store, causing each form's ConditionalComponent to react to the other form's selection. Passing a <code>scope</code> to both RadioButtonsComponent and ConditionalComponent scopes each pair to its own store so they operate independently. This is relevant for forms that update primary and secondary filers with the same-named attribute.</p><h2 id="form1-heading">Form 1</h2><form action="/" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="HQEp2J58uGbfBQ8uUMEFaZXNa8qlYOR2JK3OKB5JSI-AWtvNw_GgomEfN79dnWIPkojcJdJkGYI56tiInjv_8Q" autocomplete="off" /> <fieldset class="fieldset-group" aria-labelledby="form1-heading" x-data x-init="Alpine.store('pineapple_pizza_preference_form1', '');"> <div class="cfa-stack-med"><input type="hidden" name="form_component_preview_test_model[pineapple_pizza_preference]" value="" autocomplete="off" /> <div class="form_item"><input x-model="$store.pineapple_pizza_preference_form1" class="cfa-radio" id="form_component_preview_test_model_pineapple_pizza_preference_yes_form1" type="radio" value="yes" name="form_component_preview_test_model[pineapple_pizza_preference]" /><label for="form_component_preview_test_model_pineapple_pizza_preference_yes_form1">Yes</label></div> <div class="form_item"><input x-model="$store.pineapple_pizza_preference_form1" class="cfa-radio" id="form_component_preview_test_model_pineapple_pizza_preference_no_form1" type="radio" value="no" name="form_component_preview_test_model[pineapple_pizza_preference]" /><label for="form_component_preview_test_model_pineapple_pizza_preference_no_form1">No</label></div> </div> </fieldset> <div class="contents" x-data="{condition: false, announcement: '', ready: false, announceTimer: null}" x-effect="condition = $store.pineapple_pizza_preference_form1 === 'yes' || (Array.isArray($store.pineapple_pizza_preference_form1) && $store.pineapple_pizza_preference_form1.includes('yes'))" x-init="$nextTick(() => ready = true); $watch('condition', visible => { if (!ready) return; const message = 'Followup question for form 1 is now ' + (visible ? 'visible' : 'hidden'); clearTimeout(announceTimer); announcement = ''; announceTimer = setTimeout(() => { announcement = message; announceTimer = setTimeout(() => announcement = '', 5000); }, 50); })"> <p class="sr-only" aria-live="assertive" aria-atomic="true" role="alert" x-text="announcement"></p> <div x-cloak x-show="condition" class="cfa-stack-med"> But why!? </div> </div></form><h2 id="form2-heading">Form 2</h2><form action="/" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="37aAnZvVxQmwvejECOtDrO07kYdcfkFMxWzsVVFKRHlC7XKIxljdzQ6n0FUFtyTK6n4maCt6vLjYK_r10TjzBw" autocomplete="off" /> <fieldset class="fieldset-group" aria-labelledby="form2-heading" x-data x-init="Alpine.store('pineapple_pizza_preference_form2', '');"> <div class="cfa-stack-med"><input type="hidden" name="form_component_preview_test_model[pineapple_pizza_preference]" value="" autocomplete="off" /> <div class="form_item"><input x-model="$store.pineapple_pizza_preference_form2" class="cfa-radio" id="form_component_preview_test_model_pineapple_pizza_preference_yes_form2" type="radio" value="yes" name="form_component_preview_test_model[pineapple_pizza_preference]" /><label for="form_component_preview_test_model_pineapple_pizza_preference_yes_form2">Yes</label></div> <div class="form_item"><input x-model="$store.pineapple_pizza_preference_form2" class="cfa-radio" id="form_component_preview_test_model_pineapple_pizza_preference_no_form2" type="radio" value="no" name="form_component_preview_test_model[pineapple_pizza_preference]" /><label for="form_component_preview_test_model_pineapple_pizza_preference_no_form2">No</label></div> </div> </fieldset> <div class="contents" x-data="{condition: false, announcement: '', ready: false, announceTimer: null}" x-effect="condition = $store.pineapple_pizza_preference_form2 === 'yes' || (Array.isArray($store.pineapple_pizza_preference_form2) && $store.pineapple_pizza_preference_form2.includes('yes'))" x-init="$nextTick(() => ready = true); $watch('condition', visible => { if (!ready) return; const message = 'Followup question for form 2 is now ' + (visible ? 'visible' : 'hidden'); clearTimeout(announceTimer); announcement = ''; announceTimer = setTimeout(() => { announcement = message; announceTimer = setTimeout(() => announcement = '', 5000); }, 50); })"> <p class="sr-only" aria-live="assertive" aria-atomic="true" role="alert" x-text="announcement"></p> <div x-cloak x-show="condition" class="cfa-stack-med"> But why!? </div> </div></form>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<p> When two forms on the same page share a field with the same name, they would normally share a single Alpine store, causing each form's ConditionalComponent to react to the other form's selection. Passing a <code>scope</code> to both RadioButtonsComponent and ConditionalComponent scopes each pair to its own store so they operate independently. This is relevant for forms that update primary and secondary filers with the same-named attribute.</p><h2 id="form1-heading">Form 1</h2><%= form_with url: "/", method: :post, model: FormComponentPreview::TestModel.new do |f| %> <%= render RadioButtonsComponent.new(form: f, method: :pineapple_pizza_preference, collection: FormComponentPreview.yes_no_options, item_value_method: :value, item_label_method: :label, scope: "form1", aria_labelledby: "form1-heading") %> <%= render ConditionalComponent.new(method: :pineapple_pizza_preference, value: "yes", content_description: "Followup question for form 1", scope: "form1") do %> But why!? <% end %><% end %><h2 id="form2-heading">Form 2</h2><%= form_with url: "/", method: :post, model: FormComponentPreview::TestModel.new do |f| %> <%= render RadioButtonsComponent.new(form: f, method: :pineapple_pizza_preference, collection: FormComponentPreview.yes_no_options, item_value_method: :value, item_label_method: :label, scope: "form2", aria_labelledby: "form2-heading") %> <%= render ConditionalComponent.new(method: :pineapple_pizza_preference, value: "yes", content_description: "Followup question for form 2", scope: "form2") do %> But why!? <% end %><% end %>No notes provided.
No params configured.