Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
RequireJS, Marionette.js and Flickr API
define(['jquery', 'underscore', 'marionette', 'SearchView', 'GalleryView'],
function ($, _, Marionette, SearchView, GalleryView) {
var app = new Marionette.Application();
app.addRegions({
search: '#search',
layout: '#layout'
});
app.addInitializer(function () {
this.galleryView = new GalleryView();
this.searchBox = new SearchView();
app.search.show(this.searchBox);
});
// listen to the event "images:loaded" and
// update the gallery with the new array of images
app.on('images:loaded', function(images){
this.galleryView.collection.reset(images);
app.layout.show(this.galleryView);
});
app.on('start', function(){
// listen to the event "search:value:changed" to know when the user
// has written some words on the input text, then search on the public
// feed of Flick with the Flickr API
this.searchBox.on('search:value:changed', _.bind(function(value) {
$.ajax({
url: "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
dataType: 'json',
data: {
tags: value,
tagmode: "any",
format: "json"
},
success: function(data) {
// when the response arrive puts all the images
// found create a new Array and then trigger
// an event to notify that we have new data to display
var images = [];
$.each(data.items, function(i, item){
images.push({alt: '', src: item.media.m, link: item.link});
});
this.trigger('images:loaded', images);
},
context: this
});
}, this));
});
return app;
});
define(['marionette', 'underscore'], function (Marionette, _) {
return Marionette.ItemView.extend({
tagName: 'li',
className: 'gallery-item-view',
template: _.template('<a href="#" data-link="<%= link %>"><img src="<%= src %>" alt="<%= alt %>" /></a>'),
events: {
'click a': 'onClick'
},
onClick: function(e){
e.preventDefault();
window.open(this.ui.a.data('link'));
}
});
});
define(['marionette', 'backbone', 'GalleryItemView'], function (Marionette, Backbone, GalleryItemView) {
return Marionette.CollectionView.extend({
tagName: 'ul',
className: 'gallery-view',
childView: GalleryItemView,
collection: new Backbone.Collection()
});
});
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Flickr</title>
<link href='http://fonts.googleapis.com/css?family=Roboto:300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Flickr <em>photo finder</em></h1>
<div id="search"></div>
<div id="layout"></div>
<script id="search-box-tpl" type="text/template">
<input type="text" id="search-box-input" name="search-box-input" placeholder="tags..." />
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.min.js" data-main="js/main"></script>
</body>
</html>
require.config({
baseUrl: 'js',
paths: {
'backbone': '//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min',
'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min',
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min',
'marionette': '//cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.0.3/backbone.marionette.min'
},
shim: {
'jquery': {
'exports': 'jQuery'
},
'underscore': {
'exports': '_'
},
'backbone': {
'deps': ['jquery', 'underscore'],
'exports': 'Backbone'
},
'marionette': {
'deps': ['backbone'],
'exports': 'Marionette'
},
'facebook' : {
'exports': 'FB'
}
}
});
require(['app'], function(app) {
app.start();
});
define(['underscore', 'marionette'], function (_, Marionette) {
return Marionette.ItemView.extend({
id: 'search-box',
template: '#search-box-tpl',
ui: {
input: '#search-box-input'
},
events: {
'keyup @ui.input': '_onInputChanged'
},
_onInputChanged: function(e){
this.term = e.target.value;
clearTimeout(this.timeout);
// wait to complete the word to send the event
this.timeout = setTimeout(_.bind(this.emitSearchValueChanged, this), 500);
},
emitSearchValueChanged: function(){
this.trigger('search:value:changed', this.term);
}
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Roboto';
font-size: 12px;
margin: 25px;
font-weight: 300;
color: #474747;
}
:focus {
outline: 0;
}
img {
border: 0;
vertical-align: middle;
}
h1 {
margin: 0 0 5px 4px;
font-size: 66px;
font-weight: 300;
}
h1 em {
font-size: 22px;
}
ul.gallery-view {
overflow: hidden;
height: 1%;
font-size: 0;
}
li.gallery-item-view {
list-style: none;
float: left;
width: 128px;
height: 128px;
border: 4px solid white;
overflow: hidden;
}
li.gallery-item-view:hover {
border: 4px solid red;
}
input#search-box-input {
font-family: 'Roboto';
font-size: 26px;
font-weight: 300;
padding: 5px 10px;
margin: 0 0 5px 4px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment