I'm using Carrierwave to add and upload an image to Amazon S3. this works ok, and once the form is saved I display the image and an x box to remove it.
I would like to use ajax to handle the click event on the 'x' image' on click I would like to remove the image and clear the field on the form so that the input field is once again displayed
The image field is an attribute of the model class i am editing in the form.
Person < ActiveRecord
attr_accessible: image
the partial for this part of my form shows the image if it exists, otherwise the input file_field if it does not exists
<div class="field">
<%= image_tag #pass.background_image_url(:thumb) if #pass.background_image? %>
<%= f.file_field :background_image if #pass.background_image.to_s == '' %>
<%= content_tag :div, '', class: "delete_image_fields" if #pass.background_image? %>
</div>
I have some jquery which i can sccessful hide the image field.
jQuery ->
$('.field .delete_image_fields').click ->
$(this).parent().find('img').hide()
event.preventDefault()
The image field gets hidden no problem
What i would like to happen is
a) clear the input field from the pass object
b) submit the change (remotely)
c) delete the remote image on S3
e) re-display the file_input field for the image so it can re-selected if required
Any help or pointers would be appreciated
UPDATE
I've got this partially working to display corect fields and adjust the input link. but i'm not sure how to actually delete the file from the models attribute
I've updated the partial to the following which dispalsy either the image ro the create file button
<div class="field">
<%= f.label :background_image %><br />
<% if #pass.background_image?%>
<%= image_tag #pass.background_image_url(:thumb) %>
<%= f.file_field :background_image , style: "display:none"%>
<%= content_tag :div, '', class: "delete_image_fields" %>
<% else %>
<%= f.file_field :background_image%>
<% end %>
and updated my jquery to this
$('.field .delete_image_fields').click ->
$(this).parent().find('img').hide()
$(this).hide()
$(this).parent().find('input').val('')
$(this).parent().find('input').show()
event.preventDefault()
To delete the file, you could take advantage of the remove_mounted_field_url carrierwave creates.
From here I see two solutions, either create a new action in your controller that will only remove the file, either use the update action. I like to use as much as possible the original actions(index/new/create ...), so I will use the second solution.
You need to do an AJAX PUT request when clicking on the X box. Here what it could look like :
$('.field .delete_image_fields').click ->
$(this).parent().find('img').hide()
$(this).hide()
$(this).parent().find('input').val('')
$(this).parent().find('input').show()
event.preventDefault()
$.ajax
url: $(this).getParents('form').first().attr('action')
method: 'PUT'
data:
person:
remove_image: 1 # This will trigger the carrier wave function that remove the uploaded file
.done (data) ->
# You can do plenty if things here, for instance notify the user it's been correctly deleted
Note that this will only work on an edition form, as the url of the AJAX query which has to target the update action is taken from the form. I don't think this is a problem, as on the create form no photos is already uploaded, so there's nothing to delete.
Last thing, you could use the siblings method to find both inputs and the image
Related
I have submit button and i want to redirect in another URL (hard coded) this URL
https://www.ccavenue.com/shopzone/cc_details.jsp
my code :
<%= form_tag #ccavanue do |f| , url => "https://www.ccavenue.com/shopzone/cc_details.jsp", :html => :method => "put" %>
<%= hidden_field_tag :my_field, #MerchantId, :id => 'merchant_id' %>
<%= submit_tag "Click Me" %>
<% end %>
i want to redirect another website URL with this submit button . please guided me.
Change your code to following:
<%= form_for #ccavanue, url: "https://www.ccavenue.com/shopzone/cc_details.jsp" do |f| %>
<%= f.hidden_field :my_field, #MerchantId, :id => 'merchant_id' %>
<%= f.submit "Click Me" %>
<% end %>
In Rails a form is designed to create or update a resource and reflects the identity of the resource in several ways:
The url that the form is sent to (the form element's action attribute) should result in a request being routed to the appropriate controller action (with the appropriate :id parameter in the case of an existing resource),
Input fields should be named in such a way that in the controller their values appear in the appropriate places within the params hash, and
For an existing record, when the form is initially displayed, input fields corresponding to attributes of the resource should show the current values of those attributes.
In Rails this is achieved by creating form using form_for where:
If we want to create any object we use POST method within url and PUT method if we are trying to update an existing record.
Rails framework is smart enough to use POST or PUT method by itself looking at the url of the form. So in this case we need not use method parameter within form_for url.
Probably you can start with Michael Hartl's tutorial
I have a Comment model which belongs to both User and Story. Creating a comment correctly associated to the appropriate User and Story is working fine but when trying to edit the comment my edit action appears to retrieving the wrong record.
The offending action in comments_controller.rb:
def edit
#story = Story.find_by(params[:story_id])
#comment = #story.comments.find_by(params[:id])
end
The link used to render the comments/edit view:
<%= link_to 'edit', edit_story_comment_path(comment.story_id, comment.id) %>
The corresponding view:
<%= form_for(#comment, url: { controller: 'comments', action: 'update' }) do |f| %>
<%= f.text_area :content %>
<%= f.submit "update" %>
<% end %>
The edit view appears to be rendering the most recently added comment regardless of which #comment I am trying to edit.
You're using find_by, which is basically a magic find_by_X method, with no fields specified. find_by(1) generates invalid SQL for me using Postgres, but it might be that whatever database back-end your using accepts it.
Regardless, find_by certainly won't do what you want it to do.
You should be using find, if you want to find records by id:
#story = Story.find(params[:story_id])
I'm trying to implement some Ajax in my app. A strange behaviour occurs!
It's a daycare application. When you show a specific daycare of a specific date you can add some children.
Originally a list of the children of the database is generated and when you click on one of them the page reload and a new child appears in the attendance list of the daycare. It's working fine, i just wanna add some ajax to be more userfriendly !
When you click on child to add him to the daycare, a daycare_item is created ( join table, an id of the child and the id of the daycare ).
I make the changes to make it ajax ready:
partial for the list
format.js in the daycare_item controller
remote true on the link.
It works, no more reload! But the list is updated only when you click a second time on the children list ( the last child added doesn't appears yet ). The js transaction works and if you refresh manually the page, the missing child appears.
I tried few things and here are my results:
In my partial there are
<% #daycare.daycare_items.each do |c| %>
<li><%= c.child.firstname ></li>
<% end %>
This produce the "lag" effect with one children who is not showing ( until a full refresh )
But if i put a
<%= #daycare.daycare_items.count %>
the code is update in time !
I see nothing strange in the logs.
I'm asking why the .each method make a difference?
A var was stoping a part of the code to be executed, the var wasn't wrong and doesn't generate an error.
The elements involved:
daycare_items controller
def create
#daycare = Daycare.find(params[:daycare_id]) # for Ajax
#daycare_item = DaycareItem.new(params[:daycare_item])
....
end
the create.js.erb
$('#children-list').html(" <%=j render partial: 'daycares/daycare', locals: { daycare: #daycare } %> ");
the view daycares#show
<div id="children-list">
<%= render #daycare %>
</div>
the partial ( a part of ) _daycare.html.erb
<p>counting test:<%= daycare.daycare_items.count %></p>
# here was something like this <%= #waiting.count %> #waiting is define in the daycare controller but not in the daycare_items controller
<p>
<% daycare.daycare_items.each do |dci| %>
<%= dci.enfant.prenom %>
<% end %>
</p>
I found a number of questions and answers regarding updating a partial using Ajax after submitting a form. But my question is ?simpler?, I just want to reload a partial every few seconds and load in the new data. This really can't be hard at all, and I remember doing something similar in Rails 2.3 but I can't find the answer anywhere.
Basically, I have a show.html.erb rendering a partial like so:
<div id="latest_post">
<%= render :partial=>'info/latest', :object=>#user, :as=>:user %>
</div>
The partial file located at app/views/info/_latest
<% post = user.posts.last %>
<h1>Last Post</h1>
<p><%= post.content %></p>
I just want the latest_post div to be updated every 30 seconds. Please help!
Well it turns out the answer is a little complicated:
Step 1: Use Javascript's setInterval function along with jQuery's $.get() function to load a page, say /users/1/posts/latest.
setInterval(function(){
$.get("/users/1/posts/latest.js", function(data){
$("latest_post").html(data);
},
"html")
}, 30000);
Step 2: Create a latest.js.erb and put it in your app/views/posts folder.
Contents of latest.js.erb:
<%= render partial: 'posts/latest', object: #user.posts.last, as: :post %>
Step 3: Create the above partial with whatever you'd like (if you don't need a partial, you can just write the entire contents of the div in the latest.js.erb file.)
Step 4: Add a latest method to your PostsController, that defines #user, etc. for the latest.js.erb to use.
Step 5: Add get '/latest' to your routes.rb
I want to make a form for submitting the info needed to create an instance of model X and save it to the database, but I have a slight problem: I know how to add form fields like text areas and what not and then how to make those values accessible when the create method is called, but what if I want to also send make a value that is not part of the form accessible? For example, what if I want to be able to access some text in a <div> of my html document and send that to the create method for model X (so it can be stored in like a content variable or something)? How do I do that?
Short answer is you can't - to send data to the server, it has to be in an form field.
Longer answer - there are ways around this and you have several options - put the text in a textarea and style it to look like an div, or put it in a hidden field when the template is created, or use javascript to copy it into a hidden field ... all depends on what you are trying to do really. Perhaps you could give some more detail?
In your model you want to use attr_accessor
What you can do is use attr_accessor which creates a virtual attribute that you can use in the model but is discarded after that.
For example:
app/models.post.rb
class Post < ActiveRecord::Base
attr_accessor :some_variable
#now you can access 'some_variable' this variable in the model
#try Post.some_variable in the console
end
app/views/posts/_form.html.erb
<div id="form">
<div class="field">
<%= f.label :some_variable %>
<%= f.text_field :some_variable %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
</div>