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.
Related
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.
I am working on rails 3 and using ajax to load a form, there is a country drop down that has values thats not loading properly. Its loading html entities of the "<" and ">" sign like "<" & ">".
This is how i am rendering the partial that has the countries list
$j('#insert_to').append("<%= escape_javascript(render :partial => 'verified_address', :locals => { :item => #item, :original_item => nil, :update_alert => false }).html_safe %>");
The output i am getting is
<span id=\"ship_to_country_container\">\n
<select id
=\"item_ship_to_country\" name=\"item[ship_to_country]\"><option value=\"\">-- Select --<\/option>\n
<option value="" disabled="disabled">-------------</option>\n<option
value="Afghanistan">Afghanistan</option>\n<option value="Aland Islands"
;>Aland Islands</option>\n<option value="Albania">Albania</option>\n<
;option value="Algeria">Algeria</option>\n<option value="American Samoa"
;>American Samoa</option>\n<option value="Andorra">Andorra</option>\n
<option value="Angola">Angola</option>\n<option value="Anguilla">
;Anguilla</option>\n<option value="Antarctica">Antarctica</option>\n<option
value="Antigua And Barbuda">Antigua And Barbuda</option>\n<option value="
;Argentina">Argentina</option>\n<option value="Armenia">Armenia</option
>\n<option value="Aruba">Aruba</option>\n<option value="Australia"
;>Australia</option>\n<option value="Austria">Austria</option>\n<option
value="Azerbaijan">Azerbaijan</option>\n<option value="Bahamas">Bahamas
</option>\n<option value="Bahrain">Bahrain</option>\n<option value="
;Bangladesh">Bangladesh</option>\n<option value="Barbados">Barbados<
;/option>\n<option value="Belarus">Belarus</option>\n<option value="
;Belgium">Belgium</option>\n<option value="Belize">Belize</option>
;\n<option value="Benin">Benin</option>\n<
html entities are getting rendered and not the actual tags
1st call: $j.ajax({
url: "/items/validate_address",
type: 'POST',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $j('meta[name="csrf-token"]').attr('content'))},
data: data_address,
dataType: 'script'
});
this call the validate_address
<div id="verified_address" style="display:none">
<div id="verified_address_form" style="display:none;">
<%= form_for(item, :remote => true) do |f| %>
<%= render :partial => 'shipments/ship_to_address_form', :locals => {:f => f, :item => item}%>
<input type="hidden" name="update_alert" id="update_alert" value="<%= update_alert %>" />
<p><%= f.submit "Save", :style => 'width: 60px;' %> <%= link_to_function "Cancel", "$('verified_address_view','verified_address_form').invoke('toggle');$('order_address_id').style.position = '';$('order_address_id').style.zIndex = '';" %></p>
<% end %>
</div></div>
3rd Step: shipments/ship_to_address_form has the country dropdwon
<tr>
<td><label for="item_ship_to_country">Country</label></td>
<td>
<span id="ship_to_country_container">
<%= f.country_select :ship_to_country, {},{:selected => item.ship_to_country, :include_blank => '-- Select --'} %>
</span>
I figured out that the issue was the country_select call, i installed the gem country_select and the issue was resolved. Thanks for all your suggestions and help.
Its a messaging app but it only shows all the users. How do I show the current user?
<%= form_for :conversation, url: :conversations, html: { class: "" } do |f| %>
<div class="modal-body">
<form>
<div class="form-group">
To:
This code works by showing the users name, but when its sent.... it doesn't get saved.
<input type="text" class="form-control" id="recipient-name">
The code bellow is the only one that works but it shows all the users..
<%= f.select(:recipients, User.all.collect {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
</div>
This is the rest of the code.
<div class="form-group">
Subject:
<%= f.text_field :subject, class: "form-control" %>
</div>
<div class="form-group">
Message:
<%= f.text_area :body, class: 'form-control', placeholder: "Type your message here", rows: 4 %>
</div>
Full code:
<%= form_for :conversation, url: :conversations, html: { class: "" } do |f| %>
<div class="modal-body">
<form>
<div class="form-group">
To: <input type="text" class="form-control" id="recipient-name">
<%= f.select(:recipients, User.name {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
</div>
<div class="form-group">
Subject:
<%= f.text_field :subject, class: "form-control" %>
</div>
<div class="form-group">
Message:
<%= f.text_area :body, class: 'form-control', placeholder: "Type your message here", rows: 4 %>
</div>
Assuming you know your current user's id, just change:
<%= f.select(:recipients, User.all.collect {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
To:
<%= f.select(:recipients, User.where(id: current_users_id ).collect {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
Instead of returning an array of every user, and operating upon that, this will simply return an array of the one user you care about. That said, with a better understanding of your application as a whole, we could definitely find better display options.
Does this work?:
<%= f.collection_select :recipients, User.all.where('name is not ?', nil), :id, :name,
{ prompt: "Choose User..." } %>
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
So i'm trying a while now to get the popover work with Simple_form..
My register.js.coffee file:
$(".user_first_name").popover()
My Input:
<%= f.input :first_name, input_html: { class: "user_first_name", :rel => "popover", 'data-toggle:' => 'popover', 'data-trigger:' => 'hover', 'data-content:' => 'Some popover content' }%>
I tried in many ways to get this working but i don't know what i'm missing..
The Html Outpout of this is :
<div class="controls">
<input autofocus="autofocus"
class="string required user_first_name"
data-content:="Some popover content"
data-toggle:="popover"
data-trigger:="hover"
id="user_first_name"
name="user[first_name]"
rel="popover"
type="text">
</div>
A working Example
What am i missing ?
The data attributes are wrong. Try this:
<%= f.input :first_name, input_html: { class: "user_first_name", rel: "popover", data: { toggle: 'popover', trigger: 'hover', content: 'Some popover content' } %>