I'm attempting to add some ajax to my pagination using the will_paginate gem as specified in Pagination With Ajax and I got it up to the point where I can see the correct HTML response in Firebug but it doesn't actually render the new code oddly enough.
Here's my simplified code:
index action
def index
#videos = Video.paginate :page => params[:page], :per_page => per_page
end
index.html.haml
#box_content{:style => "padding: 1em;text-align:center;"}
= render "video
_video.html.haml
- #videos.each do |video|
%iframe{:width=>"200", :height=>"150", :src=>link_src(video.link), :frameborder=>"0", :allowfullscreen =>"true"}
%div.pageinfo
= will_paginate #videos
Application.js
$(function () {
$('.pagination a').live("click", function () {
$.get(this.href, null, null, 'script');
return false;
});
});
index.js.erb
$('#box_content').html("<%= escape_javascript(render("video")) %>");
Nothing happens at all when I click on the will_paginate links, if I look at the network GET response I see the following which does indicate a new page:
$('#box_content').html("<iframe allowfullscreen=\'true\' frameborder=\'0\' height=\'150\' src=\'http://www.youtube.com/embed/z52V60aZ7ro\' width=\'200\'><\/iframe>\n<div class=\'pageinfo\'>\n <div class=\"pagination\"><a class=\"previous_page\" rel=\"prev start\" href=\"/?_=1339623038312&page=1\">← Previous<\/a> <a rel=\"prev start\" href=\"/?_=1339623038312&page=1\">1<\/a> <em class=\"current\">2<\/em> <a rel=\"next\" href=\"/?_=1339623038312&page=3\">3<\/a> <a href=\"/?_=1339623038312&page=4\">4<\/a> <a class=\"next_page\" rel=\"next\" href=\"/?_=1339623038312&page=3\">Next →<\/a><\/div>\n<\/div>\n");
It turns out I was actually getting a Javascript error. I didn't see it in my Firebug console because the Javascript was being rendered as html and not javascript. Executing the response javascript in the firebug console manually let me see the error however.
Related
I'm struggling to get some ajax pagination with cakephp working. I've read the instructions here and various other pages on the internet eg: SO link
However I get an error in the console:
Uncaught type error undefined is not a function
Which occurs on the $(document).ready() function generated by $this->Js->writeBuffer().
Any ideas on what I'm doing wrong?
In my view index.ctp I set the paginator's options:
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true)
);
Then carry on with the remainder of the view, in particular I render the table. The controller has fetched data to be displayed.
I output my pagination controls:
echo $this->Paginator->prev();
echo $this->Paginator->numbers();
echo $this->Paginator->next();
At the end of my view I do:
echo $this->Js->writeBuffer();
I have added the relevant helpers and components to my controller:
public $helpers = array('Js' => array('jquery'));
public $components = array(
'Paginator',
'RequestHandler'
);
In default.ctp I have included jquery by adding this to the end of the HTML (just before </body>:
<script src="https://code.jquery.com/jquery.js"></script>
It looks it works in that it generated the relevant javascript and provides the id's for the links but clicking the links just works like normal.
Functions need to exist before they are called
In default.ctp I have included jquery by adding this to the end of the HTML (just before </body>
Jquery needs to be loaded before it is used. Ensure that script tags appear in the rendered html in this order:
<script src="//code.jquery.com/jquery.js"></script>
... anything or nothing ...
<script>
$(document).ready(
...
This may come off as a bit newb-ish, but I don't really know how to approach this.
Can anyone recommend me a way of delivering and image from a flask backend, after being called by an angular $http.get call?
Brief example of what I am trying to do.
//javascript code
myApp.controller('MyCtrl', function($scope, $http){
$http.get('/get_image/').success(function(data){
$scope.image = data;
});
});
#flask back end
#app.route('/get_image/', methods= ['GET', 'POST'])
def serve_image():
image_binary = get_image_binary() #returns a .png in raw bytes
return image_binary
<!-- html -->
<html ng-app= "myApp">
<div ng-controller= "MyCtrl">
{{ image }}
</div>
</html>
So as you can see, I am attempting to serve a raw-byte .png image from the flask backend, to the frontend.
I've tried something like this
<html>
<img src= "/get_image/">
</html>
But the trouble is, 'get_image_binary' takes a while to run, and the page loads before the image is ready to be served. I want the image to load asyncronously to the page, only when it is ready.
Again, I am sure there are many ways to do this, probably something built into angular itself, but it is sort of difficult to phrase this into a google-able search.
Can't speak to the flask stuff, but below is some AngularJS code.
This directive won't replace the source attribute until after Angular manipulates the DOM and the browser renders (AngularJS : $evalAsync vs $timeout).
HTML:
<div ng-controller="MyController">
<img lazy-load ll-src="http://i.imgur.com/WwPPm0p.jpg" />
</div>
JS:
angular.module('myApp', [])
.controller('MyController', function($scope) {})
.directive('lazyLoad', function($timeout) {
return {
restrict:'A',
scope: {},
link: function(scope, elem, attrs) {
$timeout(function(){ elem.attr('src', attrs.llSrc) });
},
}
});
Same code in a working JSFiddle
I'm having some problems to update my div after submitting a form with Rails 4. Here is the relevant part of my code:
View:
_details.html.haml
= form_tag(url_for(save_answer_path(format: :js)), remote: true) do
(some html code ....)
= submit_tag t('app.bouton.send'), id: 'sendButton'
%div#divlogs
= render partial: 'logs'
Controller:
def save_answer
some code ...
respond_to do |format|
format.js
end
end
JS:
save_answer.js.erb
$('#divlogs').html("<%= escape_javascript(render partial: 'logs') %>");
When I submit, everything is called correctly but I'am getting an incorrect output. What I want is to update my div, but instead I get a page with what I have on my JS file, but with the content of my partial.
Example:
My URL after submitting:
http://domaine/controller/save_answer.js
What I get on the screen:
$('#divlogs').html("<p>This should appear on the div </p>");
Does anyone know what is going on?
Solution:
As #VladKhomich said in the comments above, I was missing the JS file rails.js.
You can download it from here: https://github.com/rails/jquery-ujs/blob/master/src/rails.js
Below you will see my jquery:
$(function() {
$(".pagination span.page a").click(function (){
$.get(this.href, null, alert("The pagination link was clicked" + this.href), "script");
return false;
});
});
I know my call on my classes are working because the alert pops up. I think that it is where I am calling "script" where it is failing because it is not pulling up the page. This is a Rails 3 application that is calling an index.js.erb script. Here is the index.js.erb:
$("#search").html("<%= escape_javascript(render("search")) %>");
Any ideas?
Are you trying to render a partial?
$("#search").html("<%= escape_javascript(render :partial => "search") %>");
When looking on how rails calls ajax I came across a post. It said to do the following:
def index
format.js
end
Once I called this it started working.
I'm trying to add some Ajax functionality in my Rails 3 app.
Specifically, I want a button that will submit an Ajax request to call a remote function in my controller, which subsequently queries an API and returns a JSON object to the page.
Once I receive the JSON object I want to display the contents.
All of this with the new Rails 3 UJS approach, too. Is there a good example/tutorial for this online somewhere? I haven't been able to find one on google. A simple example using a button as the entry point (ie, the user clicks the button to start this process) would work, too.
Edit
Let me try this with a different approach. I want to have this button query an external API, which returns JSON, and display that JSON on the page. I have no idea where to even begin. Does the button itself query the external API? Do I need to go through the controller, and have the controller query the external API, get the JSON, and give the JSON back to this page? How do I display/access the contents of this JSON? I honestly can't find a good Rails 3.x example of how to handle JSON...
Here is a start:
First create your button with a link_to method in your view, for example:
=link_to "delete", "#{invitation_path(invitation)}.json", :method=>:delete, :remote=>true, :class=>"remove", :confirm=>'Are you sure you?'
Note that I am appending ".json" to the url of my resource. This is just an example of a an AJAX delete, google link_to to see the meaning of the parameters. The concept if that you make your HTTP request with the parameter :remote set to true, in other words this is translated to an AJAX call from your browser.
Second, write some javascript so that you can process what ever is the result of the AJAX call your browser will make when the user click on the link_to of step 1. For details you can see this blog post: http://www.alfajango.com/blog/rails-3-remote-links-and-forms/
An example from my site:
jQuery(function($) {
// create a convenient toggleLoading function
var toggleLoading = function() { $("#loading").toggle() };
$("#pending_invitation")
.live("ajax:loading", toggleLoading)
.live("ajax:complete", toggleLoading)
.live("ajax:success", function(event, data, status, xhr) {
var response = JSON.parse(xhr.responseText)
if (response.result == "ok") {
$(this).fadeOut('fast');
}
else {
var errors = $('<div id="error_explanation"/>');
errors.append('<h2>Pending invitation action error</h2><ul><li>' + response.error + '</li></ul>');
$('#new_invitation_error').append(errors)
}
});
});
where you can see that I parse the returned json and and change the html on the page based on that. Note that this js uses the CCS ids and classes defined in the top view that is not included here.
If you now want to write you own controller to spit out the json here is an example:
class InvitationsController < ApplicationController
respond_to :html, :json
# other methods here
# ...
def destroy
#invitation = Invitation.find(params[:id])
respond_to do |format|
if #invitation
#invitation.destroy
flash[:success] = I18n.t 'invitations.destroy.success'
format.json { render :json =>{:result => "ok", :message=>"Invitation #{params[:id]} was destroyed", :resource_id=>params[:id] } }
else
format.json { render :json => { :result=>"failed", :error=>"Cannot find Invitation #{params[:id]}", :resource_id=>params[:id] } }
end
end
end
end
Hope this help.
Old question, but a really good overview of Ajaxifying Rails applications is:
Ajax in Rails 3.1 - A Roadmap
Also consider returning errors in the following format:
render :json => #myobject.to_json, :status => :unprocessable_entity
This will ensure that your client can process the response as an error.