/Grails/backbone/web-app/js/application.js
JavaScript | 203 lines | 121 code | 39 blank | 43 comment | 8 complexity | 346b69416b19b453ae50b63cbfb8631f MD5 | raw file
Possible License(s): BSD-3-Clause
- // usage: log('inside coolFunc',this,arguments);
- // paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
- window.log = function(){
- log.history = log.history || []; // store logs to an array for reference
- log.history.push(arguments);
- if(this.console){
- console.log( Array.prototype.slice.call(arguments) );
- }
- };
- // remap jQuery to $
- (function($){
- // MODELS
- var Movie = Backbone.Model.extend({
- initialize: function (spec) {
- if (!spec || !spec.title) {
- throw "InvalidConstructArgs";
- }
-
- // we may also want to store something else as an attribute
- // for example a unique ID we can use in the HTML to identify this
- // item's element. We can use the models 'cid' or 'client id for this'.
- this.set({
- htmlId: 'movie_' + this.cid
- })
- },
-
- validate: function (attrs) {
- if (attrs.title) {
- if (!_.isString(attrs.title) || attrs.title.length === 0 ) {
- log('Movie.validate', this, arguments);
- return "Title must be a string with a length";
- }
- }
- }
- });
-
- var MovieAppModel = Backbone.Model.extend({
- initialize: function () {
- log('MovieAppModel.initialize', this, arguments);
- // init and store our MovieCollection in our app object
- this.movies = new MovieLibrary();
- }
- });
- // COLLECTIONS
- var MovieLibrary = Backbone.Collection.extend({
- model: Movie,
- initialize: function () {
- // somthing
- }
- });
-
- // VIEWS
- var MovieView = Backbone.View.extend({
- initialize: function (args) {
- _.bindAll(this, 'changeTitle');
-
- log('MovieView.initialize', this, arguments)
- //log(this.model)
- this.model.bind('change:title', this.changeTitle);
- },
- events: {
- 'click .title': 'handleTitleClick'
- },
- render: function () {
- // "ich" is ICanHaz.js magic
- // this.el = ich.movie(this.model.toJSON());
- // this.el = this.model.toJSON();
- log('MovieView.render', this, arguments);
- //log(this.model.get('title'));
- var content = '<li id="'+this.model.get('htmlId')+'"><span class="title">'+this.model.get('title')+'</span> <a href="javascript:app.view.removeMovie(\''+this.model.get('htmlId')+'\');">x</span></li>';
- //log(content)
- this.el = $(content);
- //log(this.el);
- return this;
- },
- changeTitle: function () {
- this.$('.title').text(this.model.get('title'));
- },
- handleTitleClick: function () {
- alert('you clicked the title: ' + this.model.get('title'));
- }
- });
-
- var MovieAppView = Backbone.View.extend({
- initialize: function () {
- log('MovieAppView.initialize', this, arguments);
- // this.model refers the the model we pass to the view when we
- // first init our view. So here we listen for changes to the movie collection.
- this.model.movies.bind('add', this.addMovie);
- this.model.movies.bind('remove', this.removeMovie);
- },
- events: {
- // any user events (clicks etc) we want to respond to
- },
- // grab and populate our main template
- render: function () {
- // once again this is using ICanHaz.js, but you can use whatever
- //this.el = ich.app(this.model.toJSON());
- log('MovieAppView.render', this, arguments);
- this.el = $('<ul id="movies"></ul>');//this.model.toJSON();
- // store a reference to our movie list
- this.movieList = this.el.filter('#movies');
- return this;
- },
- addMovie: function (movie) {
- var view = new MovieView(movie);
- // here we use our stored reference to the movie list element and
- // append our rendered movie view.
- log('MovieAppView.addMovie', this, arguments);
- this.movieList.append(view.render().el);
- },
- removeMovie: function (movie) {
- // here we can use the html ID we stored to easily find
- // and remove the correct element/elements from the view if the
- // collection tells us it's been removed.
- log('MovieAppView.removeMovie')
- log(movie)
-
- var htmlId = (typeof movie.get !== 'undefined') ? movie.get('htmlId') : movie
- log(htmlId)
- this.$('#' + htmlId).remove();
- }
- });
-
- // CONTROLLERS
- var MovieAppController = {
- init: function (spec) {
- // default config
- this.config = {
- connect: true
- };
- // extend our default config with passed in object attributes
- _.extend(this.config, spec);
- this.model = new MovieAppModel({
- nick: this.config.nick,
- account: this.config.account,
- jid: this.config.jid,
- boshUrl: this.config.boshUrl
- });
- this.view = new MovieAppView({model: this.model});
- // standalone modules that respond to document events
- //this.sm = new SoundMachine();
- return this;
- },
-
- promptMovie: function() {
- var movie = prompt("Please enter a Movie:");
- this.view.addMovie({model:new Movie({title:movie})});
-
- },
- // any other functions here should be events handlers that respond to
- // document level events. In my case I was using this to respond to incoming XMPP
- // events. So the logic for knowing what those meant and creating or updating our
- // models and collections lived here.
- handlePubSubUpdate: function () {}
- };
-
- $(document).ready(function() {
- // init our app
- window.app = MovieAppController.init({
- account: '{{ user.get_profile.account.slug }}',
- // etc, etc
- });
- // draw our main view
- $('#view').append(app.view.render().el);
- })
- })(this.jQuery);
- // catch all document.write() calls
- (function(doc){
- var write = doc.write;
- doc.write = function(q){
- log('document.write(): ',arguments);
- if (/docwriteregexwhitelist/.test(q)) write.apply(doc,arguments);
- };
- })(document);