Rails - How do I create a checkbox that will render a different form when checked without refreshing? - ruby-on-rails

As the title suggests, I am wondering how to create a checkbox on a view that will change what form is rendered without refreshing the page.
In my app/views/home/ folder I have _form_1.html.erb and _form_2.html.erb.
I want to default to <%= render 'form_1' %> when the box is not checked, and change to <%= render 'form_2' %> when the box is checked.
I've attempted to look up how to do this, but things like .is(":checked") and check_box_tag don't seem to be working for me, or I'm using them wrong.
Any help is appreciated!
EDIT: I am using Rails 3.2.12 and Ruby 1.9.3.

The way I'd do this is to render both the form partials from another view, and put each of them in a div. The default form div should be visible, and the optional form div should be hidden. Then you can toggle the display of the divs with a click action on the checkbox.
Depending on what's in the forms and how they interact with your controller, there's likely a lot of other work involved in processing, but in order to toggle the displayed forms, the method above is one option.

If you want to do this without a refresh you'll have to use javascript. What you'd do is render each form but as hidden. This next part is really easy with jquery. When a checkobox is selected you'd just do something like $('#form1').show(), and conversely $('#form2').hide()

Related

Can I take the submit button out of the form builder somehow?

I'm using form_for to make a form. However, I want the submit button <%= f.submit "Submit" %> to be inside another element that's not inside the form. I can't just put the element inside the form -- it's separated by too much html. Is there a way to take this submit button out and put it in another div or just use plain html to submit the form?
If Javascript is an option you could just make a button outside of the form and bind its onClick with something like
document.getElementById("myForm").submit();

Rails: How to render partial view from another controller

I am making a reddit clone. Right now I have a voting system that works, but it refreshes the page each time a user votes. I want to make this async by using AJAX.
Making buttons respond to Jquery is really hard though because they change state depending on how a user has voted on a post. The solution I came up with is this: Have 2 upvote buttons in the _upvote partial, and have 2 downvote buttons in the _downvote partial. Each partial will have one voting button that is activated when the case is already true, and clicking on it again will destroy it (for example, if a post is already upvoted on, then reclicking the upvote button will destroy it). The other button(s) in the partial will be activated in the case that the button has not been used yet (in which case clicking the button will create it).
Example:
****The _upvote partial should have the following buttons in it:****
1)create_upvote
2)destroy_upvote
****The downvote partial should have the following buttons in it:****
1)create_downvote
2)destroy_downvote
Whichever buttons are activated will depend on the controller.
My question(s) are this:
1) What is the actual syntax to a render partial view from another controller? For example: posts is rendering _post, and within that I want _upvote or _downvote to be rendered. How to render _upvote or _downvote from the controller. Again, the reason I WANT to render these partials from a controller is because the controller will be changing their state.
Downvotes partial
app/views/posts/_downvote.html.erb
Upvotes partial
app/views/posts/_downvote.html.erb
Posts partial
app/views/posts/_post.html.erb
Downvotes controller
Upvotes controller
Line 9 in the controllers is where my syntax is off! What is the syntax to render _upvote and _downvote partials, within the _posts partial? Thanks mates!
As far as syntax goes, what you want is the following:
render partial: "posts/upvote"
Instead of sending html data (the buttons you mentioned) from controller to the partial, you should have a conditional statement in each partial that activates one button or another. From there create event handlers for each respective button. That takes care of the issue of Jquery handling internal state.
Just a small note for the special cast of partials inside views/layouts/_upvote.html.erb, you should use
render partial: "layouts/upvote"
(not application/upvote)

How to alter the view based on which radio button is selected (without javascript) in Ruby on Rails

I have a form with radio buttons on a page.
I also have a helper method called vanish that adds
raw' style="display: none;" '.
In my view I would like to be able to call a boolean value based on which radio button is selected to activate/deactivate the helper method. The goal would look something like this
<p <%= vanish unless x %> > Stuff that only shows when a certain radio button is selected </p>
I am trying to do this without JavaScript. I am using Ruby on Rails 3.2.13
If you need anything else let me know.
Edit. I have seen this done in rails 2.3 where x would be params[:name] != 'value. This however does not dynamically change the page in rails 3.2
If you need this stuff to change after the page loads, you must use JavaScript. All your Ruby code is going to be executed before the user sees the page.
If this only has to do with the initial view of the page, then you're fine - all you need to do is have a variable that determines which button starts out selected, and use it for both the conditional (x, in your code), and elsewhere in the view where you display the radio buttons - see Rails - How to make a conditional Radio Button checked? for details on setting a default selected radio button like this.

In nested_form_for, link_to_add with radio buttons not sending enough info about selected item

I am using Ryan Bates' nested_form code and am having a problem in a nested form with radio button fields (the field is a boolean in the collection where only one of the members should be true).
My code to render the radio button inside the nested_form_for is:
<%= radio_button_tag "correct_distractor", d.object.id, d.object.correct %>
(if I use the usual form_for syntax and call radio_button on the nested_form_for object, the radio button does not behave like a radio button in that checking on does not uncheck the others)
Now usually when the user clicks one of the radio buttons to change the selected item the id of the new item is sent in the params, so it's fine (after a little bit of somewhat ugly parsing in the controller's update method). But...on new items that are added at runtime with link_to_add, there is no id to send, so all that is sent is:
"correct_distractor" => "on"
So can someone explain to me the proper way to implement radio buttons in a nested form when only one element of the collection should have the value turned on?

Best way to add "uncheck radiobuttons" - functionality in Rails?

Scenario: I have a dropdown-list with radiobuttons, that are not required to be selected to submit the form, and after I've chosen an option, from there on it's impossible to deselect it. I want it to be possible somehow.
Thoughts for solutions:
1) Implement some feature that enables you to deselect the radiobutton, much like a checkbox. This seems like a poor idea.
2) Add a 'reset radiobutton' option in the dropdown-list, that resets the radiobuttons when selected.
3) Add a 'reset all radiobuttons' button. Possibly for all dropdowns on the page.
4) Create a 'placeholder' option in the dropdown-list, that does nothing. The question here is, if I already made a selection X and submitted the form, if I later on choose selection Placeholder, any data that was saved when selection X was made has to be reverted.
So far I'm thinking option 2 is the best, but want to hear your ideas.
This is the code that I'm working with right now:
<% form.inputs do %>
<% #account.account_preference.editorial_attributes.each do |key, value| %>
<%= account_pref.input "editorial_#{key}".to_sym, :as => :radio, :collection => (options_for(Editorial, key.to_sym) + option_text_and_value("Reset radiobuttons")), :wrapper_html => { :class => "compact" }, :label => key.titleize %>
<% end %>
Where options_for(Editorial, key.to_sym) collects the options that actually do something, and option_text_and_value("Reset radiobuttons") is supposed to add another option that I then can link to the functionality to uncheck the radiobuttons.
This doesn't quite work as expected, as option_text_and_value returns two options instead of one. I have tried to search for some other option method on apidock but haven't found one yet. This isn't the primary question but if anyone knows about this and comments I'd be very grateful.
So to wrap it up: What way to go do you think is the best?
Regards,
Emil
Radio buttons are meant to choose something out of a group of options. Any time I see a group of radio buttons with none selected, I think whoever designed it doesn't understand radio buttons. Maybe you need to add a "None of the above" radio button?
I don't know why on earth you would want to put radio buttons in a drop down list. That sounds confusing to users. Why not just select the drop down option the normal way? Is this a business requirement?
If you absolutely have to do it, I think option 2 is the best one you've presented, although I don't know if it needs to be an option in the drop down list. It might work better as a link or a button next to or under the list. The list and the link (or button) should be in a containing div so that the corresponding drop down is easy to find, in the event that you have multiple drop downs like this on the page. From there it's easy enough to attach some javascript to the link (or button) which will deselect all radio buttons in the list.
But I still suggest that having radio buttons in a drop down list is just bad design from a user's perspective and I have no idea what this would accomplish.
I have a similar problem actually, and there is definitely sometimes a requirement to deselect a form element built out of radio buttons.
At the moment I am working on a multi-step form that has only a few required fields (think questionnaire), with the user being able to step back to previous pages in the form, allowing to deselect previous answers filled in by radio buttons.
The problem is not so much deselecting the radio buttons, this can be easily done by hanging some jQuery on the element, and controlling it through its events, but Rails is being too clever in its posting of the form data, leaving out fields that have no value, and therefor not updating the value to nil in the database, leaving me with the originally selected value when I step back in the form.
So what I am thinking of doing is having a model method for radio button fields that will empty out the values when nothing is being submitted for a particular page (the one each particular radio button fields lives on).
As for your original question: Just create a jQuery click event for your radio button control (by HTML class), and onclick you check whether the option value clicked, has its checked='checked' set, and if so, remove the checked option and it should deselect (theoretically).
I agree with #davidkovsky's answer. But i used this hint to implement toggle feature for rails radio button. We can add a hidden radio button with the same key and check it once we click on an already checked radio button.
<div style="display:none">
<%= form.radio_button :key_1, id:"hiddenselector" %>
</div>
<%= form.radio_button :key_1, class: "key1selector" %>
$(document).on('click', '.key1selector', function() {
if($(this).hasClass('checked')){
$(this).prop('checked', false);
$('#hiddenselector').prop('checked', true);
$('#hiddenselector').attr('checked', 'checked');
}else{
$(this).prop('checked', false);
$(this).addClass('checked');
}
});

Resources