0

Spoiler alert: this is a stupid question ;)

I have a Rails form where I display avatar images for the user to select, fetched from the services associated with the user account via Omniauth. It looks like this and it renders without any issues:

<%= form_for @user, :remote => true do |f| %>
  <% @services.each do |service| %>
    <% if service.avatar == @user.avatar %>
      <%= link_to image_tag(service.avatar), '#', :size => "48x48", :id => "current_avatar" %>
    <% else %>
      <%= f.text_field :avatar, :value => service.avatar, :type => :hidden, :class => "clickable"%>
      <%= image_tag(service.avatar, :class => "clickable") %>
    <% end %>
  <% end %>
<% end %>

The relevant part of my application.js file looks like this:

$('.clickable').live('click', function() {
  $(this).parents('form:first').submit();
});

The jquery-rails gem is installed and working ok.

The issue is that this setup obviously submits the whole form, making the user avatar be the last one on the list, no matter which one the user clicks.

Is it possible to submit only the field associated with the image clicked by the user?

I have a good understanding of Rails but JQuery is completely new to me, so I'm really lost. Googled a lot and couldn't find anything. At least nothing that I could understand ;)

2 Answers 2

2

One thing you can do is to use your callback function to remove all the elements with the clickable class (except for that one that was clicked) before you submit the form something along the lines of:

$('.clickable').live('click', function() {
    $(this).siblings(".clickable").remove();
    $(this).parents('form:first').submit();
});

Although in the case of your form that will likely remove all the hidden text fields you have, since the user clicks on the visible images rather than the hidden text field. So you might need to get a bit more fancy with your jquery. You would likely need to:

  • grab the value of the src attribute of your image tag
  • find the hidden text field that corresponds to it (i.e. has the same string in its value attribute)
  • remove all elements with the clickable class except for that one text field

Something along the lines of:

$('.clickable').live('click', function() {
    src_tag_value = $(this).attr("src");
    relevant_input = $(this).siblings("input.clickable[value='"+src_tag_value+"']");
    relevant_input.siblings(".clickable").remove();
    $(this).parents('form:first').submit();
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much for all this info! I marked the previous answer as correct since it fixed my problem. I hadn't reloaded the page, so I didn't see your answer. I'll try to play with it and see how it works. I'm sorry I don't have enough reputation to vote up your answer, but I thank you through this comment!
1

Why are you using hidden text fields for this? I think radio buttons would serve you better. Just create one radio button per avatar (with the current selection checked by default), make sure they all have the same name, and then wrap the image_tag elements in <label>s so that people can click on something. The values for the radio buttons would be the same :value => service.avatar that you're using for the text fields.

Once that's in place, you can submit away and it's all good as the form will only return one of the avatars.

1 Comment

Mu, your approach is obviously the most logical and correct. Can't thank you enough. Saved the day! Thank you very very much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.