Skip to content

Instantly share code, notes, and snippets.

@loopmode
Created August 6, 2014 12:58
Show Gist options
  • Save loopmode/125201a540a66f8e5e87 to your computer and use it in GitHub Desktop.
Save loopmode/125201a540a66f8e5e87 to your computer and use it in GitHub Desktop.
Simple MVC, jQuery/Underscore
(function($, _) {
if (!Function.prototype.bind) Function.prototype.bind = function(scope) { return $.proxy(this, scope); };
if (!window.console) { window.console = {log : $.noop, warn: $.noop, error : $.noop}; }
_.templateSettings = { interpolate: /\{\{(.+?)\}\}/g };
$(document).ready(function() {
window.portfolio = new PortfolioController();
});
function PortfolioController() {
var projects = new ProjectsCollection()
, gridView = new GridView(projects)
, detailsView = new DetailsView(projects)
$(document).on('click', '.portfolio-item', function(e) {
var pid = $(e.currentTarget).attr('data-project-id')
, model = projects.get(pid);
detailsView.render(model);
});
$(document).on('click', '.close-project a', function(e) {
detailsView.close();
return false;
});
this.collection = projects;
this.gridView = gridView;
this.detailsView = detailsView;
projects.load('./projects/list.json');
}
/**
* Creates a project object and makes sure that
* required properties are set to defaults.
* @param project {Object} The project json object
*/
function ProjectModel(project) {
if (!project.video && !window.location.href.match('localhost')) { console.warn('Missing video', project); }
var model = {
title : "",
category : "",
client : "",
agency : "",
year : "",
media : "",
job : "",
video : "",
path : "",
thumbnail : project.path + "/thumbnail.jpg",
poster : project.path + "/poster.jpg"
};
// extend only if value is truthy/not empty
_.each(project, function(value, key) {
if (value) {model[key] = value;}
});
//console.log('ProjectModel', project, model);
return model;
}
/**
* Creates an object that serves as a media definition for jsplayer.setMedia
* Contains a "poster" property and an extension-based property for each
* video file/format, e.g. "mp4": "myfile.mp4"
*/
function JPlayerMedia(project) {
var result = {
poster: project.poster
};
_.each((project.video || '').split(','), function(filename) {
var extension = filename.substr(filename.lastIndexOf('.') + 1, filename.length);
result[extension] = project.path + '/' + filename;
});
return result;
}
function ProjectsCollection() {
this.data = {};
this.items = [];
this.load = function(src) { $.getJSON(src, this.parse.bind(this)); };
this.parse = function(response) {
_.each(response, function(item) {
this.data[item.id] = new ProjectModel(item);
this.items.push(this.data[item.id]);
}, this);
$(this).triggerHandler('loaded', this.data, this.items);
};
this.get = function(pid) {
return this.data[pid];
};
}
function GridView(collection) {
this.render = function() {
var element = $('#portfolio-grid3')
, template = $('#project-item-template')
, compile = _.template(template.html());
;
var html = ''
_.each(collection.items, function(project) {
html += compile(project);
});
element.html(html);
};
$(collection).on('loaded', this.render.bind(this));
}
function DetailsView(model) {
var currentProjectId = null;
this.render = function(project) {
var element = $('#ajax-portfolio .ajax-content')
, template = $('#project-details-template')
, compile = _.template(template.html())
;
element.attr('id', 'portfolio-single');
element.html(compile(project));
createVideo(element.find('#jquery_jplayer_' + project.id), project);
//startAnimation(project.id);
};
function createVideo(element, project) {
element.jPlayer({
ready: function () {
element.jPlayer("setMedia", new JPlayerMedia(project));
},
size: {
width: "100%",
height: "auto"
},
cssSelectorAncestor: "#jp_interface_" + project.id,
swfPath: "files/jplayer",
supplied: "ogv,m4v,webmv,all"
});
}
}
}(window.jQuery, window._));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment