app/views/shared/_group_boxes.html.erb
<div class="form-check" data-group-context-<%= for_group %>="">
<div class="row">
<label for="patient_group_ids_<%= for_group %>_blank">
<input class="form-check-input" data-blank="" type="checkbox" value="" name="patient[group_ids][]" id="patient_group_ids_<%= for_group %>_blank">
<i>
Não me encaixo em nenhuma opção abaixo, ou não está na lista
</i>
</label>
</div>
<%= f.collection_check_boxes :group_ids, Group.send(for_group).root.active.order(:position).includes(:children), :id, :name do |b| %>
<div class="row">
<%= b.label do
b.check_box(
checked: f.object.group_ids.include?(b.value.to_i),
class: "form-check-input",
data: { 'group-parent' => b.value }
) + b.text
end %>
</div>
<% if b.object.children.active.order(:position).any? %>
<div class="form-row" hidden="true" data-group-child="<%= b.value %>">
<div class="form-group col-md-8">
<div class="form-check">
<%= f.collection_check_boxes :group_ids, b.object.children.active.order(:position), :id, :name do |s| %>
<div class="row">
<%= s.label do
s.check_box(
checked: f.object.group_ids.include?(s.value.to_i),
class: "form-check-input"
) + s.text
end %>
</div>
<% end %>
</div>
</div>
</div>
<% end %>
<% end %>
</div>
<script type="text/javascript">
$(function () {
$('[data-group-context-<%= for_group %>] [data-group-parent]').on('change', function () {
groupToggle($(this))
}).each(function () {
groupToggle($(this))
})
let selectors = [
'[data-group-context-] :checkbox',
];
selectors.forEach(function (selector) {
$(selector).on('change', function () {
requireToggle($(selector))
}).each(function () {
requireToggle($(selector))
})
})
})
</script>
<script type="text/javascript">
$(function () {
$('[data-group-context-<%= for_group %>] [data-group-parent]').on('change', function () {
groupToggle($(this))
}).each(function () {
groupToggle($(this))
})
let selectors = [
$('[data-group-context-<%= for_group %>]')
];
selectors.forEach(function (selector) {
selector.find(':checkbox').on('change', function (e) {
const target = $(e.target)
if (target.is('[data-blank]')) { // if blank one changes...
if (target.is(':checked')) { // ... to be checked...
selector.find(':checkbox:not([data-blank])').prop('checked', false) // ... then uncheck all others
} else { // ... to not be checked...
selector.find(':checkbox[data-blank]').prop('checked', true) // ... then re-check it
}
$('[data-group-parent]').each(function () { groupToggle($(this)) })
} else { // if a not blank changes...
if (target.is(':checked')) { // ... to be checked...
selector.find(':checkbox[data-blank]').prop('checked', false) // ... then uncheck the blank one
} else { // ... to not be checked...
selector.find(':checkbox[data-blank]').prop('checked', selector.find(':checkbox:not([data-blank]):checked').size() === 0) // ... then check the blank one ONLY IF no other ones are checked
}
}
}).each(function () {
selector.find(':checkbox[data-blank]').prop('checked', !($(selector).find(':checkbox:not([data-blank])').is(':checked')))
})
})
})
</script>