Handling jsonp in rails 3 controller - javascript

I want my controller action to handle jsonp requests from jquery $.getJSON. In my controller action i have the following respond_to block:
respond_to do |format|
format.html { render json: {:items_by_tag => #tagged_item_list}}
if params[:callback]
format.js { render :json => {:items_by_tag => #tagged_item_list}.to_json, :callback => params[:callback] }
else
format.json { render json: {:items_by_tag => #tagged_item_list}}
end
end
But I'm getting SyntaxError:invalid label when i call the url from $.getJSON. My url is of the form http://myservice.com?param1=a&param2=b&callback=?.
What is the problem with my code which is causing jsonp to fail?

respond_to do |format|
format.html { render json: {:items_by_tag => #tagged_item_list}}
if params[:callback]
format.js { render :json => {:items_by_tag => #tagged_item_list.to_json}, :callback => params[:callback] }
else
format.json { render json: {:items_by_tag => #tagged_item_list}}
end
end

Related

Respond to format.html with Javascript action

I'd like to execute some javascript on the respond_to action for format.html.
window.top.location.href='#{ #recurring_charge.confirmation_url }'
I need to execute javascript to open the window out of the iframe, otherwise I cannot render the page due to the following error message 'X-Frame-Options'to 'deny'.
How can I do this?
def confirm_billing
current_shop.with_shopify!
#recurring_charge = RecurringCharge.new(recurring_charge_params)
if #recurring_charge.save
respond_to do |format|
format.html { render :js => "window.top.location.href='#{ #recurring_charge.confirmation_url }'" }
format.json { render json: { success: true, redirect_url: #recurring_charge.confirmation_url }, status: 201 }
end
else
respond_to do |format|
format.html { redirect_to root_url, notice: 'Something went wrong' }
format.json { render json: { success: false, errors: #recurring_charge.errors.full_messages }, status: 201 }
end
end
end
I was able to get it to work using render :text, can't believe it actually worked!
format.html { render :text => "<script>window.top.location.href='#{ #recurring_charge.confirmation_url }';</script>" }

endless scrolling does not work

Update: My Github Repository https://github.com/Marc585/smartforce2
i just finished the onemonthrails tutorial. at the last chapter its about endless scrolling. i tripple checked my code but it just doesn't work. I don't get an error or anything. It just doesn't do anything. I'm building a pinterest clone and after i scroll to the bottom it should load the next page of pins.
This is my pins.js.coffee
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
jQuery ->
$('#pins').imagesLoaded ->
$('#pins').masonry itemSelector: ".box"
if $('.pagination').length
$(window).scroll ->
url = $('.pagination .next_page a').attr('href')
if url && $(window).scrollTop() > $(document).height() - $(window).height() - 50
# What to do at the bottom of the page
$('.pagination').text("Fetching more pins...")
$.getScript(url)
$(window).scroll()
This is my index.js.erb
$boxes = $('<%= j render(#pins) %>')
$('#pins').append( $boxes ).imagesLoaded( function(){
$('#pins').masonry( 'reload');
});
<% if #pins.next_page %>
$('.pagination').replaceWith('<%= j will_paginate(#pins) %>');
<% else %>
$('.pagination').remove();
<% end %>
This is my pins controller:
class PinsController < ApplicationController
before_filter :authenticate_user!, except: [:index]
# GET /pins
# GET /pins.json
def index
#pins = Pin.order("created_at desc").page(params[:page]).per_page(20)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #pins }
format.js
end
end
# GET /pins/1
# GET /pins/1.json
def show
#pin = Pin.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #pin }
end
end
# GET /pins/new
# GET /pins/new.json
def new
#pin = current_user.pins.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #pin }
end
end
# GET /pins/1/edit
def edit
#pin = current_user.pins.find(params[:id])
end
# POST /pins
# POST /pins.json
def create
#pin = current_user.pins.new(params[:pin])
respond_to do |format|
if #pin.save
format.html { redirect_to #pin, notice: 'Pin was successfully created.' }
format.json { render json: #pin, status: :created, location: #pin }
else
format.html { render action: "new" }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# PUT /pins/1
# PUT /pins/1.json
def update
#pin = current_user.pins.find(params[:id])
respond_to do |format|
if #pin.update_attributes(params[:pin])
format.html { redirect_to #pin, notice: 'Pin was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# DELETE /pins/1
# DELETE /pins/1.json
def destroy
#pin = current_user.pins.find(params[:id])
#pin.destroy
respond_to do |format|
format.html { redirect_to pins_url }
format.json { head :no_content }
end
end
end
Error Message from my developer tools
https://www.dropbox.com/s/odqknmw7np1f4cv/Bildschirmfoto%202013-08-31%20um%2014.34.40.png
You are missing
format.js in your show action in the pins_controller.rb. This is from the onemonth rails notes
Note: You'll have to create an analogous show.js.erb and add the format.js option to your users#show action to get endless scroll to work on users' profile pages as well
def show
#pin = Pin.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #pin }
format.js
end
end
Your show.js.erb should look like this
boxes = $('<%= j render(#pins) %>')
$('#pins').append( $boxes ).imagesLoaded( function(){
$('#pins').masonry( 'reload');
});
<% if #pins.next_page %>
$('.pagination').replaceWith('<%= j will_paginate(#pins) %>');
<% else %>
$('.pagination').remove();
<% end %>

Firefox not waiting for user interaction with data-confirm alert on delete method in rails

When a user presses the delete button an alert pops up with 'Are you sure [ok][cancel]?'. Instead of waiting for user input the delete method is run and the page redirects to the next step. I have included a jquery submit function that is saving the current state of another form on the page before moving to the delete action. I can't seem to find any info on html5 data-confirm attribute compatibility issues in firefox 10. The functionality is perfect in chrome and ie. Any ideas on how to fix this? Seems like I am missing something simple here.
View
<td style="padding:2px;padding-left:6px;"><%= link_to 'Delete',
store_store_hour_path(#store,store_hour), :class=>"button small white saveForm",
:confirm => 'Are you sure?', :method => :delete %></td>
Controller
<pre><code>
SAVE = "Save"
CANCEL = "Cancel"
class StoreHoursController < SecuredController
before_filter :grab_store_from_store_id
# GET /store_hours/new
# GET /store_hours/new.xml
def new
#store_hour = #store.store_hours.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #store_hour }
end
end
# POST /store_hours
# POST /store_hours.xml
def create
#store_hour = #store.store_hours.new(params[:store_hour])
#store = #store_hour.store
if params[:commit] == CANCEL
redirect_to edit_store_path(#store)
return
end
respond_to do |format|
if #store_hour.save
format.html { redirect_to edit_store_path(#store), :flash => { :success => 'Store hours created successfully' } }
format.xml { render :xml => #store_hour, :status => :created, :location => #store_hour }
else
format.html { render :action => "new", :flash => { :success => 'Store hours created successfully' } }
format.xml { render :xml => #store_hour.errors, :status => :unprocessable_entity }
end
end
end
# GET /store_hours/1/edit
def edit
#store_hour = #store.store_hours.find(params[:id])
end
# PUT /store_hours/1
# PUT /store_hours/1.xml
def update
#store_hour = #store.store_hours.find(params[:id])
#store = #store_hour.store
if params[:commit] == CANCEL
redirect_to edit_store_path(#store)
return
end
respond_to do |format|
if #store_hour.update_attributes(params[:store_hour])
format.html { redirect_to edit_store_path(#store), :flash => { :success => 'Store hours updated successfully' } }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #store_hour.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /store_hours/1
# DELETE /store_hours/1.xml
def destroy
#store_hour = #store.store_hours.find(params[:id])
#store = #store_hour.store
#store_hour.destroy
logger.info "in destroy: " + edit_store_path(#store)
respond_to do |format|
format.html { redirect_to edit_store_path(#store), :flash => { :success => 'Store hours deleted successfully' } }
format.xml { head :ok }
end
end
private
def grab_store_from_store_id
#store=Store.find(params[:store_id])
end
end
Jquery submit
function saveStoreInfo() {
$('.saveForm').click(function(){ $('#storeForm').submit(); return true});
}

Rails 3 - JSON of nested models not returning as expected

I'm trying to set up a javascript front in that is consuming JSON from a Rails backend.
The only problem is, when I have nested models in Rails, I'm not sure if the JSON being returned is in the correct format.
I have a Post model and a Comment model. A Post has many Comments. Each model has a 'title' and 'content' field.
Here's where my problem is so far...
1) When I visit the url: http://localhost:3000/posts.json I get the expected output:
> [{"content":"My first
> post","created_at":"2012-02-07T18:56:16Z","id":1,"title":"Hello","updated_at":"2012-02-07T18:56:16Z"},{"content":"More
> crap","created_at":"2012-02-07T21:30:51Z","id":2,"title":"My 2nd
> Post","updated_at":"2012-02-07T21:30:51Z"}]
2) If I put in this url: http://localhost:3000/posts/1/comments/4.json I also get the expected:
> {"content":"that's
> nice","created_at":"2012-02-07T20:57:16Z","id":4,"post_id":1,"title":"cool","updated_at":"2012-02-07T20:57:16Z"}
3) But... if I put in a url like this: http://localhost:3000/posts/1/comments.json
it returns null.
I don't have access to the JSON version of the list of Comments associated with the Post.
Using the standard Rails views, I can do full CRUD with the nesting no problem, but do I need to do something different from the way Rails normally passes the JSON back in order to consume it on the client side?
EDIT
I'm assuming you may need to see the controller code for the comments controller. Here it is:
class CommentsController < ApplicationController
before_filter :get_post
respond_to :html, :xml, :json
def index
#comments = #post.comments.all
respond_with (#comment)
end
def show
#comment = #post.comments.find(params[:id])
respond_with(#comment)
end
def new
#comment = #post.comments.build
respond_with(#comment)
end
def edit
#comment = #post.comments.find(params[:id])
end
def create
#comment = #post.comments.build(params[:comment])
respond_to do |format|
if #comment.save
format.html { redirect_to([#post, #comment], :notice => 'Comment was successfully created.') }
format.xml { render :xml => #comment, :status => :created, :location => #comment }
format.json { render :json => #comment, :status => :created, :location => #comment }
else
format.html { render :action => "new" }
format.xml { render :xml => #comment.errors, :status => :unprocessable_entity }
format.json { render :json => #comment.errors, :status => :unprocessable_entity }
end
end
end
def update
#comment = #post.comments.find(params[:id])
respond_to do |format|
if #comment.update_attributes(params[:comment])
format.html { redirect_to(#comment, :notice => 'Comment was successfully updated.') }
format.xml { head :ok }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #comment.errors, :status => :unprocessable_entity }
format.json { render :json => #comment.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#comment = #post.comments.find(params[:id])
#comment.destroy
respond_to do |format|
format.html { redirect_to(post_comments_url) }
format.xml { head :ok }
format.json { head :ok }
end
end
protected
def get_post
#post = Post.find_by_id(params[:post_id])
redirect_to root_path unless #post
end
end
def index
#comments = #post.comments.all
respond_with (#comment)
end
You didn't assign to #comment.

respond_to not working with format.js if format.html is present

When using respond_to, my AJAX call only invokes the javascript response if the HTML response isn't present.
I have the following javascript for submitting an edit-in-place action:
$(".eip").editable("/surveys", {
name : 'survey[name]',
select : true,
event : 'edit',
submit : 'Save',
cancel : 'cancel',
cssclass : "editable",
onblur : 'ignore',
onedit : function() { $(".eip_desc").hide(); },
onreset : function() { $(".eip_desc").show(); },
onsubmit : function() { $(".eip_desc").show(); }
});
Then I have the following Survey controller method:
class SurveysController < ApplicationController
def create
#survey = Survey.new(params[:survey])
if #survey.save
respond_to do |format|
format.html { redirect_to surveys_path, :notice => "Survey created!" }
format.js
end
else
render :action => :new
end
end
end
If I remove the format.html line, then format.js responds as it should. But if I leave format.html in there, then the whole page renders when I submit via that editable javascript bit.
I'm running Rails 3.0.3 for this app.
from docs
(String) method: Method to use when
submitting edited content. Default is
POST. You most likely want to use POST
or PUT. PUT method is compatible with
Rails.
try to pass a method: "put"

Categories