|
1 | 1 | <%# app/views/better_together/checklist_items/_form.html.erb %> |
2 | 2 | <%# Safely resolve optional locals to avoid NameError when partial is rendered without all locals %> |
3 | 3 | <% current = (local_assigns[:form_object] || local_assigns[:checklist_item] || local_assigns[:new_checklist_item]) %> |
| 4 | +<% form_base_id = current ? dom_id(current) : 'new_checklist_item' %> |
4 | 5 | <%= turbo_frame_tag (current ? "#{dom_id(current)}_frame" : 'new_checklist_item') do %> |
5 | 6 | <%= form_with(model: current || local_assigns[:new_checklist_item], url: form_url || request.path, local: false) do |f| %> |
| 7 | + <%# Title and short instructions for the form %> |
| 8 | + <div class="mb-3"> |
| 9 | + <h5 class="mb-1"><%= current && current.persisted? ? t('better_together.checklist_items.edit_title', default: 'Edit checklist item') : t('better_together.checklist_items.new_title', default: 'New checklist item') %></h5> |
| 10 | + <p class="text-muted small mb-0"><%= t('better_together.checklist_items.form_hint', default: 'Provide a short label and optional details. Use privacy to control who sees this item.') %></p> |
| 11 | + </div> |
6 | 12 | <div class="mb-2"> |
7 | | - <%= f.label :label, t('better_together.checklist_items.label', default: 'Label') %> |
8 | | - <%= f.text_field :label, class: 'form-control' %> |
| 13 | + <%= required_label(f, :label, class: 'form-label') %> |
| 14 | + <%= f.text_field :label, class: 'form-control', aria: { describedby: "#{form_base_id}_label_help" } %> |
| 15 | + <div id="<%= "#{form_base_id}_label_help" %>" class="form-text text-muted"><%= t('better_together.checklist_items.hint_label', default: 'Short title for the checklist item (required).') %></div> |
9 | 16 | </div> |
10 | 17 |
|
11 | 18 | <div class="mb-2"> |
12 | 19 | <%= f.label :description, t('better_together.checklist_items.description', default: 'Description') %> |
13 | | - <%= f.rich_text_area :description, class: 'form-control', rows: 3 %> |
| 20 | + <%= f.rich_text_area :description, class: 'form-control', rows: 3, aria: { describedby: "#{form_base_id}_description_help" } %> |
| 21 | + <div id="<%= "#{form_base_id}_description_help" %>" class="form-text text-muted"><%= t('better_together.checklist_items.hint_description', default: 'Optional details or instructions for this item. Supports rich text formatting.') %></div> |
14 | 22 | </div> |
15 | 23 |
|
16 | 24 | <div class="mb-2"> |
17 | | - <%= f.label :privacy, t('better_together.checklist_items.privacy', default: 'Privacy') %> |
| 25 | + <%= required_label(f, :privacy, class: 'form-label') %> |
18 | 26 | <%= privacy_field(form: f, klass: BetterTogether::ChecklistItem) %> |
| 27 | + <div id="<%= "#{form_base_id}_privacy_help" %>" class="form-text text-muted"><%= t('better_together.checklist_items.hint_privacy', default: 'Choose who can see this item: Public or Private.') %></div> |
19 | 28 | </div> |
20 | 29 |
|
21 | 30 | <div class="mb-2"> |
|
31 | 40 | <%# Build nested option titles using depth (e.g. "— Child label") %> |
32 | 41 | <% options = allowed_parents.map { |it| [checklist_item_option_title(it), it.id] } %> |
33 | 42 |
|
34 | | - <%= f.select :parent_id, |
35 | | - options_for_select(options, (current.parent_id if current.respond_to?(:parent_id))), |
36 | | - { include_blank: true }, |
37 | | - { class: 'form-select' + (current.errors[:parent_id].any? ? ' is-invalid' : ''), data: { controller: "better_together--slim-select" } } %> |
| 43 | + <%= f.select :parent_id, |
| 44 | + options_for_select(options, (current.parent_id if current.respond_to?(:parent_id))), |
| 45 | + { include_blank: true }, |
| 46 | + { class: 'form-select' + (current.errors[:parent_id].any? ? ' is-invalid' : ''), data: { controller: "better_together--slim-select" }, aria: { describedby: "#{form_base_id}_parent_help" } } %> |
| 47 | + <div id="<%= "#{form_base_id}_parent_help" %>" class="form-text text-muted"><%= t('better_together.checklist_items.hint_parent', default: 'Optional: nest this item under another. Maximum nesting depth is 2.') %></div> |
38 | 48 | </div> |
39 | 49 |
|
40 | 50 | <div class="d-flex justify-content-end"> |
41 | | - <%= f.submit t('globals.save', default: 'Save'), class: 'btn btn-primary btn-sm' %> |
42 | | - <%= button_tag t('globals.cancel', default: 'Cancel'), type: 'submit', name: 'cancel', value: 'true', class: 'btn btn-secondary btn-sm ms-2' %> |
| 51 | + <% submit_label = current && current.persisted? ? t('globals.update', default: 'Update') : t('globals.create', default: 'Create') %> |
| 52 | + <%= f.submit submit_label, class: 'btn btn-primary btn-sm' %> |
| 53 | + <%= button_tag t('globals.cancel', default: 'Cancel'), type: 'submit', name: 'cancel', value: 'true', class: 'btn btn-secondary btn-sm ms-2' %> |
43 | 54 | </div> |
44 | 55 | <% end %> |
45 | 56 | <% end %> |
0 commit comments