Load image ansyncronously with angular http.get call - image

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

Related

Dynamically inserting content within same page rather then going to a new page

EDIT italics = more detailed explanation added to the question. Thanks.
I'm building a jQuery Mobile site which has a Gallery section.
The gallery has a series of thumbnails on the top of the screen.
Users click on the thumbnail to load in new content, that being a larger image, text, and potentially audio on some of them.
It's at this point that I'm not sure what to do: the way jQuery Mobile works, it's geared towards loading new pages, or views. But I just want to inject new content in a container on the current page.
To be clear, when the user clicks on another thumbnail, a new image replaces the content of the container with new content.
I have two questions:
I'm not sure how to structure the dynamic content. I was thinking i'd create an html file for each item, which as a rule always contains a title, information and sometimes, audio.
I'm not sure how to script this functionality in jQuery Mobile. It's obviously Ajax, but I'm not familiar with it yet, especially since jQuery Mobile has it's own methods in place already which seems to redefine behaviors in a way that's contradictory to this approach described here.
Here is a code explanation of what i'm trying to do:
<!-- Galleries -->
<div data-role="page" id="galleries">
<div data-role="content" role="main">
This is the Selection UI, if i click on thumb2.jpg, it'd
fill #content-holder with the whatever html is in content2.php
<div id="thumb-carousel">
<img src="thumb1.jpg">
<img src="thumb2.jpg">
<img src="thumb3.jpg">
<img src="thumb4.jpg">
<img src="thumb5.jpg">
<img src="thumb6.jpg">
<img src="thumb7.jpg">
<img src="thumb8.jpg">
<img src="thumb9.jpg">
</div>
<!-- This is the container, currently it's filled
with the kinda stuff i need to put in it. -->
<div id="content-holder">
<img src="myimage1.jpg"/>
<p>Artwork Title</p>
<p>Caption</p>
<audio>//mp3</audio>
</div>
</div>
</div>
//remember to use event delegation because you never know when the page will be in the DOM
$(document).delegate('#galleries', 'pageinit', function () {
//bind a `click` event handler to each thumbnail link
$('#thumb-carousel').children().bind('click', function () {
$.ajax({
url : $(this).attr('href'),
success : function (serverResponse) {
//select the container,
//then fade it out,
//change it's HTML to the response from the AJAX request,
//and fade it back in
$('#content-holder').fadeOut(500, function () {
$(this).html(serverResponse).fadeIn(500);
});
},
error : function (jqXHR, textStatus, errorThrown) {
//remember to handle errors so your page doesn't seem broken to the user
}
});
//prevent the default behavior of the link, which is to navigate to the `href` attribute
return false;
});
});
This expects your server-response to be valid HTML markup that is ready to inject into the DOM, meaning no <html> or <body> tags, just what you want to add to the DOM:
<img src="..." />
<span>TITLE</span>
<audio src="..."></audio>
Here are some docs for ya:
$.ajax(): http://api.jquery.com/jquery.ajax
.closest(): http://api.jquery.com/closest
.fadeIn(): http://api.jquery.com/fadein

How to create a waiting page in Django

I am constructing an application that need a lengthy calculation. After a user submitted the information, it need about 30 minutes to calculate and then return the result. So I am considering to add a “please wait" page.
I followed instructions mentioned in the following link,
http://groups.google.com/group/django-users/browse_thread/thread/c1b0d916bbf86868
However, when I submit something, it stays in http://127.0.0.1:8000/please_wait
and will not redirect to the result page like http://127.0.0.1:8000/display_DHM
does anybody know what is going on?
Here are all related files, I tried various ways, but when I
submit a form, it only return the please_wait page and then stay there
forever. There is no redirect happened.
Since I want to check if it works first, there is no actual
calculation in the code.
url.py
urlpatterns = patterns('',
(r'^test$',views.test_form),
(r'^please_wait', views.please_wait),
url(r'^run_DHM$', views.run_DHM, name="run_DHM") ,
url(r'^displayDHM', views.display_DHM, name="displayDHM")
)
view.py
def test_form(request):
return render_to_response('test.html')
def please_wait(request):
return render_to_response('please_wait.html')
def run_DHM(request):
### lengthy calculations... ...
return HttpResponse("OK")
def display_DHM(request):
return render_to_response('display_DHM.html')
test.html
{% extends "baseFrame.html" %}
{% block maincontent %}
<form method="POST" action="please_wait">
<p>Test:</p>
<div id="address"></div>
<p>Type your value in here:</p>
<p><textarea name="order" rows="6" cols="50" id="order"></
textarea></p>
<p><input type="submit" value="submit" id="submit" /></p>
</form>
{% endblock %}
please_wait.html
<html>Please wait
<script type="text/javascript" src="http://code.jquery.com/
jquery-1.7.1.min.js">
$.getJSON('{% url run_DHM %}', function(data) {
if (data == 'OK') {
window.location.href = '{% url displayDHM %}';
} else {
alert(data);
}
});
</script>
</html>
display_DHM.html
<HTML>
<BODY>END FINALLY!</BODY>
</HTML>
I write here because I can't use the comment space. My question is a bit similar to yours and maybe the answer can help you.
Briefly:
the question:
I have an external python program, named c.py, which "counts" up to 20 seconds. I call it from my Django app views.py and in the html page I have a button to start it. It's ok (= in Eclipse I can see that c.py prints 0,1,2,3,...20 when I press the button on the webpage) but I would like that the button changes from "GO" to "WAIT" during c.py process (or I would like to perform a waiting page during the counting or also a pop-up).
the answer:
You would need to be able to report back the status of c to the client
via ajax long polling or WebSockets, or, if you don't care about the
incremental status of c and just want to change the text of the link,
you'll need to use JavaScript to set the value when the click event of
the link fires:
views.py
from django.core.urlresolvers import reverse
from django.http import JsonResponse
def conta(request):
c.prova(0)
redirect = reverse('name_of_home_user_view')
return JsonResponse({'redirect': redirect})
and js:
// assuming jQuery for brevity...
$(document).ready(function() {
// avoid hard-coding urls...
var yourApp = {
contaUrl: "{% url 'conta' %}"
};
$('#btnGo').click(function(e) {
e.preventDefault(); // prevent the link from navigating
// set css classes and text of button
$(this)
.removeClass('btn-primary')
.addClass('btn-danger')
.text('WAIT');
$.get(yourApp.contaUrl, function(json) {
window.top = json.redirect;
});
});
});
If you need lengthy calculations I think you could be interested in celery. Nice waiting pages (progress indicators?) would be a byproduct.

Reloading everything but one div on a web page

I'm trying to set up a basic web page, and it has a small music player on it (niftyPlayer). The people I'm doing this for want the player in the footer, and to continue playing through a song when the user navigates to a different part of the site.
Is there anyway I can do this without using frames? There are some tutorials around on changing part of a page using ajax and innerHTML, but I'm having trouble wrapping my head aroung getting everything BUT the music player to reload.
Thank you in advance,
--Adam
Wrap the content in a div, and wrap the player in a separate div. Load the content into the content div.
You'd have something like this:
<div id='content'>
</div>
<div id='player'>
</div>
If you're using a framework, this is easy: $('#content').html(newContent).
EDIT:
This syntax works with jQuery and ender.js. I prefer ender, but to each his own. I think MooTools is similar, but it's been a while since I used it.
Code for the ajax:
$.ajax({
'method': 'get',
'url': '/newContentUrl',
'success': function (data) {
// do something with the data here
}
});
You might need to declare what type of data you're expecting. I usually send json and then create the DOM elements in the browser.
EDIT:
You didn't mention your webserver/server-side scripting language, so I can't give any code examples for the server-side stuff. It's pretty simple most of time. You just need to decide on a format (again, I highly recommend JSON, as it's native to JS).
I suppose what you could do is have to div's.. one for your footer with the player in it and one with everything else; lets call it the 'container', both of course within your body. Then upon navigating in the site, just have the click reload the page's content within the container with a ajax call:
$('a').click(function(){
var page = $(this).attr('page');
// Using the href attribute will make the page reload, so just make a custom one named 'page'
$('#container').load(page);
});
HTML
<a page="page.php">Test</a>
The problem you then face though, is that you wouldnt really be reloading a page, so the URL also doesnt get update; but you can also fix this with some javascript, and use hashtags to load specific content in the container.
Use jQuery like this:
<script>
$("#generate").click(function(){
$("#content").load("script.php");
});
</script>
<div id="content">Content</div>
<input type="submit" id="generate" value="Generate!">
<div id="player">...player code...</div>
What you're looking for is called the 'single page interface' pattern. It's pretty common among sites like Facebook, where things like chat are required to be persistent across various pages. To be honest, it's kind of hard to program something like this yourself - so I would recommend standing on top of an existing framework that does some of the leg work for you. I've had success using backbone.js with this pattern:
http://andyet.net/blog/2010/oct/29/building-a-single-page-app-with-backbonejs-undersc/
You can reload desired DIVs via jQuery.ajax() and JSON:
For example:
index.php
<script type="text/javascript" src="jquery-1.4.2.js"></script>
<script type="text/javascript" src="ajax.js"></script>
<a href='one.php' class='ajax'>Page 1</a>
<a href='two.php' class='ajax'>Page 2</a>
<div id='player'>Player Code</div>
<div id='workspace'>workspace</div>
one.php
<?php
$arr = array ( "workspace" => "This is Page 1" );
echo json_encode($arr);
?>
two.php
<?php
$arr = array( 'workspace' => "This is Page 2" );
echo json_encode($arr);
?>
ajax.js
jQuery(document).ready(function(){
jQuery('.ajax').click(function(event) {
event.preventDefault();
// load the href attribute of the link that was clicked
jQuery.getJSON(this.href, function(snippets) {
for(var id in snippets) {
// updated to deal with any type of HTML
jQuery('#' + id).html(snippets[id]);
}
});
});
});

Running a function in a jQuery implicit context

My html document looks like this:
<html>
<head> .. load jquery and other stuff </head>
<body>
<div id="cool_container">
<div class="cool">.. no script friendly markup ..</div>
</div>
<a id="cool_link">Link</a>
<script>
function installStuff(){
$('.cool').coolPlugin();
$('#cool_link').click(function(){
$('#cool_container').load('/anothercooldiv.html');
});
}
$(document).load(function(){ installStuff(); });
</script>
</body>
</html>
Of course, /anothercooldiv.html gives another <div class="cool"> .. etc ...</div> fragment.
So what's the best way to turn the fresh cool div into a coolPlugin without breaking everything (and writing some nasty hacks) ?
It'd would be great to be able to either:
Call installStuff with a default jQuery context '#cool_container', so I could call something like:
$.doThisInContext(function(){installStuff();}, $('#cool_container');
In the load callback.
Or, have an equivalent of 'live' (that would solve the problem of links if cool contains links), but on an element existence, that I could use like that in my function installStuff:
$('.cool').exists(function(what){ what.coolPlugin() };
Then the coolPlugin would be installed on all cool elements now and in the future.
I'd suggest the .livequery() plugin for this still:
$(function() {
$('.cool').livequery(function() {
$(this).coolPlugin();
});
$('#cool_link').click(function(){
$('#cool_container').load('/anothercooldiv.html');
});
});
The important bit:
$('.cool').livequery(function() {
$(this).coolPlugin();
});
Will run for every current and future .cool element as they're added, running the plugin on each.
Applying the plugin to the newly ajax loaded content shouldn't be too tricky:
$('#cool_container').load('/anothercooldiv.html', function() {
$(this).coolPlugin();
});

Partial page refresh for evary X seconds with Jquery and Ajax?

1) I have to change images dynamically according to values for every x seconds.
I'm using the following function:
setInterval(function() {
$("#content").load(location.href+" #content>*","");
}, 5000);
It works fine for updating the value, but the images not getting updated into its position.
2) From the 1st question i want to know whether the jquery and css files included in the head tag will load every x seconds or not. if not how to load?
Please give me the suggestion.
If you are returning a whole HTML page and returning it into the body of another page, that is a bad idea.
Think about it, your html structure would be something like
<doc type>
<html>
<head>
</head>
<body>
<div>
<doc type>
<html>
<head>
</head>
<body>
<div>
</div>
</body>
</html>
</div>
</body>
</html>
Ideally you should be retuning just the content that is to be displayed, not everything.
If you are just updating images, there usually is no need to make an XHR call. You can just set the image src and force the browser to update that content that way.
Does this need to be done with Ajax at all? How many images are you going to cycle through? If it is only a few, just keep all of the src's on the page and switch the image src attribute periodically. This requires no page reload. You may also want to preload all the images so there is no flicker when changing to the other image. For example:
$(function () {
var images = ['1.png', '2.png', '3.png'];
$.each(images, function (index, src) {
$("<img />").attr('src', src); //preload
});
var keep = 1;
setInterval(function () {
$("#main_img").attr('src', images[keep]);
keep++;
if (keep >= images.length) { keep = 0; }
}, 5000);
});
Now if you don't want to hard code the image urls in the JS, you can load them initially with a single Ajax request.
I would only recommend using Ajax to do all the work if you are talking about an unpredictable set of images or some massive number of images.

Resources