Reder class for a collection_radio_buttons within simple_form - ruby-on-rails

I am using simple_form to create a form within my Rails project.
<%= simple_form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post, id: 'invitations-form', class: 'invitations-form'} do |f| %>
<%= f.input :first_name, label: false, placeholder: "Family Member's First Name", input_html: { maxlength: 15, size: 40, value: nil } %>
<%= f.input :last_name, label: false, placeholder: "Family Member's Last", input_html: { maxlength: 15, size: 40, value: nil } %>
<%= f.input :email, label: false, placeholder: "Enter Email Address", input_html: { value: nil } %>
<div class="radio_buttons">
<%= f.label "#{:gender}:"%>
<%= f.collection_radio_buttons :gender, [["male", "male"] ,["female", "female"]], :first, :last %>
</div>
<%= f.input :invitation_relation, label: false, prompt: "I am this person's:", collection: relation_types, label_method: :humanize, input_html: { class: "browser-default dropmodule__input-select" } %>
<%= submit_tag "Send Invitation" %>
<% end %>
I have used the collection_radio_buttons method to create, well, a collection of radio buttons. I'm not sure this is relevant, but the reason I used this method instead of f.input :foo, as: :radio_buttons was due to the fact that the input method wasn't producing a label tag for me, which I think I could now produce using label_html. I'm not sure if this would be a viable alternative, but this bug is bothersome to me due to the time I've spent on it.
Here's the html generated output for the relevant div above:
<div class="radio_buttons">
<label class="string optional control-label" for="user_gender:">Gender:</label>
<span>
<input checked="checked" id="user_gender_male" name="user[gender]" type="radio" value="male">
<label class="collection_radio_buttons" for="user_gender_male">male</label>
</span>
<span>
<input id="user_gender_female" name="user[gender]" type="radio" value="female">
<label class="collection_radio_buttons" for="user_gender_female">female</label>
</span>
</div>
I need the input tag for each radio_button to contain a class of "with-gap", like so:
<input checked="checked" id="user_gender_male" class="with-gap" name="user[gender]" type="radio" value="male">
and
<input id="user_gender_female" class="with-gap" name="user[gender]" type="radio" value="female">
but I have been unsuccessful. Although I really want to solve the issue by placing the class within the label of the collection_radio_buttons method, if there is an alternative within simple_form please show this as a solution.

OK, I found the answer here:
https://stackoverflow.com/a/30619068/4379077
What I needed to do was add an item_wrapper_class as the 5th argument to the method. It doesn't look like it's optional. When I try to remove it from the argument list my class argument (the 6th arg in the method) gets ignored. Here's the final input:
<div class="radio_buttons">
<%= f.label "#{:gender}:"%>
<%= f.collection_radio_buttons :gender, [["male", "male"] ,["female", "female"]], :first, :last, {:item_wrapper_class => 'foo-bar'}, {:class => "with-gap" } %>
</div>
and final output:
<div class="radio_buttons">
<label class="string optional control-label" for="user_gender:">Gender:</label>
<span class="foo-bar">
<input checked="checked" class="with-gap" id="user_gender_male" name="user[gender]" type="radio" value="male">
<label class="collection_radio_buttons" for="user_gender_male">male</label >
</span>
<span class="foo-bar">
<input class="with-gap" id="user_gender_female" name="user[gender]" type="radio" value="female">
<label class="collection_radio_buttons" for="user_gender_female">female</label>
</span>
</div>
If anyone knows how to make the inline_wrapper_class optional please let me know.

Related

Ruby on Rails Devise edit registration form with ability to select or add a separate model (e.g. Company)

I have a User model and a Company model (amongst others) and an "Edit Profile" page with a form. One field of the form is to select a company from a list and save to the Users table in a column called "company_id", which is linked to the ID of each Company in the Companies table.
This all works great.
However, I would prefer to have a text field in which a user can start typing a company name and select a suggestion or create a new Company if theirs is not in the database.
I'm new to ruby and would like to know the best way to do this if anyone can help.
app\views\devise\registrations\edit.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<div id="errorexplanationcontainer"><%= devise_error_messages! %></div>
<div class="mdl-textfield mdl-js-textfield">
<%= f.text_field :first_name, class: 'mdl-textfield__input', autofocus: true %>
<label class="mdl-textfield__label" for="first_name">First name</label>
</div>
<div class="mdl-textfield mdl-js-textfield">
<%= f.text_field :last_name, class: 'mdl-textfield__input' %>
<label class="mdl-textfield__label" for="last_name">Last name</label>
</div>
<!-- Company Field -->
<div class="field">
<%= f.label :company_id %>
<%= f.select :company_id, Company.all.collect {|company| [company.name, company.id]}, {:include_blank => "Select One"}, id: :job_company_id %>
</div>
<!-- End -->
<div class="mdl-textfield mdl-js-textfield">
<%= f.text_field :job_title, class: 'mdl-textfield__input' %>
<label class="mdl-textfield__label" for="job_title">Job Title</label>
</div>
<div class="mdl-textfield mdl-js-textfield">
<%= f.email_field :email, class: 'mdl-textfield__input' %>
<label class="mdl-textfield__label" for="email">Email</label>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="mdl-textfield mdl-js-textfield">
<%= f.password_field :password, class: 'mdl-textfield__input', autocomplete: "off" %>
<label class="mdl-textfield__label" for="password">New password</label>
</div>
<div class="mdl-textfield mdl-js-textfield">
<%= f.password_field :password_confirmation, class: 'mdl-textfield__input', autocomplete: "off" %>
<label class="mdl-textfield__label" for="password_confirmation">Confirm password</label>
</div>
<button id="show-dialog" type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
UPDATE
</button>
<dialog class="mdl-dialog">
<h4 class="mdl-dialog__title">Save Changes</h4>
Re-enter your password to save changes to your account.
<div class="mdl-textfield mdl-js-textfield">
<%= f.password_field :current_password, class: 'mdl-textfield__input', autocomplete: "off" %>
<label class="mdl-textfield__label" for="current_password">Current password</label>
</div>
<div class="mdl-dialog__actions">
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
<%= f.submit "UPDATE", class: 'hideinput' %>
</button>
<button type="button" class="mdl-button close">CANCEL</button>
</div>
</dialog>
<script>
var dialog = document.querySelector('dialog');
var showDialogButton = document.querySelector('#show-dialog');
if (! dialog.showModal) {
dialogPolyfill.registerDialog(dialog);
}
showDialogButton.addEventListener('click', function() {
dialog.showModal();
});
dialog.querySelector('.close').addEventListener('click', function() {
dialog.close();
});
</script>
<% end %>
I have used Twitter typeahead in on of my projects. It is pretty smooth and light, you just have to pass an array to it and it does the trick for you.
Some detailed documentation and examples are listed here: https://twitter.github.io/typeahead.js/examples/
Bundle install twitter-typeahead-rails
In your application.js, add the following line above require_tree:
//= require twitter/typeahead.min
In your controller, you can initialize the array:
#companies = Company.pluck(:name)
In your view:
<div id='search'>
<%= f.text_field :company, class: 'mdl-textfield__input' %>
</div>
Javascript:
var companies = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.whitespace,
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: #{#companies},
});
$('#search .mdl-textfield__input').typeahead('destroy').typeahead({
hint: true,
highlight: true,
minLength: 2
},
{
source: companies
});

Unable to combine a normal form with Dropzone.js

In My Rails app I need the user to be able to post Facebook-style posts that would always contain text and optionally an image. I need this to happen without a page reload.
Since I'd like to use Dropzone.js to manage the asynchronous image uploads, I've been trying to combine my form with Dropzone without success. I've used mainly this source.
I'm a bit lost here. What I've tried is below. Could you point me into the right direction?
My form here
<%= simple_form_for(#post, remote: true, :authenticity_token => true, html: { multipart: true, class: 'form-inline dropzone', id: 'new_post_form'}) do |f| %>
<div class="dropzone-previews"></div>
<%= f.input :content, :label => false, :placeholder => " Say something here!", as: :text, :required => true, :autofocus => true, :input_html => { id: "new_post_content_field" } %>
<%= f.input :poster_id, :as => :hidden, :required => true, :autofocus => true, input_html: {value: current_user.id } %>
<%= f.input :poster_type, :as => :hidden, :required => true, :autofocus => true, input_html: {value: current_user.class } %>
<%= f.input :community_id, :as => :hidden, :required => true, :autofocus => true, input_html: {value: #community.id } %>
<div class="fallback">
<%= f.input :post_image, :label => false %>
</div>
<%= f.button :submit, input_html: {id: 'submit-all' } %>
<% end %>
The resulting html
<form class="simple_form form-inline dropzone dz-clickable" id="new_post_form" novalidate="novalidate" enctype="multipart/form-data" action="/posts" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="3OC6YhVKtCvjXk0QIHQUUG+72PtkkN3NieWvtLmYzitsh2vDvhu2ggPJBcbDII+39CHuFaRqdRHXK27eR6W1Bw==">
<div class="dropzone-previews"></div>
<div class="form-group text required post_content"><textarea class="form-control text required" id="new_post_content_field" autofocus="autofocus" required="required" aria-required="true" placeholder=" Say something here!" name="post[content]"></textarea></div>
<div class="form-group hidden post_poster_id"><input class="form-control hidden" value="2" autofocus="autofocus" required="required" aria-required="true" type="hidden" name="post[poster_id]" id="post_poster_id"></div>
<div class="form-group hidden post_poster_type"><input class="form-control hidden" value="Participant" autofocus="autofocus" required="required" aria-required="true" type="hidden" name="post[poster_type]" id="post_poster_type"></div>
<div class="form-group hidden post_community_id"><input class="form-control hidden" value="1" autofocus="autofocus" required="required" aria-required="true" type="hidden" name="post[community_id]" id="post_community_id"></div>
<input type="submit" name="commit" value="Create Post" input_html="{:id=>"submit-all"}" class="btn btn-default" data-disable-with="Create Post">
<div class="dz-default dz-message"><span>Drop files here to upload</span></div></form>
application.js
Dropzone.options.newPostForm = {
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
paramName: "post[post_image]",
init: function() {
var myDropzone = this;
$("#submit-all").click(function (e) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
}
}
Create Action in the Posts controller
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
#post_comment = Comment.new()
format.js
format.json { render json: { message: "success", fileID: #post.id }, :status => 200 }
else
format.js {render inline: "toastr.error('Something went wrong');"}
format.jsnon { render json: { error: #post.errors.full_messages.join(',')}, :status => 400 }
end
end
end
Currently, if I hit 'submit' I get the flowing params
<ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"3OC6YhVKtCvjXk0QIHQUUG+72PtkkN3NieWvtLmYzitsh2vDvhu2ggPJBcbDII+39CHuFaRqdRHXK27eR6W1Bw==", "post"=>{"content"=>"ddddddd", "poster_id"=>"2", "poster_type"=>"Participant", "community_id"=>"1"}, "commit"=>"Create Post", "controller"=>"posts", "action"=>"create"} permitted: false>
So it seems no params that are related to the image are sent to the controller and I'm not sure how I can solve this.
I ended up finding what was the issue.
The input field for the image (below) shouldn't have been included in the form helper
<%= f.input :post_image, :label => false %>
And I was making a mistake setting the id of the submit button. I was using:
<%= f.button :submit, input_html: {id: 'submit-all' } %>
instead of:
<%= f.button :submit, id: 'submit-all' %>
This prevented the JS to select the appropriate form button.

Rails fields_for in fields_for rows not associating with parent id

I am trying to add some custom questions to the bottom of my form. However the id of the question isn't being associated with the answer field. How would I go about this?
input.html.erb
<% #event.event_questions.each do |question| %>
<%= f.simple_fields_for :event_question, question do |answer| %>
<%= answer.simple_fields_for :event_answer do |e| %>
<%= e.input :answer, label: question.question %>
<% end %>
<% end %>
<% end %>
output.html
<div class="form-group string required participant_event_question_event_answer_answer"><label class="string required control-label" for="participant_event_question_event_answer_answer"><abbr title="required">*</abbr> Goals</label><input class="string required form-control" type="text" name="participant[event_question][event_answer][answer]" id="participant_event_question_event_answer_answer" /></div>
<div class="form-group string required participant_event_question_event_answer_answer"><label class="string required control-label" for="participant_event_question_event_answer_answer"><abbr title="required">*</abbr> Action Plan</label><input class="string required form-control" type="text" name="participant[event_question][event_answer][answer]" id="participant_event_question_event_answer_answer" /></div>
<div class="form-group string required participant_event_question_event_answer_answer"><label class="string required control-label" for="participant_event_question_event_answer_answer"><abbr title="required">*</abbr> Vision</label><input class="string required form-control" type="text" name="participant[event_question][event_answer][answer]" id="participant_event_question_event_answer_answer" /></div>
Assuming you have question_id in answers table, you can try the below code.
<% #event.event_questions.each do |question| %>
<%= f.simple_fields_for :event_question, question do |answer| %>
<%= answer.simple_fields_for :event_answer do |e| %>
<%= e.input :answer, label: question.question %>
<%= e.input :question_id, as: :hidden, input_html: { :value => question.id }
<% end %>
<% end %>
<% end %>

how to add text in label tag simple_form

I'm using simple_form and trying to add text before the closing label tag.
<label>search</label>
This is what I have
<%= simple_form_for "", html: { id: "searchform1", class: "searchform", role: "search" }, :method => :get do |f| %>
<%= f.input "", wrapper: false, label_html: { id: "spanLabel0", class: "fLabel"}, input_html: {size: 27, name: "s", id: "s1", class: "s", title: "search"} %>
<%= f.submit "search", :type => :image, :src => "/assets/search.png", id: "searchsubmit1", class: "searchsubmit" %>
<% end %>
I'm looking to reproduce this (notice "search" before closing label tag):
<form accept-charset="UTF-8" action="/" class="simple_form searchform" id="searchform1" method="get" role="search">
<label class="string required control-label fLabel" for="s1" id="spanLabel0">search</label>
<input class="string required s" id="s1" name="s" size="27" title="search" type="text">
<input class="searchsubmit" id="searchsubmit1" name="commit" src="/assets/search.png" type="image" value="search">
</form>
If you want to have a label of Search for you form, simply put <%= f.label :search %>: before the f.input tag. You'll find more info on that in the Action View form Helper documenttion

How to add sr-only class to input's label?

I have simple form:
<%= simple_form_for #link do |f| %>
<%= f.input :url, placeholder: "http://..." %>
<%= f.button :submit, "Submit Link", class: "btn-primary" %>
<% end %>
it outputs input like this:
<div class="form-group url required link_url">
<label class="url required control-label" for="link_url">
<abbr title="required">*</abbr> Url
</label>
<input class="string url required form-control" placeholder="http://..." type="url" name="link[url]" id="link_url">
</div>
How can I add 'sr-only' class to label element?
Just do:
<%= f.input :url, placeholder: "http://...", label_html: { class: 'sr-only' } %>

Resources