Dropzone Rails 505 Error - javascript

I'm using dropzone-rails to add dropzone to my Rails app. I'm using CarrierWave for image uploads which is working fine without Dropzone.
I'm getting an error when I drop an image onto my dropzone form. The form is located on the edit page of my "Canvas" model.
Form html
<%= form_for(#canvas, :html => { :class => 'dropzone', :id => 'awesomeDropzone' }) do |f| %>
<%= f.file_field :image %>
<%= f.submit %>
<% end %>
Dropzone JS call
Dropzone.options.awesomeDropzone = {
paramName: "canvas[image]", // The name that will be used to transfer the file
clickable: false
};
Console error:
GET http://localhost:3000/canvases/21/edit 500 (Internal Server Error)
canvases_controller.rb
def edit
#canvas = Canvas.find(params[:id])
end
def update
#canvas = Canvas.find(params[:id])
if #canvas.update_attributes(update_params)
redirect_to edit_canvas_path(#canvas)
else
render :edit
end
end
canvas.rb
mount_uploader :image, ImageUploader
Full log data

As per the error,
ActionView::MissingTemplate (Missing template canvases/edit, application/edit with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
* "/Users/colmtuite/dev/design_tool/app/views"
):
You don't have edit view for canvases. Make sure that you have edit.html.erb file in app/views/canvases folder.
UPDATE
Also, I noticed that the request is going for Processing by CanvasesController#edit as JSON,
NOTE the format is JSON and not HTML. If you have edit.html.erb file and you want to render that particular view, make sure that you don't specify format as 'JSON' while calling edit action so by default format would be considered as HTML.
Change your update action as below:
def update
#canvas = Canvas.find(params[:id])
if #canvas.update_attributes(update_params)
redirect_to edit_canvas_path(#canvas, format: :html) ## Specify format as html
else
render :edit
end
end

dropzone using JSON format, not HTML, so
you can change controller to:
render nothing: true
or
render nothing: true, status: 200
Regards!

Related

Rails 5 - Rendering form submission results as js or some other format (e.g. PDF)

I'm trying to set up a form that takes in a set of criteria, runs a query using those criteria, and either displays the results in the browser window below the form (via js) or as a pdf (using Prawn) in a new window.
index.html.erb (the form):
<%= form_for :criteria, url: results_path, method: :patch, remote: true do |f| %>
...input fields...
<%= button_tag("View", remote: true, value: 'js', name: 'format' %>
<%= button_tag("PDF", remote: true, value: 'pdf', name: 'format', formtarget: '_blank') %>
<div id='report-results'>
</div>
<% end %>
controller:
def index
end
def results
#results = ...the query...
respond_to do |format|
format.js
format.pdf do
report = ResultsPdf.new(#results)
send_data report.render, filename: "Results_#{Date.today}.pdf", type: 'application/pdf', disposition: "inline"
end
end
end
results.js.erb:
$('div#report-results').empty();
$('div#report-results').html("<%= escape_javascript(render 'report_results') %>");
With this code, the View option works (renders the results in the browser) but the PDF option appears to do nothing. The server shows it hitting the controller as PDF, running the query, and sending the data but the pdf itself is not generated. If I remove remote: true from the form declaration then the PDF options works but the View option just renders the text of results.js.erb in the browser.
Here's how I got this to work (for now, anyway):
Removed the PDF button from the form, forcing the user to submit the form via ajax and view the results in the browser.
Added a link in the report_results partial and passed back the IDs of the records resulting from the run in step 1 as a param:
<%= link_to "PDF", results_path(ids: #results.ids, format: 'pdf'), class: "btn", target: "_blank" %>
Added an if/else block to the controller to determine if the request to the action came from the form submission or the pdf link:
if params[:criteria]
#results = ...query based on params[:criteria]...
elsif params[:ids]
#results = ...query based on params[:ids]...
else
...error handling...
end
Hackey? Probably. Does it work? Yeah.

Locals issue in Rails application

I am getting errors while doing an AJAX call with remote: true with locals. Here's the error:
ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x94db890>:0x9ab41d0>):
Here is my code below:
new.html.erb
<%= form_for(#author) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :age %><br>
<%= f.number_field :age %>
</div>
<%= link_to "Add Books" , remote: true %>
<div id = "add_book"></div>
<%= f.submit %>
Controller
def new
#author = Author.new
#books = #author.books.build
respond_to do |format|
format.html
format.js
end
end
new.js.erb
$("#add_book").append(" <%= escape_javascript(render partial: 'addbook', :locals => { :f => f }) %> ");
You are calling the new action of your controller using remote: true (an AJAX call). This will result in new.js.erb being rendered to be sent back as the response - the new.html.erb will not be processed.
Within new.js.erb you have:
$("#add_book").append(" <%= escape_javascript(render partial: 'addbook', :locals => { :f => f }) %> ");
Meaning it is attempting to render the addbook partial and set up a local variable for it, to be referenced in the partial as f, and assigning it the value (local to new.js.erb) f.
new.js.erb has not declared the local var f and thus your error.
To assist more we would need to know what the intention of this variable is - in what way does _addbook.html.erb require it?
So... the way that an erb template works is this:
Rails generates a page, in your example, this would be new by going through the new action in the controller and gathering up all the variables (eg author and books).
Then it gets the right template for the action. In the case when you first open up the new page you get the form... right? That comes from the new.html.erb template.
So rails reads through the template and runs the ruby code... replacing it with appropriate html. Then it sends the html to the browser.
By the time it's sent it to the browser, there is no longer any ruby code... just html, because the browser doesn't understand ruby, just html - so that's all that gets sent.
Now... the browser has an html form, that contains some js - this would be the add books link - it's html, that calls some js that sends a request to your rails app.
The rails app then goes through the new action, gathering the variables again, but this time, it doesn't render the html template... because it got called by js. So it grabs the js template instead.
At this point rails knows nothing about the html template. Anything that was in the html template is long gone - sent away to the browser. All it knows about is what is in the js template. It tries to run the ruby code in the template... and it's asking for f... and f doesn't exist in your js template... so it gets confused and tells you it doesn't know about this f thing.
It doesn't matter that at some point in the past it rendered a form called f, because that belonged to a way distant past request that no longer exists. The browser doesn't tell rails about f because it never knew about it (that was part of the ruby, not the html that is all that the browser ever saw). So... there is no f. ;)
In this case - I am not sure you need to pass f in as a local variable at all. If you are rendering the template that contains the form... then you don't need to pass in a form because it will already be rendering the form. Try just rendering the partial without passing in locals, and see what happens... if you get a bug, we can then work on that.

Rails 4: Turbolinks redirect with flash

Lets say I have a standard controller create action:
def create
#object = Object.new(object_params)
if #object.save
redirect_to #object, flash: {success: "Created object successfully."}
else
render :new
end
end
Now if I change the redirect to use turbolinks:
redirect_to #object, turbolinks: true, flash: {success: "Created object successfully."}
the server returns a text/javascript response, and my browser is displaying it as a white page with just this line of text on it:
Turbolinks.visit('http:/localhost:3000/objects/1');
How do I make it so my browser actually executes that code instead of displaying it as text?
Also, how can I get the flash success message to appear?
This is not a direct answer to your question. But I would suggest using unobtrusive JS for this. You'd want to add remote: true in your form first.
def create
#object = Object.new(object_params)
if #object.save
flash.now.success = 'Created object successfully.'
else
flash.now.alert = #object.errors.full_messages.to_sentence
end
render :js
end
Create a file create.js.erb containing only the following:
$('#flash').replaceWith("<%= j render partial: 'layouts/flash' %>");
This is what render :js will be rendered back to the browser, thereby executing a script that will replace your flash container (#flash or whatever id you used) with the new flash messages
Furthermore make sure that you have a partial view file app/layouts/_flash.html.erb which contains your flash HTML code.
Update:
If not using Unobtrusive JS. You can render the partial file like the following:
def create
#object = Object.new(object_params)
if #object.save
flash.now.success = 'Created object successfully.'
else
flash.now.alert = #object.errors.full_messages.to_sentence
end
render partial: 'layouts/flash'
end
Then in your HTML, you embed something like the following:
$('#myForm').ajaxForm({
url : '<%= url_for objects_path %>',
type: 'post',
dataType : 'json',
success : function (response) {
$('#flash').replaceWith(response);
}
});
P.S. You might also be interested with Wiselinks which actually does this already (partial view loading; you specify the target container to be replaced). Because currently turbolinks do not have support yet with partial loading, it always loads the whole body.
This is how I ended up solving this using Turbolinks and materialize toasts for a great flash UX:
In my controller:
format.js {
flash[:toast] = 'Created record successfully.'
render :create
}
In create.js.erb:
Turbolinks.visit("<%= success_path %>");
In my _flash.html.erb partial:
<% flash.each do |type, message| %>
<% if type == "toast" %>
<script id="toast">
$(function() {
Materialize.toast('<%= message %>', 3000);
});
</script>
<% elsif type == "success" %>
...
<% elsif type == "alert" %>
...
<% end %>
<% end %>

Rails 4 - manifest JS not available in AJAXed-in JS rendered partial

Good evening SO,
I am having issues gaining access to javascript functions in manifest files when rendering a JS partial. Below are the files which make the current articles#index page work:
Manifested files:
assets/javascripts/option_set_interface.js.coffee.erb
on_load = ->
load_article_click_handlers $('ul.index li.article')
$(document).ready on_load //standard DOM refresh
document.addEventListener 'page:change', on_load //turbolinks
load_article_click_handlers = (jQuery_object) ->
.. Do some stuff...
load_article_click_handlers is the function I would like to gain access to in create.js.erb
assets/javascript/articles.js.coffee
//= require option_set_interface
articles_controller.rb:
class ArticlesController < ApplicationController
def create
#article = Article.new(article_params)
#article.save
respond_to do |format|
format.html { redirect_to articles_path }
format.js { render 'create' }
end
end
def index
#articles = Article.all
end
protected
def article_params
params.require(:article).permit(:title)
end
end
Views and partials: views/articles/
index.html.haml
- provide(:title, 'Article list')
%h1 Article list
.row
.aside.span3
.row
%ul.index
- #articles.each do |article|
= render article
= render 'new'
_article.html.haml
%li.article
%input{ type: 'hidden', value: article.id, name: 'article_id' }
= article.id
= article.title
_new.html.haml
= form_for Article.new, remote: true, html: { id: 'new_article_form' } do |f|
= f.label :title
= f.text_field :title
= f.submit 'Create', class: 'btn btn-large btn-primary'
create.js.erb (where the issue is)
new_list_item = $('<%= escape_javascript( render #article ) %>')
new_list_item.prependTo('ul.index').slideDown()
load_article_click_handlers(new_list_item) //this is the line that breaks the code
The code works well, until I try to call load_article_click_handlers in create.js.erb. I am not sure how to get debug information on it because it uses rails' magic ajax. I'm not very sure how to capture the response.
create.js has access to jquery, clearly. But it does not seem to accept my custom functions. Any help or advice is appreciated, particularly tips on how to debug rail's ajax rendered JS. Currently attemtping to access load_article_click_handlers causes teh script not to run at all.
Things I have tried:
Adding '//= require option_set_interface' to application.js
using javascript_inlude_tag 'option_set_interface' in create.js.erb
EDIT
Found 1 correction, did not eliminate problem.
Solved.
I was going down the wrong path. Issue was with coffeescript's anonymous function wrapper. The feature was built to avoid "polluting the global namespace", which was exactly what I wanted to do with an include file.
Solution is to add
window.load_article_click_handlers = load_article_click_handlers
after the definition of load_article_click_handlers.
Hope this helps someone else.

Rails Ajax search not doing anything -- 404 error

Trying to figure out Ajax search in a Rails 3 app, following this post, which itself borrows from a Railscast. Currently, when I submit, nothing happens, and if I go into the Chrome console, I see this error:
GET http://localhost:3000/search?utf8=%E2%9C%93&search=&_=1361491523102 404 (Not Found)
posts.js line 5 seems to be culpable, but that just seems to be the jQuery call, so I'm not sure what I'm doing wrong.
My relevant code:
posts.js.coffee
jQuery ->
# Ajax search on submit
$('.search_form').submit( ->
$.get(this.action, $(this).serialize(), null, 'script')
false
)
posts_controller.rb
def show
#search = Post.search(params[:search])
respond_to do |format|
format.html # show.html.erb
format.json { redirect_to #post }
end
end
def search
#search = Post.search(params[:search])
render json: { results: #search }
end
post.rb
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
show.html.erb
<%= form_tag search_path, method: "get", class: "search_form form-inline",
style: "display:inline-block;" do %>
<%= text_field_tag :search, params[:search], placeholder: "Search:", id: "search_field" %>
<%= submit_tag("Search", name: nil, class: "btn search", remote: true) %>
<% end %>
# Testing for #search stops it from pulling a "no method '.first' for nil NilClass" error.
<div id="list"><%= render partial: 'list', locals: { search: #search } if #search%></div>
list.html.erb
<ul>
<% #search.each do |p| %>
<li>(<%= p.created_at.strftime("%b %d, %Y") %>)</span></li>
<% end %>
</ul>
Any idea what's going wrong here?
EDIT -- Adding relevant lines of routes file:
resources :posts
# ...
match '/search', to: 'posts#search'
I already had that '/search' route there. Is that right -- in which case, is the problem somewhere else? Does the rest of the code look goodish?
EDIT -- added search method to PostsController, per Damien's rec. New things of interest are a) the way I call the partial, the new search action, and that fact that then I tried to replace the contents of the show method in Post.rb with "Post.all", it still didn't show anything. No errors thrown, though.
"No search action! Didn't realize I needed one. What should be in it?
When I tried an earlier version of this without AJAX, I had a search
action that was basically a replica of show (+ #search etc), with all
the same variables, otherwise it wouldn't work, because it rendered
the show page. Is that the right idea? It seemed very unDRY"
Using AJAX, there is no need to render the entire show page. Just return the filtered results in desired format:
def search
#search = Post.search(params[:search])
render json: { results: #search }
end
Add format based returns if necessary.

Categories

Resources