SlideShare a Scribd company logo
Raimonds Simanovskis

Rails-like JavaScript
using CoffeeScript,
Backbone.js and
Jasmine
Raimonds Simanovskis

       github.com/rsim




         @rsim

             .com
The Problem
Ruby code in Rails

Recommended for you

Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5

ECMAScript 5 (ES5) is the 5th edition of the ECMAScript standard. It introduces new meta-level controls like property descriptors to define properties, refinements like making built-ins tamper-proof, and additions to the language API like new methods for strings and arrays. Strict mode helps catch errors and undefined behavior. Support for ES5 varies across browsers.

use strictjavascriptstrict mode
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...

This talk takes a deep dive into asynchronous programming patterns and practices, with an emphasis on the promise pattern. We go through the basics of the event loop, highlighting the drawbacks of asynchronous programming in a naive callback style. Fortunately, we can use the magic of promises to escape from callback hell with a powerful and unified interface for async APIs. Finally, we take a quick look at the possibilities for using coroutines both in current and future (ECMAScript Harmony) JavaScript.

javascriptpromisesajax
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript

Love it or hate it, JavaScript is playing an increasingly important role in the next generation of web and mobile apps. As code continues to move from the server to the client, JavaScript is being used to do more than simple HTML manipulation. Be prepared for this transition and make sure the JavaScript you write is optimized and ready to perform on desktops and devices! In this session, you will learn ten practical tips that you can use today to write faster, more maintainable, memory friendly JavaScript.

software developmentbest practicejavascript
JavaScript code in
   Rails 3.0.x
application.js
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
Which leads to...
(example from Redmine)
application.js
                  (example from Redmine)
/* redMine - project management software
   Copyright (C) 2006-2008 Jean-Philippe Lang */

function checkAll (id, checked) {
  var els = Element.descendants(id);
  for (var i = 0; i < els.length; i++) {
    if (els[i].disabled==false) {
      els[i].checked = checked;
    }
  }
}

function toggleCheckboxesBySelector(selector) {
  boxes = $$(selector);
  var all_checked = true;
  for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
  for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
}

function setCheckboxesBySelector(checked, selector) {
  var boxes = $$(selector);
  boxes.each(function(ele) {
    ele.checked = checked;
  });
}

function showAndScrollTo(id, focus) {
  Element.show(id);
  if (focus!=null) { Form.Element.focus(focus); }

Recommended for you

Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp

The fundamentals and advance application of Node will be covered. We will explore the design choices that make Node.js unique, how this changes the way applications are built and how systems of applications work most effectively in this model. You will learn how to create modular code that’s robust, expressive and clear. Understand when to use callbacks, event emitters and streams.

nodev8version 8
Scala active record
Scala active recordScala active record
Scala active record

This document provides an overview of Scala-ActiveRecord, a type-safe Active Record model library for Scala. It discusses features such as being type-safe, having Rails ActiveRecord-like functionality, automatic transaction control, and support for associations and validations. The document also covers getting started, defining schemas, CRUD operations, queries, caching queries, validations, callbacks, and relationships.

AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript

The document discusses working with code abstract syntax trees (ASTs). It provides examples of parsing code into ASTs using libraries like Esprima, querying ASTs using libraries like grasp-equery, constructing and transforming ASTs, and generating code from ASTs. It introduces aster, an AST-based code builder that allows defining reusable AST transformations as plugins and integrating AST-based builds into generic build systems like Grunt and Gulp. Aster aims to improve on file-based builders by working directly with ASTs in a streaming fashion.

source codejavascriptmetaprogramming
/*
 * 1 - registers a callback which copies the csrf token into the
 * X-CSRF-Token header with each ajax request. Necessary to


                           application.js
 * work with rails applications which have fixed
 * CVE-2011-0447
 * 2 - shows and hides ajax indicator
 */
Ajax.Responders.register({

                      (example from Redmine)
    onCreate: function(request){
        var csrf_meta_tag = $$('meta[name=csrf-token]')[0];

         if (csrf_meta_tag) {
             var header = 'X-CSRF-Token',
                 token = csrf_meta_tag.readAttribute('content');

                if (!request.options.requestHeaders) {
                  request.options.requestHeaders = {};
                }
                request.options.requestHeaders[header] = token;
            }

         if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
             Element.show('ajax-indicator');
         }
      },
      onComplete: function(){
          if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
              Element.hide('ajax-indicator');
          }
      }
});

function hideOnLoad() {
  $$('.hol').each(function(el) {
    el.hide();
  });
}

Event.observe(window, 'load', hideOnLoad);
The Problem #2
Do we really know
    (and love?)
   JavaScript?
Sample JavaScript
               (from RailsCasts #267)
var CreditCard = {
  cleanNumber: function(number) {
    return number.replace(/[- ]/g, "");
  },

     validNumber: function(number) {
       var total = 0;
       number = this.cleanNumber(number);
       for (var i=number.length-1; i >= 0; i--) {
         var n = parseInt(number[i]);
         if ((i+number.length) % 2 == 0) {
            n = n*2 > 9 ? n*2 - 9 : n*2;
          }
          total += n;
       };
       return total % 10 == 0;
     }
};

console.log(CreditCard.validNumber('4111 1111-11111111')); // true
console.log(CreditCard.validNumber('4111111111111121'));   // false

Recommended for you

Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012

The document discusses bytecode and the ASM library for manipulating Java bytecode. It provides an overview of bytecode structure and instructions. ASM is introduced as a low-level API for working with bytecode using visitors and nodes. Examples are given for generating bytecode using ASM, such as creating a ClassWriter, visiting classes, fields and methods, and generating instructions.

33degree
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST

This was a talk given at HTML5DevConf SF in 2015. Ever wanted to write your own Browserify or Babel? Maybe have an idea for something new? This talk will get you started understanding how to use a JavaScript AST to transform and generate new code.

astbabelshift-ast
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015

Video presentation: https://www.youtube.com/watch?v=jLAFXQ1Av50 Most applications written in Ruby are great, but also exists evil code applying WOP techniques. There are many workarounds in several programming languages, but in Ruby, when it happens, the proportion is bigger. It's very easy to write Ruby code with collateral damage. You will see a collection of bad Ruby codes, with a description of how these codes affected negatively their applications and the solutions to fix and avoid them. Long classes, coupling, misapplication of OO, illegible code, tangled flows, naming issues and other things you can ever imagine are examples what you'll get.

rubysoftware developmentprodis
We see as this
                  “ugly” Ruby
CreditCard = {
  :cleanNumber => lambda { |number|
    return number.gsub(/[- ]/, "");
  },

     :validNumber => lambda { |number|
       total = 0;
       number = CreditCard[:cleanNumber].call(number);
       for i in 0..(number.length-1)
         n = number[i].to_i;
         if ((i+number.length) % 2 == 0)
            n = n*2 > 9 ? n*2 - 9 : n*2;
         end
         total += n;
       end;
       return total % 10 == 0;
     }
};

puts(CreditCard[:validNumber].call('4111 1111-11111111')); # true
puts(CreditCard[:validNumber].call('4111111111111121'));   # false
Or as this “normal” Ruby
module CreditCard
  def self.clean_number(number)
    number.gsub(/[- ]/, "")
  end

  def self.valid_number?(number)
    total = 0
    number = clean_number(number)
    for i in 0...number.length
      n = number[i].to_i
      if i+number.length % 2 == 0
        n = n*2 > 9 ? n*2 - 9 : n*2
      end
      total += n
    end
    total % 10 == 0
  end
end

puts CreditCard.valid_number?('4111 1111-11111111') # true
puts CreditCard.valid_number?('4111111111111121')   # false
“Best practices” Ruby
class CreditCard
  def initialize(number)
    @number = clean_number(number)
  end

  def valid?
    total = 0
    for i in 0...@number.length
      n = @number[i].to_i
      if i+@number.length % 2 == 0
        n = n*2 > 9 ? n*2 - 9 : n*2
      end
      total += n
    end
    total % 10 == 0
  end

  private

  def clean_number(number)
    number.gsub(/[- ]/, "")
  end
end

puts CreditCard.new('4111 1111-11111111').valid? # true
puts CreditCard.new('4111111111111121').valid?   # false
JavaScript has objects too!
var CreditCard = function(number) {
   function cleanNumber(number) {
     return number.replace(/[- ]/g, "");
   }
   this.number = cleanNumber(number);
};

CreditCard.prototype = {
   isValid: function() {
     var total = 0;
     for (var i=this.number.length-1; i >= 0; i--) {
       var n = parseInt(this.number[i]);
       if ((i+this.number.length) % 2 == 0) {
          n = n*2 > 9 ? n*2 - 9 : n*2;
        }
        total += n;
     };
     return total % 10 == 0;
   }
};

console.log( (new CreditCard('4111 1111-11111111')).isValid() ); // true
console.log( (new CreditCard('4111111111111121')).isValid() );   // false

Recommended for you

G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門

This document describes configuration files and commands related to the Grails web application framework. It includes snippets of code for configuring data sources, dependencies, plugins, logging and more. It also shows URL mapping definitions, service classes, tag libraries and examples of testing controllers and services. The document provides an overview of the core components and configuration of Grails applications.

jggug grails groovy sandai
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a string

The document discusses abstract syntax trees (ASTs) and parsing of code. It provides examples of parsing JavaScript code into tokens and then building a syntax tree. It also discusses common JavaScript parsers like Esprima and Acorn, and AST specifications like ESTree. Homomorphic parsing is shown where code and AST are equivalent. Common uses of ASTs include transpilation, linting, minification, and code transformation.

estreejavascriptparser
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices

In this presentation there are ten useful JavaScript techniques which can be included in your application easily with less friction along with some AngularJs tips and best practices as a bonus. These tips and best practices are accompanied by examples & will cover script loading, design pattern, performance optimization and other areas. Since best practices are very subjective topics, proper benchmarking needs to be done.

javascript tipsjavascript best practicesjavascript
But this would be much
        more Ruby-like!
class CreditCard
  cleanNumber = (number) -> number.replace /[- ]/g, ""

 constructor: (number) ->
   @number = cleanNumber number

 isValid: (number) ->
   total = 0
   for i in [0...@number.length]
     n = +@number[i]
     if (i+@number.length) % 2 == 0
       n = if n*2 > 9 then n*2 - 9 else n*2
     total += n
   total % 10 == 0

console.log (new CreditCard '4111 1111-11111111').isValid() # true
console.log (new CreditCard '4111111111111121').isValid()   # false
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Sample CoffeeScript
# Assignment:                   # Splats:
number   = 42                   race = (winner, runners...) ->
opposite = true                   print winner, runners

# Conditions:                   # Existence:
number = -42 if opposite        alert "I knew it!" if elvis?

# Functions:                    # Array comprehensions:
square = (x) -> x * x           cubes = (math.cube num for num in list)

# Arrays:
list = [1, 2, 3, 4, 5]

# Objects:
math =
  root:    Math.sqrt
  square: square
  cube:   (x) -> x * square x

Recommended for you

RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote

This document provides instructions for setting up a demonstration of the magic_model_generator gem. It mentions setting up the database.yml file and increasing the font size. It also provides commands for starting the postgres database, generating models from existing tables, and preparing the development environment for the demo.

Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8

Presentation from xlab workshop about functional programming components introduced to the Java 8. How to operate the streams and lambdas in theory and practice.

programmingxsolvejava
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack

Http4s, Doobie and Circe together form a nice platform for building web services. This presentations provides an introduction to using them to build your own service.

scalafunctional programmingcirce
Functions
square = (x) -> x * x
cube   = (x) -> square(x) * x

fill = (container, liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."

awardMedals = (first, second, others...) ->
  gold   = first
  silver = second
  rest   = others

contenders = [
  "Michael Phelps"
  "Liu Xiang"
  "Yao Ming"
  "Allyson Felix"
  "Shawn Johnson"
]

awardMedals contenders...
Objects and Arrays
 song = ["do", "re", "mi", "fa", "so"]

 singers = {Jagger: "Rock", Elvis: "Roll"}

 bitlist   = [
   1, 0,   1
   0, 0,   1
   1, 1,   0
 ]

 kids =
   brother:
     name: "Max"
     age: 11
   sister:
     name: "Ida"
     age: 9
Variable Scope

                          var changeNumbers, inner, outer;
outer = 1                 outer = 1;
changeNumbers = ->        changeNumbers = function() {
                             var inner;
  inner = -1                 inner = -1;
  outer = 10                 return outer = 10;
inner = changeNumbers()   };
                          inner = changeNumbers();
Existential Operator
 solipsism = true if mind? and not world?

 speed ?= 75

 footprints = yeti ? "bear"

 zip = lottery.drawWinner?().address?.zipcode

Recommended for you

Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing

Workshop JavaScript Testing. Frameworks. Client vs Server Testing. Jasmine. Chai. Nock. Sinon. Spec Runners: Karma. TDD. Code coverage. Building a testable JS app. Presentado por ing: Raúl Delgado y Mario García

visualengintestingjavascript
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript

Basic JavaScript Object Oriented Best Practices Library MVC Performance Debug Documentation Tools

javascriptmvctools
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript

The document discusses CoffeeScript, a programming language that compiles to JavaScript. It provides examples of CoffeeScript syntax for functions, conditionals, loops, classes, and other constructs. It explains how CoffeeScript aims to have less syntactic noise than JavaScript while remaining true to the underlying JavaScript semantics through compilation.

coffeescript
Conditionals
mood = greatlyImproved if singing

if happy and knowsIt
  clapsHands()
  chaChaCha()
else
  showIt()

date = if friday then sue else jill

options or= defaults
Loops

eat food for food in ['toast', 'cheese', 'wine']
countdown = (num for num in [10..1])

earsOld = max: 10, ida: 9, tim: 11
ages = for child, age of yearsOld
  child + " is " + age
Classes, Inheritance
     and super
  class Animal
    constructor: (@name) ->

    move: (meters) ->
      alert @name + " moved " + meters + "m."

  class Snake extends Animal
    move: ->
      alert "Slithering..."
      super 5

  class Horse extends Animal
    move: ->
      alert "Galloping..."
      super 45

  sam = new Snake "Sammy the Python"
  tom = new Horse "Tommy the Palomino"

  sam.move()
  tom.move()
Function Binding

Account = (customer, cart) ->
  @customer = customer
  @cart = cart

  $('.shopping_cart').bind 'click', (event) =>
    @customer.purchase @cart

Recommended for you

CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript

CoffeeScript is a programming language that compiles to JavaScript. It aims to enhance JavaScript with features like significant whitespace, variables and functions declarations, and pattern matching. The document provides an overview of CoffeeScript's syntax and features like classes, functions, objects, and array/object comprehensions which compile down to cleaner JavaScript code. Examples are given throughout to illustrate CoffeeScript code and its compiled JavaScript output.

coffeescriptjavascriptpython
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy

My talk about Functional Programming with Groovy at Greach Greach http://greach.es/ the Groovy spanish conf Date: 04-11-2011

groovyfunctional programming
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try

Let's try to look at Elm, is it something like TypeScript or Haskell? Should we use it on a daily basis?

elmhaskelljavascript
And many other
nice features...
How to install?


brew install node # or install node.js otherwise
curl http://npmjs.org/install.sh | sh
npm install -g coffee-script
Back to the
Problem #1
Dynamic single page
    application

Recommended for you

Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine

This document discusses using CoffeeScript, Backbone.js, and Jasmine BDD to build single page web applications. It begins by explaining why CoffeeScript is useful for cleaning up JavaScript code and avoiding errors. It then discusses how Backbone.js provides structure for single page apps by defining models, collections, views and routers. It notes that Backbone works well with CoffeeScript. Finally, it mentions that Jasmine BDD can be used for writing professional tests.

backbone coffeescript jasmine bdd tdd web applicat
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction

This document provides an introduction to Javascript and jQuery. It covers Javascript data types including numbers, strings, Booleans, null/undefined, and arrays. It then covers jQuery topics like jQuery objects, selectors, CSS manipulation, events including ready and load, and AJAX/JSON requests using both asynchronous and synchronous modes. It includes examples for working with numbers, strings, selectors, events, AJAX calls and shortcuts. The document aims to provide a pragmatic introduction to Javascript and jQuery concepts and functionality.

jqueryjavascriptajax
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy

Groovy is a dynamic language for the Java platform that provides features inspired by languages like Python, Ruby and Smalltalk. It allows Java developers to use these features with a syntax that is very similar to Java. Groovy code can be compiled to Java bytecode and integrated with Java applications and libraries. It supports features like closures, metaprogramming, builders and templates to improve developer productivity.

javagroovyprogramming
Identifying
components
    AppView
Identifying
components
    AppView



              TodoView
              TodoView
              TodoView
Identifying
components
          AppView

keypress event
click event          TodoView
      dblclick event TodoView
                     TodoView
                     click event
Browser-side
       Views and Models
          AppView
                                   TodoList
keypress event
click event          TodoView       Todo
      dblclick event TodoView       Todo
                     TodoView       Todo
                     click event

Recommended for you

Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters

This document provides an overview of various JavaScript concepts and techniques, including: - Prototypal inheritance allows objects in JavaScript to inherit properties from other objects. Functions can act as objects and have a prototype property for inheritance. - Asynchronous code execution in JavaScript is event-driven. Callbacks are assigned as event handlers to execute code when an event occurs. - Scope and closures - variables are scoped to functions. Functions create closures where they have access to variables declared in their parent functions. - Optimization techniques like event delegation and requestAnimationFrame can improve performance of event handlers and animations.

javascriptprogrammingwebdev
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour

The document provides an overview of the Ruby programming language with sections on installation, data types, operators, control structures, methods, classes and modules. It discusses key aspects of Ruby like its object oriented nature, dynamic typing, syntax and cross-platform capabilities. The document serves as a quick tour of the Ruby language covering its basic concepts, structures and features.

ruby quick tour
Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB

This document provides an overview of CoffeeScript, highlighting some of its key features and benefits compared to JavaScript. It discusses CoffeeScript's lighter syntax, object literals, list comprehensions, and implicit returns. It also addresses some criticisms of CoffeeScript, such as concerns about it being "just JavaScript" or a "toy language." Overall, the document promotes CoffeeScript as a cleaner syntax for writing JavaScript code.

coffeescriptjavascriptruby on rails
Browser-side
       Views and Models
          AppView
                                   new, fetch
                                                  TodoList
keypress event
click event          TodoView      create, save
                                                   Todo
      dblclick event TodoView                      Todo
                     TodoView                      Todo
                     click event
Browser-side
      Views and Models
         AppView
                               refresh, add    TodoList
keypress event
click event          TodoView                   Todo
      dblclick event TodoViewchange, destroy    Todo
                     TodoView                   Todo
                     click event
Browser-side Models
and RESTful resources
Browser                  Rails
             GET
 TodoList            TodosController
            POST          index
  Todo       PUT          show
  Todo                    create
            DELETE       update
  Todo
                         destroy
              JSON
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine

Recommended for you

CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript

This document provides an overview and introduction to CoffeeScript, a programming language that compiles to JavaScript. It shows how CoffeeScript code compiles to equivalent JavaScript code, and demonstrates CoffeeScript features like functions, classes, and object-oriented programming. The document introduces CoffeeScript syntax for arrays, objects, loops, and functions, and compares syntax to JavaScript. It also covers CoffeeScript concepts like scoping, context, and class-based object-oriented programming using prototypes.

coffeescriptjavascript
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer

The document describes MOBL, a programming language for building mobile web applications. MOBL aims to provide a small core language with large and extensible libraries. It includes built-in types, controls, and abstraction mechanisms like screens and functions. The language exposes low-level primitives while providing a native interface to external APIs. MOBL code can be deployed by concatenating, eliminating dead code, and minifying for client-side execution on mobile browsers. The language has been publicly released since January 2011 and sees over 1,000 visitors per day, with ongoing development focused on error handling, data evolution, documentation and libraries.

ihomemoblmobile web
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture

Mobl is a programming language for building mobile web applications. It aims to provide portability across different mobile platforms and browsers by compiling to JavaScript and HTML5. Mobl supports common mobile features like location services, camera, contacts and more through a simple object-oriented syntax. It also includes tools for building user interfaces, accessing data through entities and queries, and making web service requests. The goal is to enable complete coverage of mobile development needs while avoiding platform-specific code.

programmingdslmdsd
Organize CoffeeScript
and JavaScript Code




 using http://github.com/Sutto/barista
application.coffee

    # main namespace
    window.TodoApp = {}
Todo model
class TodoApp.Todo extends Backbone.Model

 # If you don't provide a todo, one will be provided for you.
 EMPTY: "empty todo..."

 # Ensure that each todo created has `content`.
 initialize: ->
   unless @get "content"
     @set content: @EMPTY

 # Toggle the `done` state of this todo item.
 toggle: ->
   @save done: not @get "done"
TodoList collection
class TodoApp.TodoList extends Backbone.Collection

 # Reference to this collection's model.
 model: TodoApp.Todo

 # Save all of the todo items under the `"todos"` namespace.
 url: '/todos'

 # Filter down the list of all todo items that are finished.
 done: ->
   @filter (todo) -> todo.get 'done'

 # Filter down the list to only todo items that are still not finished.
 remaining: ->
   @without this.done()...

 # We keep the Todos in sequential order, despite being saved by unordered
 # GUID in the database. This generates the next order number for new items.
 nextOrder: ->
   if @length then @last().get('order') + 1 else 1

 # Todos are sorted by their original insertion order.
 comparator: (todo) ->
   todo.get 'order'

Recommended for you

Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tips

jQuery Tips and Trick by NagaHarish on 21 Jan 2012... For the Demos given in this slides refer https://github.com/anubavam-techkt/jQuery-tricks-tips-nagaharish

optimizationjquery
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure

This document discusses refactoring Java code to Clojure using macros. It provides examples of refactoring Java code that uses method chaining to equivalent Clojure code using the threading macros (->> and -<>). It also discusses other Clojure features like type hints, the doto macro, and polyglot projects using Leiningen.

Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016

Redux-observable allows combining RxJS and Redux by introducing Epics. Epics are Observable streams that handle asynchronous logic in response to Redux actions. This avoids callback hell and enables features like cancellation. An Epic takes an action stream, performs asynchronous operations like AJAX calls using RxJS, and dispatches result actions. This keeps Redux synchronous while managing complex async flows in a declarative and reusable way.

rxjsjavascriptreact
Todo item view
class TodoApp.TodoView extends Backbone.View
  # ... is a list tag.
  tagName: "li"

 # Cache the template function for a single item.
 template: TodoApp.template '#item-template'

 # The DOM events specific to an   item.
 events:
   "click .check"              :   "toggleDone"
   "dblclick div.todo-content" :   "edit"
   "click span.todo-destroy"   :   "destroy"
   "keypress .todo-input"      :   "updateOnEnter"

 # The TodoView listens for changes to its model, re-rendering. Since there's
 # a one-to-one correspondence between a **Todo** and a **TodoView** in this
 # app, we set a direct reference on the model for convenience.
 initialize: ->
   _.bindAll this, 'render', 'close'
   @model.bind 'change', @render
   @model.bind 'destroy', => @remove()

 # Re-render the contents of the todo item.
 render: ->
   $(@el).html @template @model.toJSON()
   @setContent()
   this
# Re-render the contents of the todo item.
render: ->
  $(@el).html @template @model.toJSON()
  @setContent()


            Todo item view
  this

# To avoid XSS (not that it would be harmful in this particular app),
# we use `jQuery.text` to set the contents of the todo item.
setContent: ->
  content = @model.get 'content'
  @$('.todo-content').text content
  @input = @$('.todo-input')
  @input.blur @close
  @input.val content

# Toggle the `"done"` state of the model.
toggleDone: ->
  @model.toggle()

# Switch this view into `"editing"` mode, displaying the input field.
edit: ->
  $(@el).addClass "editing"
  @input.focus()

# Close the `"editing"` mode, saving changes to the todo.
close: ->
  @model.save content: @input.val()
  $(@el).removeClass "editing"

# If you hit `enter`, we're through editing the item.
updateOnEnter: (e) ->
  @close() if e.keyCode == 13

# Destroy the model.
destroy: ->
  @model.destroy()
Application view
class TodoApp.AppView extends Backbone.View

 # Instead of generating a new element, bind to the existing skeleton of
 # the App already present in the HTML.
 el: "#todoapp"

 # Our template for the line of statistics at the bottom of the app.
 statsTemplate: TodoApp.template '#stats-template'

 # Delegated events for creating new items, and clearing completed ones.
 events:
   "keypress #new-todo" : "createOnEnter"
   "keyup #new-todo"     : "showTooltip"
   "click .todo-clear a" : "clearCompleted"

 # At initialization we bind to the relevant events on the `Todos`
 # collection, when items are added or changed. Kick things off by
 # loading any preexisting todos that might be saved.
 initialize: ->
   _.bindAll this, 'addOne', 'addAll', 'renderStats'

   @input = @$("#new-todo")

   @collection.bind 'add',     @addOne
   @collection.bind 'refresh', @addAll
   @collection.bind 'all',     @renderStats

   @collection.fetch()
@collection.bind 'add',     @addOne
 @collection.bind 'refresh', @addAll
 @collection.bind 'all',     @renderStats



       Application view
 @collection.fetch()

# Re-rendering the App just means refreshing the statistics -- the rest
# of the app doesn't change.
renderStats: ->
  @$('#todo-stats').html @statsTemplate
    total:      @collection.length
    done:       @collection.done().length
    remaining: @collection.remaining().length

# Add a single todo item to the list by creating a view for it, and
# appending its element to the `<ul>`.
addOne: (todo) ->
  view = new TodoApp.TodoView model: todo
  @$("#todo-list").append view.render().el

# Add all items in the collection at once.
addAll: ->
  @collection.each @addOne

# Generate the attributes for a new Todo item.
newAttributes: ->
  content: @input.val()
  order:   @collection.nextOrder()
  done:    false

# If you hit return in the main input field, create new **Todo** model,
# persisting it to server.
createOnEnter: (e) ->
  if e.keyCode == 13
    @collection.create @newAttributes()
    @input.val ''

Recommended for you

Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental Concepts

We will discover : - functional programming - naming conventions - types, operators & pattern matching - numbers & strings - list, enum, stream - tuple - modules & functions - map (key/value) - structs - case, cond and if - alias, import, require, use - try/rescue/after, throw/catch, exit

elixirerlang
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript

Long ago, in the late days of the first Internet boom, before jQuery, before Underscore, before Angular, there was a web application built by a large corporation. This application was written as a server-side application using server-side technology like Java or PHP. A tiny seed of JavaScript was added to some of the pages of this application to give it a little sizzle. Over the ages, this tiny bit of JavaScript grew like kudzu. Most of it was embedded in the HTML in

refactoringjavascriptlegacy
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE

PHP is a server-side scripting language that is embedded into HTML files. The goal is to generate client-side code like HTML, CSS, and JavaScript. PHP files are executed on the web server and must be saved in a subdirectory that is accessible to the server, like /var/www. PHP allows variables, operators, conditional statements, loops, functions, and arrays. Sessions and cookies can be used to store and retrieve information across multiple requests.

#iice.in
view = new TodoApp.TodoView model: todo
 @$("#todo-list").append view.render().el

# Add all items in the collection at once.


       Application view
addAll: ->
  @collection.each @addOne

# Generate the attributes for a new Todo item.
newAttributes: ->
  content: @input.val()
  order:   @collection.nextOrder()
  done:    false

# If you hit return in the main input field, create new **Todo** model,
# persisting it to server.
createOnEnter: (e) ->
  if e.keyCode == 13
    @collection.create @newAttributes()
    @input.val ''

# Clear all done todo items, destroying their views and models.
clearCompleted: ->
  todo.destroy() for todo in @collection.done()
  false

# Lazily show the tooltip that tells you to press `enter` to save
# a new todo item, after one second.
showTooltip: (e) ->
  tooltip = @$(".ui-tooltip-top")
  val = @input.val()
  tooltip.fadeOut()
  clearTimeout @tooltipTimeout if @tooltipTimeout
  unless val == '' or val == @input.attr 'placeholder'
    @tooltipTimeout = _.delay ->
      tooltip.show().fadeIn()
    , 1000
#todoapp
                  index.html.haml
  .title
    %h1 Todos
  .content
    #create-todo
      %input#new-todo{:placeholder => "What needs to be done?", :type => "text"}/
      %span.ui-tooltip-top{:style => "display:none;"} Press Enter to save this task
    #todos
      %ul#todo-list
    #todo-stats
%ul#instructions
  %li Double-click to edit a todo.

:coffeescript
  $ ->
    TodoApp.appView = new TodoApp.AppView collection: new TodoApp.TodoList

%script#item-template{:type => "text/html"}
  .todo{:class => "{{#done}}done{{/done}}"}
    .display
      %input{:class => "check", :type => "checkbox", :"{{#done}}checked{{/done}}" => true}
      .todo-content
      %span.todo-destroy
    .edit
      %input.todo-input{:type => "text", :value => ""}

%script#stats-template{:type => "text/html"}
  {{#if total}}
  %span.todo-count
%input#new-todo{:placeholder => "What needs to be done?", :type => "text"}/
      %span.ui-tooltip-top{:style => "display:none;"} Press Enter to save this task
    #todos
      %ul#todo-list


                  index.html.haml
    #todo-stats
%ul#instructions
  %li Double-click to edit a todo.

:coffeescript
  $ ->
    TodoApp.appView = new TodoApp.AppView collection: new TodoApp.TodoList

%script#item-template{:type => "text/html"}
  .todo{:class => "{{#done}}done{{/done}}"}
    .display
      %input{:class => "check", :type => "checkbox", :"{{#done}}checked{{/done}}" => true}
      .todo-content
      %span.todo-destroy
    .edit
      %input.todo-input{:type => "text", :value => ""}

%script#stats-template{:type => "text/html"}
  {{#if total}}
  %span.todo-count
    %span.number {{remaining}}
    %span.word {{pluralize remaining "item"}}
    left.
  {{/if}}
  {{#if done}}
  %span.todo-clear
    %a{:href => "#"}
      Clear
      %span.number-done {{done}}
      completed
      %span.word-done {{pluralize done "item"}}
  {{/if}}
One more thing:
Backbone Controllers
          Routers
class Workspace extends Backbone.Controller Router

  routes:
    "help"                : "help"     #help
    "search/:query"       : "search"   #search/kiwis
    "search/:query/p:page": "search"   #search/kiwis/p7

  help: ->
    ...

  search: (query, page) ->
    ...

Recommended for you

JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code

Get this Course https://www.udemy.com/javascript-course-plus/?couponCode=SLIDESHARE Useful methods and JavaScript code snippets power up your code and make even more happen with it. This course is perfect for anyone who has fundamental JavaScript experience and wants to move to the next level.  Use and apply more advanced code, and do more with JavaScript. Everything you need to learn more about JavaScript Source code is included 60+ page Downloadable PDF guide with resources and code snippets 3 Challenges to get you coding try the code demonstrating useful JavaScript methods that can power up your code and make even more happen with it. Course lessons will cover JavaScript Number Methods JavaScript String Methods JavaScript Math - including math random DOMContentLoaded - DOM ready when the document has loaded. JavaScript Date - Date methods and how to get set and use date. JavaScript parse and stringify - strings to objects back to strings JavaScript LocalStorage - store variables in the user browser JavaScript getBoundingClientRect() - get the dimensions of an element JavaScript Timers setTimeout() setInterval() requestAnimationFrame() - Run code when you want too encodeURIComponent - encoding made easy Regex - so powerful use it to get values from your string prototype - extend JavaScript objects with customized powers Try and catch - perfect for error and testing Fetch xHR requests - bring content in from servers and more No libraries, no shortcuts just learning JavaScript making it DYNAMIC and INTERACTIVE web application. Step by step learning with all steps included.

javascriptwebweb2.0
Profiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production EnvironmentProfiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production Environment

Mondrian MDX requests can be slow in production environments for several reasons: large schemas with many dimensions and measures can cause performance issues; querying large datasets from the database can also impact performance. To address these issues, the document discusses profiling Mondrian requests, optimizing the JVM and database, using caching, and tuning the Mondrian schema. A Mondrian schema pool is also described that reuses schema objects and periodically flushes unused schemas to free memory.

pcm18mondrianmondrian-olap
Improve Mondrian MDX usability with user defined functions
Improve Mondrian MDX usability with user defined functionsImprove Mondrian MDX usability with user defined functions
Improve Mondrian MDX usability with user defined functions

The document discusses improving MDX usability in Mondrian through user defined functions (UDFs). It provides examples of UDFs that allow accessing member properties, parsing dates, performing date calculations, calculating cumulative totals over time periods, aggregating calculated members, and setting default context. The UDFs extend MDX capabilities and make queries more readable and maintainable.

mondrianmdxeazybi
How do you test it?
RSpec-like testing for
    JavaScript
Together with all
  other tests
Testing Todo model
describe "Todo", ->
  todo = null
  ajaxCall = (param) -> jQuery.ajax.mostRecentCall.args[0][param]

  beforeEach ->
    todo = new TodoApp.Todo
    todos = new TodoApp.TodoList [todo]

  it "should initialize with empty content", ->
    expect(todo.get "content").toEqual "empty todo..."

  it "should initialize as not done", ->
    expect(todo.get "done").toBeFalsy()

  it "should save after toggle", ->
    spyOn jQuery, "ajax"
    todo.toggle()
    expect(ajaxCall "url").toEqual "/todos"
    expect(todo.get "done").toBeTruthy()

Recommended for you

Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015

This document discusses analyzing and visualizing git commit logs to gain insights. It provides examples of visualizing commit data by time, authors, files changed, and other dimensions. Examples shown include contributions over time to Rails and Node.js, top contributors, and analyzing patterns in commit times. The document advocates using git logs for code metrics and "Mining" them to learn from a codebase's history.

devternitygiteazybi
Data Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data AnalysisData Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data Analysis

The document discusses data warehouses and multi-dimensional data analysis. It provides an example of modeling sales data across multiple tables in a relational database and shows how long queries take on large amounts of data. It then introduces dimensional modeling and how to structure data in a data warehouse using fact and dimension tables. Finally, it demonstrates how to model the sales data multidimensionally using a data cube and discusses OLAP technologies like Mondrian for multi-dimensional analysis.

data-warehouse mondrian-olap railsconf
mondrian-olap JRuby library
mondrian-olap JRuby librarymondrian-olap JRuby library
mondrian-olap JRuby library

The document describes mondrian-olap, a JRuby library that allows querying Mondrian OLAP schemas using Ruby and provides examples of defining Mondrian schemas, connecting to databases, executing MDX queries, and extending functionality through user-defined functions in Ruby, JavaScript, and CoffeeScript. It proposes defining Mondrian schemas directly in CoffeeScript for increased brevity and readability.

mondrianpcm14jruby
and TodoList
                  collection
describe "TodoList", ->
  attributes = [
    content: "First"
    done: true
  ,
    content: "Second"
  ]
  todos = null

  beforeEach ->
    todos = new TodoApp.TodoList attributes

  it "should return done todos", ->
    expect(_.invoke todos.done(), "toJSON").toEqual [attributes[0]]

  it "should return remaining todos", ->
    expect(_.invoke todos.remaining(), "toJSON").toEqual [attributes[1]]
Rails 3.1
Asset Pipeline
application.js.coffee
    using Sprockets

     #=   require jquery
     #=   require underscore
     #=   require backbone
     #=   require handlebars
     #=   require ./todo_app
     #=   require_tree ./models
     #=   require ./views/helpers
     #=   require_tree ./views
Watch RailsConf
           DHH keynote
http://en.oreilly.com/rails2011/public/schedule/detail/19068

Recommended for you

eazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applicationseazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applications

This document discusses embedding the Mondrian OLAP engine in other applications. It describes how eazyBI embeds Mondrian in its integrated business intelligence application to provide ETL, reports, charts, dashboards and the ability to embed analytics in other apps. It also discusses options for deploying Mondrian in embedded and multi-tenant configurations, current issues with long running threads and calculated measures, and additional user defined functions developed for Mondrian.

pcm14eazybijruby
Atvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze LatvijāAtvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze Latvijā

Precentācija LATA 2014 konferencē

lata2014
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine

This document discusses JavaScript unit testing with Jasmine. It provides an overview of Jasmine's syntax including describes, contexts, matches, spies and stubs. It also discusses tools that can be used with Jasmine like jasmine-jquery for DOM testing and jasmine-given for behavior-driven development style tests.

javascriptjasminetesting
References
     http://jashkenas.github.com/coffee-script/

    http://documentcloud.github.com/backbone/

         http://pivotal.github.com/jasmine/



https://github.com/rsim/backbone_coffeescript_demo
Used in eazybi.com

More Related Content

What's hot

Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecord
scalaconfjp
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
Ingvar Stepanyan
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
Hermann Hueck
 
Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5
Juriy Zaytsev
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript
Todd Anglin
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
Troy Miles
 
Scala active record
Scala active recordScala active record
Scala active record
鉄平 土佐
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012
Anton Arhipov
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
Jarrod Overson
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
Fernando Hamasaki de Amorim
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
Tsuyoshi Yamamoto
 
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a string
Ingvar Stepanyan
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
Ankit Rastogi
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
Dr Nic Williams
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
XSolve
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
GaryCoady
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
Visual Engineering
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
Tarek Yehia
 

What's hot (20)

Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecord
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
 
Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Scala active record
Scala active recordScala active record
Scala active record
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
 
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a string
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 

Similar to Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine

Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
niklal
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
Ryan McGeary
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
Arturo Herrero
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
Eugene Zharkov
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
Iban Martinez
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
André Faria Gomes
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
Ara Pehlivanian
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
aztack
 
Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
jhchabran
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
Scott Leberknight
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
zefhemel
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture
zefhemel
 
Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tips
anubavam-techkt
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
Ben Lesh
 
Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental Concepts
Héla Ben Khalfallah
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Guy Royse
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
AbhishekSharma2958
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
Laurence Svekis ✔
 

Similar to Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine (20)

Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture
 
Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tips
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental Concepts
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
 

More from Raimonds Simanovskis

Profiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production EnvironmentProfiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production Environment
Raimonds Simanovskis
 
Improve Mondrian MDX usability with user defined functions
Improve Mondrian MDX usability with user defined functionsImprove Mondrian MDX usability with user defined functions
Improve Mondrian MDX usability with user defined functions
Raimonds Simanovskis
 
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Raimonds Simanovskis
 
Data Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data AnalysisData Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data Analysis
Raimonds Simanovskis
 
mondrian-olap JRuby library
mondrian-olap JRuby librarymondrian-olap JRuby library
mondrian-olap JRuby library
Raimonds Simanovskis
 
eazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applicationseazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applications
Raimonds Simanovskis
 
Atvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze LatvijāAtvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze Latvijā
Raimonds Simanovskis
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
Raimonds Simanovskis
 
JRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVMJRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVM
Raimonds Simanovskis
 
Agile Operations or How to sleep better at night
Agile Operations or How to sleep better at nightAgile Operations or How to sleep better at night
Agile Operations or How to sleep better at night
Raimonds Simanovskis
 
TDD - Why and How?
TDD - Why and How?TDD - Why and How?
TDD - Why and How?
Raimonds Simanovskis
 
Analyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and ProfitAnalyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and Profit
Raimonds Simanovskis
 
PL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be FunPL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be Fun
Raimonds Simanovskis
 
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizationsopendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
Raimonds Simanovskis
 
Extending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on RailsExtending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on Rails
Raimonds Simanovskis
 
RailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRubyRailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRuby
Raimonds Simanovskis
 
Multidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRubyMultidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRuby
Raimonds Simanovskis
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Raimonds Simanovskis
 
How to Adopt Agile at Your Organization
How to Adopt Agile at Your OrganizationHow to Adopt Agile at Your Organization
How to Adopt Agile at Your Organization
Raimonds Simanovskis
 
Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)
Raimonds Simanovskis
 

More from Raimonds Simanovskis (20)

Profiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production EnvironmentProfiling Mondrian MDX Requests in a Production Environment
Profiling Mondrian MDX Requests in a Production Environment
 
Improve Mondrian MDX usability with user defined functions
Improve Mondrian MDX usability with user defined functionsImprove Mondrian MDX usability with user defined functions
Improve Mondrian MDX usability with user defined functions
 
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
Analyze and Visualize Git Log for Fun and Profit - DevTernity 2015
 
Data Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data AnalysisData Warehouses and Multi-Dimensional Data Analysis
Data Warehouses and Multi-Dimensional Data Analysis
 
mondrian-olap JRuby library
mondrian-olap JRuby librarymondrian-olap JRuby library
mondrian-olap JRuby library
 
eazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applicationseazyBI Overview - Embedding Mondrian in other applications
eazyBI Overview - Embedding Mondrian in other applications
 
Atvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze LatvijāAtvērto datu izmantošanas pieredze Latvijā
Atvērto datu izmantošanas pieredze Latvijā
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
 
JRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVMJRuby - Programmer's Best Friend on JVM
JRuby - Programmer's Best Friend on JVM
 
Agile Operations or How to sleep better at night
Agile Operations or How to sleep better at nightAgile Operations or How to sleep better at night
Agile Operations or How to sleep better at night
 
TDD - Why and How?
TDD - Why and How?TDD - Why and How?
TDD - Why and How?
 
Analyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and ProfitAnalyze and Visualize Git Log for Fun and Profit
Analyze and Visualize Git Log for Fun and Profit
 
PL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be FunPL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be Fun
 
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizationsopendata.lv Case Study - Promote Open Data with Analytics and Visualizations
opendata.lv Case Study - Promote Open Data with Analytics and Visualizations
 
Extending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on RailsExtending Oracle E-Business Suite with Ruby on Rails
Extending Oracle E-Business Suite with Ruby on Rails
 
RailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRubyRailsWayCon: Multidimensional Data Analysis with JRuby
RailsWayCon: Multidimensional Data Analysis with JRuby
 
Multidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRubyMultidimensional Data Analysis with JRuby
Multidimensional Data Analysis with JRuby
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
 
How to Adopt Agile at Your Organization
How to Adopt Agile at Your OrganizationHow to Adopt Agile at Your Organization
How to Adopt Agile at Your Organization
 
Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)Multidimensional Data Analysis with Ruby (sample)
Multidimensional Data Analysis with Ruby (sample)
 

Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine

  • 1. Raimonds Simanovskis Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
  • 2. Raimonds Simanovskis github.com/rsim @rsim .com
  • 4. Ruby code in Rails
  • 5. JavaScript code in Rails 3.0.x
  • 6. application.js // Place your application-specific JavaScript functions and classes here // This file is automatically included by javascript_include_tag :defaults
  • 8. application.js (example from Redmine) /* redMine - project management software Copyright (C) 2006-2008 Jean-Philippe Lang */ function checkAll (id, checked) { var els = Element.descendants(id); for (var i = 0; i < els.length; i++) { if (els[i].disabled==false) { els[i].checked = checked; } } } function toggleCheckboxesBySelector(selector) { boxes = $$(selector); var all_checked = true; for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } } for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; } } function setCheckboxesBySelector(checked, selector) { var boxes = $$(selector); boxes.each(function(ele) { ele.checked = checked; }); } function showAndScrollTo(id, focus) { Element.show(id); if (focus!=null) { Form.Element.focus(focus); }
  • 9. /* * 1 - registers a callback which copies the csrf token into the * X-CSRF-Token header with each ajax request. Necessary to application.js * work with rails applications which have fixed * CVE-2011-0447 * 2 - shows and hides ajax indicator */ Ajax.Responders.register({ (example from Redmine) onCreate: function(request){ var csrf_meta_tag = $$('meta[name=csrf-token]')[0]; if (csrf_meta_tag) { var header = 'X-CSRF-Token', token = csrf_meta_tag.readAttribute('content'); if (!request.options.requestHeaders) { request.options.requestHeaders = {}; } request.options.requestHeaders[header] = token; } if ($('ajax-indicator') && Ajax.activeRequestCount > 0) { Element.show('ajax-indicator'); } }, onComplete: function(){ if ($('ajax-indicator') && Ajax.activeRequestCount == 0) { Element.hide('ajax-indicator'); } } }); function hideOnLoad() { $$('.hol').each(function(el) { el.hide(); }); } Event.observe(window, 'load', hideOnLoad);
  • 11. Do we really know (and love?) JavaScript?
  • 12. Sample JavaScript (from RailsCasts #267) var CreditCard = { cleanNumber: function(number) { return number.replace(/[- ]/g, ""); }, validNumber: function(number) { var total = 0; number = this.cleanNumber(number); for (var i=number.length-1; i >= 0; i--) { var n = parseInt(number[i]); if ((i+number.length) % 2 == 0) { n = n*2 > 9 ? n*2 - 9 : n*2; } total += n; }; return total % 10 == 0; } }; console.log(CreditCard.validNumber('4111 1111-11111111')); // true console.log(CreditCard.validNumber('4111111111111121')); // false
  • 13. We see as this “ugly” Ruby CreditCard = { :cleanNumber => lambda { |number| return number.gsub(/[- ]/, ""); }, :validNumber => lambda { |number| total = 0; number = CreditCard[:cleanNumber].call(number); for i in 0..(number.length-1) n = number[i].to_i; if ((i+number.length) % 2 == 0) n = n*2 > 9 ? n*2 - 9 : n*2; end total += n; end; return total % 10 == 0; } }; puts(CreditCard[:validNumber].call('4111 1111-11111111')); # true puts(CreditCard[:validNumber].call('4111111111111121')); # false
  • 14. Or as this “normal” Ruby module CreditCard def self.clean_number(number) number.gsub(/[- ]/, "") end def self.valid_number?(number) total = 0 number = clean_number(number) for i in 0...number.length n = number[i].to_i if i+number.length % 2 == 0 n = n*2 > 9 ? n*2 - 9 : n*2 end total += n end total % 10 == 0 end end puts CreditCard.valid_number?('4111 1111-11111111') # true puts CreditCard.valid_number?('4111111111111121') # false
  • 15. “Best practices” Ruby class CreditCard def initialize(number) @number = clean_number(number) end def valid? total = 0 for i in 0...@number.length n = @number[i].to_i if i+@number.length % 2 == 0 n = n*2 > 9 ? n*2 - 9 : n*2 end total += n end total % 10 == 0 end private def clean_number(number) number.gsub(/[- ]/, "") end end puts CreditCard.new('4111 1111-11111111').valid? # true puts CreditCard.new('4111111111111121').valid? # false
  • 16. JavaScript has objects too! var CreditCard = function(number) { function cleanNumber(number) { return number.replace(/[- ]/g, ""); } this.number = cleanNumber(number); }; CreditCard.prototype = { isValid: function() { var total = 0; for (var i=this.number.length-1; i >= 0; i--) { var n = parseInt(this.number[i]); if ((i+this.number.length) % 2 == 0) { n = n*2 > 9 ? n*2 - 9 : n*2; } total += n; }; return total % 10 == 0; } }; console.log( (new CreditCard('4111 1111-11111111')).isValid() ); // true console.log( (new CreditCard('4111111111111121')).isValid() ); // false
  • 17. But this would be much more Ruby-like! class CreditCard cleanNumber = (number) -> number.replace /[- ]/g, "" constructor: (number) -> @number = cleanNumber number isValid: (number) -> total = 0 for i in [0...@number.length] n = +@number[i] if (i+@number.length) % 2 == 0 n = if n*2 > 9 then n*2 - 9 else n*2 total += n total % 10 == 0 console.log (new CreditCard '4111 1111-11111111').isValid() # true console.log (new CreditCard '4111111111111121').isValid() # false
  • 20. Sample CoffeeScript # Assignment: # Splats: number = 42 race = (winner, runners...) -> opposite = true print winner, runners # Conditions: # Existence: number = -42 if opposite alert "I knew it!" if elvis? # Functions: # Array comprehensions: square = (x) -> x * x cubes = (math.cube num for num in list) # Arrays: list = [1, 2, 3, 4, 5] # Objects: math = root: Math.sqrt square: square cube: (x) -> x * square x
  • 21. Functions square = (x) -> x * x cube = (x) -> square(x) * x fill = (container, liquid = "coffee") -> "Filling the #{container} with #{liquid}..." awardMedals = (first, second, others...) -> gold = first silver = second rest = others contenders = [ "Michael Phelps" "Liu Xiang" "Yao Ming" "Allyson Felix" "Shawn Johnson" ] awardMedals contenders...
  • 22. Objects and Arrays song = ["do", "re", "mi", "fa", "so"] singers = {Jagger: "Rock", Elvis: "Roll"} bitlist = [ 1, 0, 1 0, 0, 1 1, 1, 0 ] kids = brother: name: "Max" age: 11 sister: name: "Ida" age: 9
  • 23. Variable Scope var changeNumbers, inner, outer; outer = 1 outer = 1; changeNumbers = -> changeNumbers = function() { var inner; inner = -1 inner = -1; outer = 10 return outer = 10; inner = changeNumbers() }; inner = changeNumbers();
  • 24. Existential Operator solipsism = true if mind? and not world? speed ?= 75 footprints = yeti ? "bear" zip = lottery.drawWinner?().address?.zipcode
  • 25. Conditionals mood = greatlyImproved if singing if happy and knowsIt clapsHands() chaChaCha() else showIt() date = if friday then sue else jill options or= defaults
  • 26. Loops eat food for food in ['toast', 'cheese', 'wine'] countdown = (num for num in [10..1]) earsOld = max: 10, ida: 9, tim: 11 ages = for child, age of yearsOld child + " is " + age
  • 27. Classes, Inheritance and super class Animal constructor: (@name) -> move: (meters) -> alert @name + " moved " + meters + "m." class Snake extends Animal move: -> alert "Slithering..." super 5 class Horse extends Animal move: -> alert "Galloping..." super 45 sam = new Snake "Sammy the Python" tom = new Horse "Tommy the Palomino" sam.move() tom.move()
  • 28. Function Binding Account = (customer, cart) -> @customer = customer @cart = cart $('.shopping_cart').bind 'click', (event) => @customer.purchase @cart
  • 29. And many other nice features...
  • 30. How to install? brew install node # or install node.js otherwise curl http://npmjs.org/install.sh | sh npm install -g coffee-script
  • 32. Dynamic single page application
  • 34. Identifying components AppView TodoView TodoView TodoView
  • 35. Identifying components AppView keypress event click event TodoView dblclick event TodoView TodoView click event
  • 36. Browser-side Views and Models AppView TodoList keypress event click event TodoView Todo dblclick event TodoView Todo TodoView Todo click event
  • 37. Browser-side Views and Models AppView new, fetch TodoList keypress event click event TodoView create, save Todo dblclick event TodoView Todo TodoView Todo click event
  • 38. Browser-side Views and Models AppView refresh, add TodoList keypress event click event TodoView Todo dblclick event TodoViewchange, destroy Todo TodoView Todo click event
  • 39. Browser-side Models and RESTful resources Browser Rails GET TodoList TodosController POST index Todo PUT show Todo create DELETE update Todo destroy JSON
  • 41. Organize CoffeeScript and JavaScript Code using http://github.com/Sutto/barista
  • 42. application.coffee # main namespace window.TodoApp = {}
  • 43. Todo model class TodoApp.Todo extends Backbone.Model # If you don't provide a todo, one will be provided for you. EMPTY: "empty todo..." # Ensure that each todo created has `content`. initialize: -> unless @get "content" @set content: @EMPTY # Toggle the `done` state of this todo item. toggle: -> @save done: not @get "done"
  • 44. TodoList collection class TodoApp.TodoList extends Backbone.Collection # Reference to this collection's model. model: TodoApp.Todo # Save all of the todo items under the `"todos"` namespace. url: '/todos' # Filter down the list of all todo items that are finished. done: -> @filter (todo) -> todo.get 'done' # Filter down the list to only todo items that are still not finished. remaining: -> @without this.done()... # We keep the Todos in sequential order, despite being saved by unordered # GUID in the database. This generates the next order number for new items. nextOrder: -> if @length then @last().get('order') + 1 else 1 # Todos are sorted by their original insertion order. comparator: (todo) -> todo.get 'order'
  • 45. Todo item view class TodoApp.TodoView extends Backbone.View # ... is a list tag. tagName: "li" # Cache the template function for a single item. template: TodoApp.template '#item-template' # The DOM events specific to an item. events: "click .check" : "toggleDone" "dblclick div.todo-content" : "edit" "click span.todo-destroy" : "destroy" "keypress .todo-input" : "updateOnEnter" # The TodoView listens for changes to its model, re-rendering. Since there's # a one-to-one correspondence between a **Todo** and a **TodoView** in this # app, we set a direct reference on the model for convenience. initialize: -> _.bindAll this, 'render', 'close' @model.bind 'change', @render @model.bind 'destroy', => @remove() # Re-render the contents of the todo item. render: -> $(@el).html @template @model.toJSON() @setContent() this
  • 46. # Re-render the contents of the todo item. render: -> $(@el).html @template @model.toJSON() @setContent() Todo item view this # To avoid XSS (not that it would be harmful in this particular app), # we use `jQuery.text` to set the contents of the todo item. setContent: -> content = @model.get 'content' @$('.todo-content').text content @input = @$('.todo-input') @input.blur @close @input.val content # Toggle the `"done"` state of the model. toggleDone: -> @model.toggle() # Switch this view into `"editing"` mode, displaying the input field. edit: -> $(@el).addClass "editing" @input.focus() # Close the `"editing"` mode, saving changes to the todo. close: -> @model.save content: @input.val() $(@el).removeClass "editing" # If you hit `enter`, we're through editing the item. updateOnEnter: (e) -> @close() if e.keyCode == 13 # Destroy the model. destroy: -> @model.destroy()
  • 47. Application view class TodoApp.AppView extends Backbone.View # Instead of generating a new element, bind to the existing skeleton of # the App already present in the HTML. el: "#todoapp" # Our template for the line of statistics at the bottom of the app. statsTemplate: TodoApp.template '#stats-template' # Delegated events for creating new items, and clearing completed ones. events: "keypress #new-todo" : "createOnEnter" "keyup #new-todo" : "showTooltip" "click .todo-clear a" : "clearCompleted" # At initialization we bind to the relevant events on the `Todos` # collection, when items are added or changed. Kick things off by # loading any preexisting todos that might be saved. initialize: -> _.bindAll this, 'addOne', 'addAll', 'renderStats' @input = @$("#new-todo") @collection.bind 'add', @addOne @collection.bind 'refresh', @addAll @collection.bind 'all', @renderStats @collection.fetch()
  • 48. @collection.bind 'add', @addOne @collection.bind 'refresh', @addAll @collection.bind 'all', @renderStats Application view @collection.fetch() # Re-rendering the App just means refreshing the statistics -- the rest # of the app doesn't change. renderStats: -> @$('#todo-stats').html @statsTemplate total: @collection.length done: @collection.done().length remaining: @collection.remaining().length # Add a single todo item to the list by creating a view for it, and # appending its element to the `<ul>`. addOne: (todo) -> view = new TodoApp.TodoView model: todo @$("#todo-list").append view.render().el # Add all items in the collection at once. addAll: -> @collection.each @addOne # Generate the attributes for a new Todo item. newAttributes: -> content: @input.val() order: @collection.nextOrder() done: false # If you hit return in the main input field, create new **Todo** model, # persisting it to server. createOnEnter: (e) -> if e.keyCode == 13 @collection.create @newAttributes() @input.val ''
  • 49. view = new TodoApp.TodoView model: todo @$("#todo-list").append view.render().el # Add all items in the collection at once. Application view addAll: -> @collection.each @addOne # Generate the attributes for a new Todo item. newAttributes: -> content: @input.val() order: @collection.nextOrder() done: false # If you hit return in the main input field, create new **Todo** model, # persisting it to server. createOnEnter: (e) -> if e.keyCode == 13 @collection.create @newAttributes() @input.val '' # Clear all done todo items, destroying their views and models. clearCompleted: -> todo.destroy() for todo in @collection.done() false # Lazily show the tooltip that tells you to press `enter` to save # a new todo item, after one second. showTooltip: (e) -> tooltip = @$(".ui-tooltip-top") val = @input.val() tooltip.fadeOut() clearTimeout @tooltipTimeout if @tooltipTimeout unless val == '' or val == @input.attr 'placeholder' @tooltipTimeout = _.delay -> tooltip.show().fadeIn() , 1000
  • 50. #todoapp index.html.haml .title %h1 Todos .content #create-todo %input#new-todo{:placeholder => "What needs to be done?", :type => "text"}/ %span.ui-tooltip-top{:style => "display:none;"} Press Enter to save this task #todos %ul#todo-list #todo-stats %ul#instructions %li Double-click to edit a todo. :coffeescript $ -> TodoApp.appView = new TodoApp.AppView collection: new TodoApp.TodoList %script#item-template{:type => "text/html"} .todo{:class => "{{#done}}done{{/done}}"} .display %input{:class => "check", :type => "checkbox", :"{{#done}}checked{{/done}}" => true} .todo-content %span.todo-destroy .edit %input.todo-input{:type => "text", :value => ""} %script#stats-template{:type => "text/html"} {{#if total}} %span.todo-count
  • 51. %input#new-todo{:placeholder => "What needs to be done?", :type => "text"}/ %span.ui-tooltip-top{:style => "display:none;"} Press Enter to save this task #todos %ul#todo-list index.html.haml #todo-stats %ul#instructions %li Double-click to edit a todo. :coffeescript $ -> TodoApp.appView = new TodoApp.AppView collection: new TodoApp.TodoList %script#item-template{:type => "text/html"} .todo{:class => "{{#done}}done{{/done}}"} .display %input{:class => "check", :type => "checkbox", :"{{#done}}checked{{/done}}" => true} .todo-content %span.todo-destroy .edit %input.todo-input{:type => "text", :value => ""} %script#stats-template{:type => "text/html"} {{#if total}} %span.todo-count %span.number {{remaining}} %span.word {{pluralize remaining "item"}} left. {{/if}} {{#if done}} %span.todo-clear %a{:href => "#"} Clear %span.number-done {{done}} completed %span.word-done {{pluralize done "item"}} {{/if}}
  • 52. One more thing: Backbone Controllers Routers class Workspace extends Backbone.Controller Router routes: "help" : "help" #help "search/:query" : "search" #search/kiwis "search/:query/p:page": "search" #search/kiwis/p7 help: -> ... search: (query, page) -> ...
  • 53. How do you test it?
  • 55. Together with all other tests
  • 56. Testing Todo model describe "Todo", -> todo = null ajaxCall = (param) -> jQuery.ajax.mostRecentCall.args[0][param] beforeEach -> todo = new TodoApp.Todo todos = new TodoApp.TodoList [todo] it "should initialize with empty content", -> expect(todo.get "content").toEqual "empty todo..." it "should initialize as not done", -> expect(todo.get "done").toBeFalsy() it "should save after toggle", -> spyOn jQuery, "ajax" todo.toggle() expect(ajaxCall "url").toEqual "/todos" expect(todo.get "done").toBeTruthy()
  • 57. and TodoList collection describe "TodoList", -> attributes = [ content: "First" done: true , content: "Second" ] todos = null beforeEach -> todos = new TodoApp.TodoList attributes it "should return done todos", -> expect(_.invoke todos.done(), "toJSON").toEqual [attributes[0]] it "should return remaining todos", -> expect(_.invoke todos.remaining(), "toJSON").toEqual [attributes[1]]
  • 59. application.js.coffee using Sprockets #= require jquery #= require underscore #= require backbone #= require handlebars #= require ./todo_app #= require_tree ./models #= require ./views/helpers #= require_tree ./views
  • 60. Watch RailsConf DHH keynote http://en.oreilly.com/rails2011/public/schedule/detail/19068
  • 61. References http://jashkenas.github.com/coffee-script/ http://documentcloud.github.com/backbone/ http://pivotal.github.com/jasmine/ https://github.com/rsim/backbone_coffeescript_demo