Reputation: 474
I want to know how to hide an element if a radio button is selected.
I have a form and want to show both first_name
and last_name
inputs if the radio button is selected that corresponds to account.kind == "person"
, otherwise they should be hidden.
Here is the Haml code:
= simple_form_for(@account, html: { class: 'edit-form edit_account' }, wrapper: :edit_form) do |f|
%fieldset.large-2-col
%legend.hint
%span= t('views.accounts.profile.description')
.fields-block
= f.input :kind, as: :radio_buttons, wrapper_class: 'fields-group contact-type', item_wrapper_class: 'inline', item_wrapper_tag: 'div', collection: Account.kind.options, required: true, wrapper: :inline_radio
= f.input :first_name, autofocus: true, input_html: { data: { person: Account.human_attribute_name('first_name'), company: Account.human_attribute_name('company_name') } }
= f.input :last_name
And the related CoffeeScript that may or may not be relevant:
$("form input[name='account[kind]']").bind 'change', () ->
selected_value = $("input[name='account[kind]']:checked").val()
$("label[for='account_first_name']").html $('#account_first_name').data(selected_value)
$("#account_last_name").parents('.fields-group').toggleClass('hidden', selected_value != 'person')
$("#account_last_name").val('') if selected_value == 'company'
false
$("input[name='account[kind]']").trigger 'change' if $("input[name='account[kind]']").length > 0
Upvotes: 0
Views: 863
Reputation: 102240
This has nothing really to do with Haml as it's just done in the client.
// this create an idempotent handler that works with Turbolinks
$(document).on('change', "input[name='account[kind]']", function(e){
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements
// this avoids traversing the entire DOM when we know what the user has clicked anyways
let input = $(this.form.elements["account[last_name]"]);
let label = $(this.form.elements["account[first_name]"]).parents('.fields-group').find('label');
input.parents('.fields-group').toggle(this.value === "person");
// prevents input from being sent if the form is submitted
input.prop('disabled', function(){ return e.target.value !== "person" });
// transform label
label.text(this.value === "person" ? "First name" : "Name");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="field">
<input type="radio" id="person" name="account[kind]" value="person" checked>
<label for="male">Person</label><br>
<input type="radio" id="company" name="account[kind]" value="company">
<label for="female">Company</label><br>
</div>
<div class="fields-group">
<label for="account[first_name]" data-se>First name</label>
<input type="text" name="account[first_name]">
</div>
<div class="fields-group">
<label for="account[last_name]">Last name</label>
<input type="text" name="account[last_name]">
</div>
</form>
In CoffeScript:
# this create an idempotent handler that works with Turbolinks
$(document).on 'change', 'input[name=\'account[kind]\']', (e) ->
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements
# this avoids traversing the entire DOM when we know what the user has clicked anyways
input = $(@form.elements['account[last_name]'])
label = $(@form.elements['account[first_name]']).parents('.fields-group').find('label')
input.parents('.fields-group').toggle @value == 'person'
# prevents input from being sent if the form is submitted
input.prop 'disabled', ->
e.target.value != 'person'
# transform label
label.text if @value == 'person' then 'First name' else 'Name'
return
You may have to adjust this slightly as I don't know exactly what your rendered view looks like but it's pretty straight forward.
Upvotes: 1