SlideShare ist ein Scribd-Unternehmen logo
1 von 92
Modern Application
Foundations: Underscore
and Twitter Bootstrap
Howard M. Lewis Ship
TWD Consulting
hlship@gmail.com
@hlship
                       © 2012 Howard M. Lewis Ship
Rich Client
Challenges                         Make It Work


              Make It Work in IE

                                           Make It Right




                          Make It Pretty
Underscore
  Make it work, right
Bootstrap
  Make it pretty
Bootstrap.js + jQuery
  Make it interact right
  Make it work right under IE
_
❝Underscore is a utility-belt
    library for JavaScript 

without extending any of the
 built-in JavaScript objects.
 It's the tie to go along with
        jQuery's tux, and
         Backbone.js's
          suspenders.❞
Functional Programming
Is JavaScript a Functional Language?




                    © 2008 Hans Splinter – http://www.flickr.com/photos/67196253@N00/2941655917/
underscore.js 1.3.1

 Great documentation
 34 Kb / < 4 Kb
 60+ built-in functions
 Uses native support where available
 Extensible
http://jsconsole.com/
Caution: CoffeeScript
Caution: CoffeeScript
 CoffeeScript
 ➠ ❝
 a little language that compiles into JavaScript❞
 Concise and readable
 Optional parenthesis
 Implicit returns
 Concise function deïŹnitions
 Great ïŹt with Underscore!
CoffeeScript: Invoking Functions
$(".x-cancel").tooltip "hide"             $(".x-cancel").tooltip("hide")




collection.add new Quiz(originalModel),
  at: 0

                                collection.add(new Quiz(originalModel), {
                                  at: 0
                                });
CoffeeScript: DeïŹning Functions
                                         function (x, y) {
(x,y) -> x * y                             return x * y;
                                         }



                           function isBlank(str) {
isBlank = (str) ->
                             return _.isNull(str) ||
  _.isNull(str) or
                                    _.isUndefined(str) ||
  _.isUndefined(str) or
                                    str.trim() === "";
  str.trim() is ""
                           }




_.map list, (x) -> 2 * x   _.map(list, function(x) {
                             return 2 * x;
                           });
Simple Object / Value
Utilities
Useful Predicates
Predicate     Description

isEmpty       Is the value null, undeïŹned, the empty string, an empty object, or an empty array?

isElement     Is the value a DOM element?

isArray       Is the value an array (but not arguments)?

isArguments   Is the value the special arguments object?

isFunction    Is the value a function?

isString      Is the value a string?

isNumber      Is the value a number

isBoolean     Is the value a boolean?

isDate        Is the value a JavaScript Date?

isRegExp      Is the value a Regular Expression

isNaN         Is the value NaN (note: returns false for undeïŹned)

isNull        Is the value null (but not undeïŹned)

isUndeïŹned    Is the value speciïŹcally undeïŹned
_.isEmpty
 _.isEmpty   null ➠ true
 _.isEmpty   undefined ➠ true
 _.isEmpty   [] ➠ true
 _.isEmpty   "" ➠ true
 _.isEmpty   {} ➠ true
 _.isEmpty   [1] ➠ false

 _.isEmpty name:null ➠ false

 me = name:"Howard"
 delete me.name
 _.isEmpty me ➠ true
_.keys, _.values, _.has
 me =
   firstName: "Howard"
   lastName: "Lewis Ship"

 _.keys me ➠ ["firstName", "lastName"]

 _.values me ➠ ["Howard", "Lewis Ship"]
                  Just keys for this object, not inherited
                  Not sorted



 _.has me, "firstName" ➠ true
 _.has me, "middleName" ➠ false
_.functions


_.functions me ➠ []

_.functions _ ➠ ["after", "all", "any",
"bind", "bindAll", "chain", 

                                   Sorted
_.extend and _.defaults
 shape = type: "circle"
 ➠ {"type": "circle"}                       extend: last value wins

 _.extend shape, { radius: 20 }, { type: "spiral" }
 ➠ {"radius": 20, "type": "spiral"}

    ModiïŹes and returns ïŹrst parameter



 shape = type: "circle"
                                         defaults: ïŹrst non-null value wins
 ➠ {"type": "circle"}

 _.defaults shape, { radius: 20 }, { type: "spiral" }
 ➠ {"radius": 20, "type": "circle"}
Collection Functions
_.each(list, iterator, [context])
                            this set to context before invoking iterator




_.each ["alpha", "bravo", "charlie"],
  (value, index) ->
    console.log "#{value} is at #{index}"
alpha is at 0
bravo is at 1             More CoffeeScript goodness
charlie is at 2
➠ undefined

Alias: _.forEach
iterator function
 Callback function passed to Underscore functions
 Iterating arrays
   value
   index
   array being iterated
 Iterating objects
   value
   key
   object being iterated
context and this
 this is a side-effect of method invocation:

 anObject.aMethod() ➠     var fn = anObject["aMethod"];
                          fn.call(anObject)

                              Sets this for new stack frame


 DOM and JQuery manipulate this
 ➠ Usually the DOM element that triggered event
 this not relevant to HOFs
   Functions, parameters, local scope
 Optional context parameter on many _ functions
_.each(object, iterator, [context])


_.each me, (value, key) ->
  console.log "Value for #{key} is #{value}"
Value for firstName is Howard
Value for lastName is Lewis Ship
➠ undefined
_.each(list) and undeïŹned

sparse = []
sparse[10] = "ten"
sparse[20] = "twenty"

_.each sparse, (value, index) ->
    console.log "#{value} is at #{index}"
"ten is at 10"
"twenty is at 20"
➠ undefined
_.map(list, iterator, [context])
 _.map [1, 2, 3], (value) -> 2 * value
 ➠[2, 4, 6]

 _.map [1, 2, 3, 40, 500],
   (value, index) -> value * index
 ➠[0, 2, 6, 120, 2000]

 _.map me,(value, key) ->
    "Value for #{key} is #{value}"
 ➠ ["Value for firstName is Howard",
     "Value for lastName is Lewis Ship"]


Alias: _.collect
_.reduce(list, iterator, memo, [context])
                                       aka "accumulator"


_.reduce ["Howard", "Lewis Ship", "TWD Consulting"],
  (memo, name) -> memo + name.length
  0
➠ 30

"HowardLewis ShipTWD Consulting".length
➠ 30
                                      A side effect!
_.reduce me,
  (memo, value, key) -> memo[value] = key ; return memo
  {}
➠ {"Howard": "firstName", "Lewis Ship": "lastName"}




 Aliases: _.inject, _.foldl
_.ïŹnd(list, iterator, [context])
_.find [1, 2, 3, 4, 5, 6],
  (x) -> x % 2 is 0
➠ 2

hand = [
  { value:3,   suit:   "hearts" }
  { value:2,   suit:   "spades" }
  { value:7,   suit:   "spades" }
  { value:8,   suit:   "diamonds" }
]
➠ 


_.find hand, (card) -> 8 + card.value is 15
➠ {"suit": "spades", "value": 7}

_.find hand, (card) -> 27 + card.value is 31
➠ undefined




Alias: _.detect
                                      © 2009 scribbletaylor – http://www.flickr.com/photos/64958688@N00/3604756480/
_.all(list, iterator, [context])



_.all hand, (card) -> card.value >= 2
➠ true

_.all hand, (card) -> card.suit is "hearts"
➠ false




Alias: _.every
_.any(list, [iterator], [context])


 _.any hand, (card) -> card.suit is "clubs"
 ➠ false

 _.any hand, (card) -> card.suit is "diamonds"
 ➠ true

 _.any []        Default iterator is _.identity
 ➠ false

 _.any [false]
 ➠ false

 _.any [true]
 ➠ true
Alias: _.every
_.ïŹlter(list, iterator, [context])


_.filter hand, (card) -> card.suit is "spades"
➠ [{"suit": "spades", "value": 2},
   {"suit": "spades", "value": 7}]

_.reject hand, (card) -> card.suit is "spades"
➠ [{"suit": "hearts", "value": 3},
   {"suit": "diamonds", "value": 8}]



  Alias: _.select
_.groupBy(list, iterator)

   _.groupBy hand, (card) -> card.suit
   ➠ {"diamonds": [{"suit": "diamonds", "value": 8}],
      "hearts": [{"suit": "hearts", "value": 3}],
      "spades": [{"suit": "spades", "value": 2},
                 {"suit": "spades", "value": 7}]}

   _.groupBy hand, (card) -> card.value
   ➠ {"2": [{"suit": "spades", "value": 2}],
      "3": [{"suit": "hearts", "value": 3}],
      "7": [{"suit": "spades", "value": 7}],
      "8": [{"suit": "diamonds", "value": 8}]}

   _.groupBy hand, "suit"
   ➠ {"diamonds": [{"suit": "diamonds", "value": 8}],
      "hearts": [{"suit": "hearts", "value": 3}],
      "spades": [{"suit": "spades", "value": 2},
                 {"suit": "spades", "value": 7}]}
_.sortBy(list, iterator, [context])

_.sortBy hand, (card) ->
  suitIndex = _.indexOf ["clubs", "diamonds", "hearts", "spades"],
    card.suit
  100 * suitIndex + card.value
➠ [{"suit": "diamonds", "value": 8},
   {"suit": "hearts", "value": 3},
   {"suit": "spades", "value": 2},
   {"suit": "spades", "value": 7}]

_.sortBy hand, "propertyName"
Object propertyName has no method 'call'

_.sortBy ["fred", "wilma", "barney"], _.identity
➠ ["barney", "fred", "wilma"]
                                         (x) -> x
_.max(list, [iterator], [context])

   _.max [-1, 2, 3]
   ➠ 3

   _.max []
   ➠ -Infinity

   _.max hand, (card) -> card.value
   ➠ {"suit": "diamonds", "value": 8}
_.min(list, [iterator], [context])
   _.min [-1, 2, 3]
   ➠ -1

   _.min []
   ➠ Infinity

   _.min hand, (card) -> card.value
   ➠ {"suit": "spades", "value": 2}

   _.min ["fred", "wilma", "barney"]
   ➠ NaN
_.include(list, value)

     _.include [1, 2, 3], 2
     ➠ true

     _.include [1, 2, 3], 99
     ➠ false

     _.include [1, 2, 3], "2"
     ➠ false
                     Uses === comparison




Alias: _.contains
_.pluck(list, propertyName)

_.pluck hand, "value"
➠ [3, 2, 7, 8]

_.pluck hand, "suit"
➠ ["hearts", "spades", "spades", "diamonds"]

_.pluck hand, "score"
➠ [undefined, undefined, undefined, undefined]
_.shufïŹ‚e(list)

  _.shuffle hand
  ➠ [{"suit": "spades", "value": 2},
     {"suit": "diamonds", "value": 8},
     {"suit": "hearts", "value": 3},
     {"suit": "spades", "value": 7}]

  _.shuffle null
  ➠ []
Object Oriented Style and
Chaining
_ is a function
                                   Every function on _ is also on
Returns a wrapper object                  wrapper object

    _(hand).pluck "value"
    ➠ [3, 2, 7, 8]
                           Wrapped object passed as ïŹrst parameter

    _(hand).size()
    ➠ 4
Chaining Can Be Ugly

 _.map(_.first(_.sortBy(hand,cardSortValue).reverse(), 2),
       (card) -> "#{card.value} of #{card.suit}")
 ➠ ["8 of diamonds", "7 of spades"]



1.Sort the hand using the cardSortValue function
2.Reverse the result
3.Take the ïŹrst two cards
4.Convert each card to a string
_.chain(object) and _.value(object)


 _.chain(hand)
   .sortBy(cardSortValue)
   .reverse()
   .first(2)                  Each step returns a new wrapped object
   .map((card) -> "#{card.value} of #{card.suit}")
   .value()
 ➠ ["8 of diamonds", "7 of spades"]
Flow of Transformations




© 2008 Manu GĂłmez – http://www.flickr.com/photos/manugomi/2884678938/
_.tap(object, interceptor)

  _.chain(hand)
    .sortBy(cardSortValue)
    .tap(console.log)
    .reverse()
    .first(2)
    .map((card) -> "#{card.value} of #{card.suit}")
    .value()
  [{"suit": "diamonds", "value": 8},
   {"suit": "spades", "value": 7},
   {"suit": "hearts", "value": 3},
   {"suit": "spades", "value": 2}]
  ➠ ["8 of diamonds", "7 of spades"]
Array prototype methods

                        Extra methods on wrapper not on _


           _.([1, 2]).concat "three"
           ➠ [1, 2, "three"]
 concat                   shift
 join                     slice
 pop                      sort
 push                     splice
 reverse                  unshift
Array Functions
Name                                Description                                                    Aliases

ïŹrst(array)                         Return ïŹrst element in array, as single value                  head


ïŹrst(array, n)                      Return ïŹrst elements of array as list                          head


initial(array, [n])                 Return everything but last n (default = 1) elements of array


last(array)                         Return last element in array, as single value


last(array, n)                      Return last n (default = 1) elements of array


rest(array, [n])                    Return array from index n (default = 1) on                     tail


indexOf(array, value, [isSorted])   Index of value inside array, or -1


lastIndexOf(array, value)           Last index of value inside array, or -1


                                    Returns copy with all falsey (null, false, 0, undeïŹned, NaN)
compact(array)
                                    removed


ïŹ‚atten(array, [shallow])            Collapses nested arrays down to a single array
Set Operations

    _.without [5, 4, 3, 2, 1], 4, 2
    ➠ [5, 3, 1]

    _.difference [5, 4, 4, 3, 3, 2, 2, 1],
      [1, 2],
      [4, 10, 22]
    ➠ [5, 3, 3]

    _.union [3, 2, 1, 3, 4, 5], [101, 1], [3, 4], [500]
    ➠ [3, 2, 1, 4, 5, 101, 500]

    _.intersection [5, 4, 4, 3, 3, 2, 2, 1],
      [1, 2, 3, 4, 5],
      [4, 10, 22, 3]
    ➠ [4, 3]
_.uniq(array, [isSorted], [iterator])


   _.uniq [1, 30, 50, 40, 30, 1]
   ➠ [1, 30, 50, 40]

   _.uniq [1, 30, 50, 40, 30, 1], false, (x) -> "#{x}".length
   ➠ [1, 30]
_.range([start], stop, [step])
     _.range 5
     ➠ [0, 1, 2, 3, 4]

     _.range 3, 5
     ➠ [3, 4]

     _.range 1, 20, 3
     ➠ [1, 4, 7, 10, 13, 16, 19]

     _.range 1, 20, -3
     ➠ []

     _.range 20, 1, -4
     ➠ [20, 16, 12, 8, 4]
_.zip(*arrays)

_.zip(["a", "b", "c"],
      [1, 2, 3],
      ["alpha", "bravo", "charlie", "delta"])
➠ [["a", 1, "alpha"],
   ["b", 2, "bravo"],
   ["c", 3, "charlie"],
   [undefined, undefined, "delta"]]
Higher Order Underscore
_.bind(fn, context, [*args])

greet = (greeting) -> "#{greeting}: #{this.name}"

greet("Hello, unbound this")
➠ "Hello, unbound this: "

bgreet = _.bind greet, { name: "Howard" }

bgreet "Hello"
➠ "Hello: Howard"

fgreet = _.bind greet, { name: "Mr. Lewis Ship" }, "Salutations"

fgreet()
➠ "Salutations: Mr. Lewis Ship"
_.defer(function)
     do invokes the function with no parameters


    do ->
      _.defer -> console.log "deferred"
      console.log "immediate"
    immediate
    ➠ undefined
    deferred
_.delay(fn, wait, [*arguments])


       log = _.bind console.log, console
       do ->
         _.delay log, 1000, "delayed"
         log "immediate"
       immediate
       ➠ undefined
       delayed

           About 1 second later
_.wrap(function, interceptor)
   timerInterceptor = (wrapped, args...) ->
     start = Date.now()
     result = wrapped(args...)
     elapsed = Date.now() - start
     console.log "Function call took #{elapsed} ms."
     return result

   fib = (x) ->
     switch x
       when 0 then 0
       when 1 then 1
       else fib(x - 1) + fib(x - 2)

   tfib = _.wrap fib, timerInterceptor

   tfib 30
   Function call took 23 ms.
   ➠ 832040

   tfib 40
   Function call took 2674 ms.
   ➠ 102334155
More Functions on Functions
 bindAll
 memoize
 throttle
 debounce
 once
 after
 compose
Underscore Utilities
Name                          Description


identity(value)               Returns its argument, a default iterator



times(n, iterator)            Invoke its iterator n times, passing the index to it




uniqueId([preïŹx])             Creates a unique id, good for labelling DOM elements




escape(string)                Converts & < > " ' / in string to HTML entities (&amp; &lt; 
 )




template(string, [context])   Converts the string into a template function, using a <% 
 %> syntax




mixin(object)                 Adds new functions to _ and to the OOP wrapper, for use with _.chain()
Twitter Bootstrap
Quizzical Empire
Paperwork
Twitter Bootstrap	

 Built by and for nerds
 All skill levels
 Desktop, tablets 
 even smartphones and IE
 Custom jQuery Plugins
 Based on LESS for customizability
Minimal Setup
  <!DOCTYPE html>
  <html>
  <head>
    <link rel="stylesheet" href="/bootstrap/css/bootstrap.css">
    <script src="/bootstrap/js/bootstrap.js"></script>
  </head>
  <body>
    

  </body>
  </html>
12 Column Grid

  1   1       1       1   1   1        1   1       1       1       1   1


          4                       4                            4


          4                                    8

                  6                                    6

                                  12

                              940px
12 Column Grid
<div class="container">
  <div class="row">
    <div class="span2">Span 2</div>
    <div class="span8">Span 8</div>
    <div class="span2">Span 2</div>
  </div>
  <div class="row">
    <div class="span6 offset1">Span 6 / Offset 1</div>
    <div class="span5">Span 5</div>
  </div>
</div>
12 Column Grid – Jade
.container
  .row
    .span2 Span 2
    .span8 Span 8
    .span2 Span 2
  .row
    .span6.offset1 Span 6 / Offset 1
    .span5 Span 5
Nested Rows
   .container
     .row
       .span2 Span 2
       .span8 Span 8 - Level 1        Add up to
          .row                        container
            .span4 Span 4 - Level 2     span

            .span4 Span 4 - Level 2
       .span2 Span 2
Fluid Layout
   .container-fluid
     .row-fluid
       .span2 Span 2
       .span8 Span 8 - Level 1
         .row-fluid                  Add up to
                                        12
           .span6 Span 6 - Level 2
           .span6 Span 6 - Level 2
       .span2 Span 2
General Bootstrap Approach


 Basic, semantic, markup
 Reasonable default look
 Simple CSS classes: "row", "span3", "offset1"
 Additiive: more CSS classes to tune
Tables
         .container
           table.span12
             caption Bare Table
             thead:tr
               th.span8 Column A
               th Column B
               th.span2 Column C
             tbody
               each row in [1, 2, 3, 4]
                 tr
                    each cell in ["A", "B", "C"]
                      td Cell #{row}-#{cell}
.table
.table.table-bordered
.table.table-bordered.table-condensed.table-striped
Buttons




‱Use with:
  ‱ <a>
  ‱ <button>
  ‱ <input type="submit">
  ‱ <input type="button">
  ‱ <input type="reset">
Glyphicons




         <i class="icon-search"/>
Bootstrap Components
.container

Tab     ul.nav.nav-tabs
          li.active: a(href="#moe", data-toggle="tab") Moe
          li: a(href="#larry", data-toggle="tab") Larry
          li: a(href="#curly", data-toggle="tab") Curly
        .tab-content
          .tab-pane.active#moe
            h1 Moe Howard
            img(src="images/moe.jpg")
          .tab-pane#larry
            h1 Larry Fine
            img(src="images/larry.jpg")
          .tab-pane#curly
            h1 Curly Howard
            img(src="images/curly.jpg")
                 Text




                    Requires jQuery and Twitter Bootstrap.js
Dynamic Tabs
   ex7.jade
   .container
     ul.nav.nav-tabs
     .tab-content
   != js("ex7")




   ex7.coffee
   jQuery ($) ->
     tabs = $("ul.nav.nav-tabs")
     tabContent = $(".tab-content")

     _.each ["Moe Howard", "Larry Fine", "Curly Howard"],
       (name) ->
       


     tabs.find("li:first").addClass "active"
     tabContent.find(".tab-pane:first").addClass "active in"
Dynamic Tabs
   _.each ["Moe Howard", "Larry Fine", "Curly Howard"],
     (name) ->
       firstName = name.split(' ')[0]
       uid = _.uniqueId "tab"

       tab = $("""
         <li>
            <a href="##{uid}" data-toggle="tab">
              #{firstName}
            </a>
         </li>
       """)
       content = $("""
         <div class="tab-pane fade" id="#{uid}">
            <h1>#{name}</h1>
            <img src="images/#{firstName.toLowerCase()}.jpg">
         </div>
       """)

       content.appendTo tabContent
       tab.appendTo tabs
Modal Dialogs
Modal Dialogs
  ex8.jade
  .container
    button#danger.btn.btn-danger(data-toggle="modal"
      data-target=".x-danger-alert") Do Not Press
  .modal.x-danger-alert.fade
    .modal-header
      a.close(data-dismiss="modal") &times;
      h3 Why did you press it?
    .modal-body
      p You pressed the button marked
        strong Do Not Press
        .
    .modal-footer
      button.btn.btn-warning(data-dismiss="modal") Continue
      button.btn(data-dismiss="modal") Cancel
Alerts
   ex8.coffee
   jQuery ($) ->
     $(".x-danger-alert .btn-warning").on "click", ->
       alert = $("""
         <div class="alert fade in">
            <a class="close" data-dismiss="alert">&times;</a>
            <strong>Well, you pressed it!</strong>
         </div>
       """)
       alert.prependTo $(".container")
Other Plugins


     Popover                  Tooltip

                And more:
                  Scrollspy
     Dropdown     Button
                  Collapse
                  Carousel
                  Typeahead
Wrap Up
Underscore

  Effective, functional JavaScript

Bootstrap

  Sharp L&F out of the box

  Very customizable

Bootstrap JS

  Lots of UI pizzaz, effortlessly

CoffeeScript

  Concise, readable JavaScript
http://howardlewisship.com
Q&A

Weitere Àhnliche Inhalte

Was ist angesagt?

JavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptJavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptLaurence Svekis ✔
 
From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰
From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰
From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰Night Sailer
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentationguestcf600a
 
Super Advanced Python –act1
Super Advanced Python –act1Super Advanced Python –act1
Super Advanced Python –act1Ke Wei Louis
 
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingYury Chemerkin
 
Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Leonardo Soto
 
Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is AwesomeAstrails
 
Embedding a language into string interpolator
Embedding a language into string interpolatorEmbedding a language into string interpolator
Embedding a language into string interpolatorMichael Limansky
 
Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)Leonardo Soto
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a tryEugene Zharkov
 
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Topological indices (t is) of the graphs  to seek qsar models of proteins com...Topological indices (t is) of the graphs  to seek qsar models of proteins com...
Topological indices (t is) of the graphs to seek qsar models of proteins com...Jitendra Kumar Gupta
 
The Ring programming language version 1.3 book - Part 34 of 88
The Ring programming language version 1.3 book - Part 34 of 88The Ring programming language version 1.3 book - Part 34 of 88
The Ring programming language version 1.3 book - Part 34 of 88Mahmoud Samir Fayed
 
Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]
Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]
Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]MongoDB
 
NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•
NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•
NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•Tomohiro Nishimura
 
Scala best practices
Scala best practicesScala best practices
Scala best practicesAlexander Zaidel
 

Was ist angesagt? (18)

JavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScriptJavaScript Objects and OOP Programming with JavaScript
JavaScript Objects and OOP Programming with JavaScript
 
From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰
From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰
From mysql to MongoDBMongoDB2011挗äșŹäș€æ”äŒšïŒ‰
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentation
 
Super Advanced Python –act1
Super Advanced Python –act1Super Advanced Python –act1
Super Advanced Python –act1
 
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
 
Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)Jython: Python para la plataforma Java (EL2009)
Jython: Python para la plataforma Java (EL2009)
 
Functional es6
Functional es6Functional es6
Functional es6
 
Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is Awesome
 
Embedding a language into string interpolator
Embedding a language into string interpolatorEmbedding a language into string interpolator
Embedding a language into string interpolator
 
Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)Jython: Python para la plataforma Java (JRSL 09)
Jython: Python para la plataforma Java (JRSL 09)
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Topological indices (t is) of the graphs  to seek qsar models of proteins com...Topological indices (t is) of the graphs  to seek qsar models of proteins com...
Topological indices (t is) of the graphs to seek qsar models of proteins com...
 
The Ring programming language version 1.3 book - Part 34 of 88
The Ring programming language version 1.3 book - Part 34 of 88The Ring programming language version 1.3 book - Part 34 of 88
The Ring programming language version 1.3 book - Part 34 of 88
 
Swift tips and tricks
Swift tips and tricksSwift tips and tricks
Swift tips and tricks
 
Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]
Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]
Aggregation Pipeline Power++: MongoDB 4.2 파읎프 띌읞 ìżŒëŠŹ, 업데읎튞 및 ê”ŹìȮ화된 ë·° 소개 [MongoDB]
 
NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•
NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•
NoSQL を Ruby ă§ćźŸè·”ă™ă‚‹ăŸă‚ăź n 怋ぼæ–čæł•
 
Python speleology
Python speleologyPython speleology
Python speleology
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 

Ähnlich wie Modern Application Foundations: Underscore and Twitter Bootstrap

Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kirill Rozov
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
 
Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”
Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”
Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”ì§„ì„± 였
 
Erlang for data ops
Erlang for data opsErlang for data ops
Erlang for data opsmnacos
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonUC San Diego
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Paige Bailey
 
Coscup2021-rust-toturial
Coscup2021-rust-toturialCoscup2021-rust-toturial
Coscup2021-rust-toturialWayne Tsai
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 
ì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala Language
ì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala Languageì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala Language
ì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala LanguageAshal aka JOKER
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)MongoSF
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05cKaz Yoshikawa
 
Javascript
JavascriptJavascript
JavascriptVlad Ifrim
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional SwiftJason Larsen
 
High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scaladjspiewak
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 

Ähnlich wie Modern Application Foundations: Underscore and Twitter Bootstrap (20)

Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2Kotlin Basics - Apalon Kotlin Sprint Part 2
Kotlin Basics - Apalon Kotlin Sprint Part 2
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”
Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”
Swift 험ᄉᅟ ᄏᅄᄅᅔᆌ á„‰á…Ąá„‹á…­á†Œá„’á…Ąá„€á…”
 
Erlang for data ops
Erlang for data opsErlang for data ops
Erlang for data ops
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!
 
Coscup2021-rust-toturial
Coscup2021-rust-toturialCoscup2021-rust-toturial
Coscup2021-rust-toturial
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
ì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala Language
ì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala Languageì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala Language
ì—Źìžê°œë°œìžëȘšìž„í„° 6ìŁŒë…„ 개발 ì„žëŻžë‚˜ - Scala Language
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
ddd+scala
ddd+scaladdd+scala
ddd+scala
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
 
Javascript
JavascriptJavascript
Javascript
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
 
High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 

Mehr von Howard Lewis Ship

Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEBHoward Lewis Ship
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestHoward Lewis Ship
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserHoward Lewis Ship
 
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHave Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHoward Lewis Ship
 
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)Howard Lewis Ship
 
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd PerspectiveArduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd PerspectiveHoward Lewis Ship
 
Practical Clojure Programming
Practical Clojure ProgrammingPractical Clojure Programming
Practical Clojure ProgrammingHoward Lewis Ship
 
Clojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingClojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingHoward Lewis Ship
 
Tapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting EaseTapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting EaseHoward Lewis Ship
 
Brew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoBrew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoHoward Lewis Ship
 
Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Howard Lewis Ship
 
Tapestry: State of the Union
Tapestry: State of the UnionTapestry: State of the Union
Tapestry: State of the UnionHoward Lewis Ship
 
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Howard Lewis Ship
 

Mehr von Howard Lewis Ship (17)

Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To Test
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for JavaHave Your Cake and Eat It Too: Meta-Programming Techniques for Java
Have Your Cake and Eat It Too: Meta-Programming Techniques for Java
 
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
Clojure: Towards The Essence Of Programming (What's Next? Conference, May 2011)
 
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd PerspectiveArduino: Open Source Hardware Hacking from the Software Nerd Perspective
Arduino: Open Source Hardware Hacking from the Software Nerd Perspective
 
Practical Clojure Programming
Practical Clojure ProgrammingPractical Clojure Programming
Practical Clojure Programming
 
Clojure: Towards The Essence of Programming
Clojure: Towards The Essence of ProgrammingClojure: Towards The Essence of Programming
Clojure: Towards The Essence of Programming
 
Codemash-Clojure.pdf
Codemash-Clojure.pdfCodemash-Clojure.pdf
Codemash-Clojure.pdf
 
Codemash-Tapestry.pdf
Codemash-Tapestry.pdfCodemash-Tapestry.pdf
Codemash-Tapestry.pdf
 
Tapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting EaseTapestry 5: Java Power, Scripting Ease
Tapestry 5: Java Power, Scripting Ease
 
Brew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoBrew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with Cappuccino
 
Clojure Deep Dive
Clojure Deep DiveClojure Deep Dive
Clojure Deep Dive
 
Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)Clojure: Functional Concurrency for the JVM (presented at OSCON)
Clojure: Functional Concurrency for the JVM (presented at OSCON)
 
Cascade
CascadeCascade
Cascade
 
Tapestry: State of the Union
Tapestry: State of the UnionTapestry: State of the Union
Tapestry: State of the Union
 
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
Clojure: Functional Concurrency for the JVM (presented at Open Source Bridge)
 

KĂŒrzlich hochgeladen

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 

KĂŒrzlich hochgeladen (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 

Modern Application Foundations: Underscore and Twitter Bootstrap

  • 1. Modern Application Foundations: Underscore and Twitter Bootstrap Howard M. Lewis Ship TWD Consulting hlship@gmail.com @hlship © 2012 Howard M. Lewis Ship
  • 2. Rich Client Challenges Make It Work Make It Work in IE Make It Right Make It Pretty
  • 3. Underscore Make it work, right Bootstrap Make it pretty Bootstrap.js + jQuery Make it interact right Make it work right under IE
  • 4. _
  • 5. ❝Underscore is a utility-belt library for JavaScript 
 without extending any of the built-in JavaScript objects. It's the tie to go along with jQuery's tux, and Backbone.js's suspenders.❞
  • 7. Is JavaScript a Functional Language? © 2008 Hans Splinter – http://www.flickr.com/photos/67196253@N00/2941655917/
  • 8. underscore.js 1.3.1 Great documentation 34 Kb / < 4 Kb 60+ built-in functions Uses native support where available Extensible
  • 11. Caution: CoffeeScript CoffeeScript ➠ ❝
 a little language that compiles into JavaScript❞ Concise and readable Optional parenthesis Implicit returns Concise function deïŹnitions Great ïŹt with Underscore!
  • 12. CoffeeScript: Invoking Functions $(".x-cancel").tooltip "hide" $(".x-cancel").tooltip("hide") collection.add new Quiz(originalModel), at: 0 collection.add(new Quiz(originalModel), { at: 0 });
  • 13. CoffeeScript: DeïŹning Functions function (x, y) { (x,y) -> x * y return x * y; } function isBlank(str) { isBlank = (str) -> return _.isNull(str) || _.isNull(str) or _.isUndefined(str) || _.isUndefined(str) or str.trim() === ""; str.trim() is "" } _.map list, (x) -> 2 * x _.map(list, function(x) { return 2 * x; });
  • 14.
  • 15. Simple Object / Value Utilities
  • 16. Useful Predicates Predicate Description isEmpty Is the value null, undeïŹned, the empty string, an empty object, or an empty array? isElement Is the value a DOM element? isArray Is the value an array (but not arguments)? isArguments Is the value the special arguments object? isFunction Is the value a function? isString Is the value a string? isNumber Is the value a number isBoolean Is the value a boolean? isDate Is the value a JavaScript Date? isRegExp Is the value a Regular Expression isNaN Is the value NaN (note: returns false for undeïŹned) isNull Is the value null (but not undeïŹned) isUndeïŹned Is the value speciïŹcally undeïŹned
  • 17. _.isEmpty _.isEmpty null ➠ true _.isEmpty undefined ➠ true _.isEmpty [] ➠ true _.isEmpty "" ➠ true _.isEmpty {} ➠ true _.isEmpty [1] ➠ false _.isEmpty name:null ➠ false me = name:"Howard" delete me.name _.isEmpty me ➠ true
  • 18. _.keys, _.values, _.has me = firstName: "Howard" lastName: "Lewis Ship" _.keys me ➠ ["firstName", "lastName"] _.values me ➠ ["Howard", "Lewis Ship"] Just keys for this object, not inherited Not sorted _.has me, "firstName" ➠ true _.has me, "middleName" ➠ false
  • 19. _.functions _.functions me ➠ [] _.functions _ ➠ ["after", "all", "any", "bind", "bindAll", "chain", 
 Sorted
  • 20. _.extend and _.defaults shape = type: "circle" ➠ {"type": "circle"} extend: last value wins _.extend shape, { radius: 20 }, { type: "spiral" } ➠ {"radius": 20, "type": "spiral"} ModiïŹes and returns ïŹrst parameter shape = type: "circle" defaults: ïŹrst non-null value wins ➠ {"type": "circle"} _.defaults shape, { radius: 20 }, { type: "spiral" } ➠ {"radius": 20, "type": "circle"}
  • 22. _.each(list, iterator, [context]) this set to context before invoking iterator _.each ["alpha", "bravo", "charlie"], (value, index) -> console.log "#{value} is at #{index}" alpha is at 0 bravo is at 1 More CoffeeScript goodness charlie is at 2 ➠ undefined Alias: _.forEach
  • 23. iterator function Callback function passed to Underscore functions Iterating arrays value index array being iterated Iterating objects value key object being iterated
  • 24. context and this this is a side-effect of method invocation: anObject.aMethod() ➠ var fn = anObject["aMethod"]; fn.call(anObject) Sets this for new stack frame DOM and JQuery manipulate this ➠ Usually the DOM element that triggered event this not relevant to HOFs Functions, parameters, local scope Optional context parameter on many _ functions
  • 25. _.each(object, iterator, [context]) _.each me, (value, key) -> console.log "Value for #{key} is #{value}" Value for firstName is Howard Value for lastName is Lewis Ship ➠ undefined
  • 26. _.each(list) and undeïŹned sparse = [] sparse[10] = "ten" sparse[20] = "twenty" _.each sparse, (value, index) -> console.log "#{value} is at #{index}" "ten is at 10" "twenty is at 20" ➠ undefined
  • 27. _.map(list, iterator, [context]) _.map [1, 2, 3], (value) -> 2 * value ➠[2, 4, 6] _.map [1, 2, 3, 40, 500], (value, index) -> value * index ➠[0, 2, 6, 120, 2000] _.map me,(value, key) -> "Value for #{key} is #{value}" ➠ ["Value for firstName is Howard", "Value for lastName is Lewis Ship"] Alias: _.collect
  • 28. _.reduce(list, iterator, memo, [context]) aka "accumulator" _.reduce ["Howard", "Lewis Ship", "TWD Consulting"], (memo, name) -> memo + name.length 0 ➠ 30 "HowardLewis ShipTWD Consulting".length ➠ 30 A side effect! _.reduce me, (memo, value, key) -> memo[value] = key ; return memo {} ➠ {"Howard": "firstName", "Lewis Ship": "lastName"} Aliases: _.inject, _.foldl
  • 29. _.ïŹnd(list, iterator, [context]) _.find [1, 2, 3, 4, 5, 6], (x) -> x % 2 is 0 ➠ 2 hand = [ { value:3, suit: "hearts" } { value:2, suit: "spades" } { value:7, suit: "spades" } { value:8, suit: "diamonds" } ] ➠ 
 _.find hand, (card) -> 8 + card.value is 15 ➠ {"suit": "spades", "value": 7} _.find hand, (card) -> 27 + card.value is 31 ➠ undefined Alias: _.detect © 2009 scribbletaylor – http://www.flickr.com/photos/64958688@N00/3604756480/
  • 30. _.all(list, iterator, [context]) _.all hand, (card) -> card.value >= 2 ➠ true _.all hand, (card) -> card.suit is "hearts" ➠ false Alias: _.every
  • 31. _.any(list, [iterator], [context]) _.any hand, (card) -> card.suit is "clubs" ➠ false _.any hand, (card) -> card.suit is "diamonds" ➠ true _.any [] Default iterator is _.identity ➠ false _.any [false] ➠ false _.any [true] ➠ true Alias: _.every
  • 32. _.ïŹlter(list, iterator, [context]) _.filter hand, (card) -> card.suit is "spades" ➠ [{"suit": "spades", "value": 2}, {"suit": "spades", "value": 7}] _.reject hand, (card) -> card.suit is "spades" ➠ [{"suit": "hearts", "value": 3}, {"suit": "diamonds", "value": 8}] Alias: _.select
  • 33. _.groupBy(list, iterator) _.groupBy hand, (card) -> card.suit ➠ {"diamonds": [{"suit": "diamonds", "value": 8}], "hearts": [{"suit": "hearts", "value": 3}], "spades": [{"suit": "spades", "value": 2}, {"suit": "spades", "value": 7}]} _.groupBy hand, (card) -> card.value ➠ {"2": [{"suit": "spades", "value": 2}], "3": [{"suit": "hearts", "value": 3}], "7": [{"suit": "spades", "value": 7}], "8": [{"suit": "diamonds", "value": 8}]} _.groupBy hand, "suit" ➠ {"diamonds": [{"suit": "diamonds", "value": 8}], "hearts": [{"suit": "hearts", "value": 3}], "spades": [{"suit": "spades", "value": 2}, {"suit": "spades", "value": 7}]}
  • 34. _.sortBy(list, iterator, [context]) _.sortBy hand, (card) ->   suitIndex = _.indexOf ["clubs", "diamonds", "hearts", "spades"],     card.suit   100 * suitIndex + card.value ➠ [{"suit": "diamonds", "value": 8}, {"suit": "hearts", "value": 3}, {"suit": "spades", "value": 2}, {"suit": "spades", "value": 7}] _.sortBy hand, "propertyName" Object propertyName has no method 'call' _.sortBy ["fred", "wilma", "barney"], _.identity ➠ ["barney", "fred", "wilma"] (x) -> x
  • 35. _.max(list, [iterator], [context]) _.max [-1, 2, 3] ➠ 3 _.max [] ➠ -Infinity _.max hand, (card) -> card.value ➠ {"suit": "diamonds", "value": 8}
  • 36. _.min(list, [iterator], [context]) _.min [-1, 2, 3] ➠ -1 _.min [] ➠ Infinity _.min hand, (card) -> card.value ➠ {"suit": "spades", "value": 2} _.min ["fred", "wilma", "barney"] ➠ NaN
  • 37. _.include(list, value) _.include [1, 2, 3], 2 ➠ true _.include [1, 2, 3], 99 ➠ false _.include [1, 2, 3], "2" ➠ false Uses === comparison Alias: _.contains
  • 38. _.pluck(list, propertyName) _.pluck hand, "value" ➠ [3, 2, 7, 8] _.pluck hand, "suit" ➠ ["hearts", "spades", "spades", "diamonds"] _.pluck hand, "score" ➠ [undefined, undefined, undefined, undefined]
  • 39. _.shufïŹ‚e(list) _.shuffle hand ➠ [{"suit": "spades", "value": 2}, {"suit": "diamonds", "value": 8}, {"suit": "hearts", "value": 3}, {"suit": "spades", "value": 7}] _.shuffle null ➠ []
  • 40. Object Oriented Style and Chaining
  • 41. _ is a function Every function on _ is also on Returns a wrapper object wrapper object _(hand).pluck "value" ➠ [3, 2, 7, 8] Wrapped object passed as ïŹrst parameter _(hand).size() ➠ 4
  • 42. Chaining Can Be Ugly _.map(_.first(_.sortBy(hand,cardSortValue).reverse(), 2),       (card) -> "#{card.value} of #{card.suit}") ➠ ["8 of diamonds", "7 of spades"] 1.Sort the hand using the cardSortValue function 2.Reverse the result 3.Take the ïŹrst two cards 4.Convert each card to a string
  • 43. _.chain(object) and _.value(object) _.chain(hand) .sortBy(cardSortValue) .reverse() .first(2) Each step returns a new wrapped object .map((card) -> "#{card.value} of #{card.suit}") .value() ➠ ["8 of diamonds", "7 of spades"]
  • 44. Flow of Transformations © 2008 Manu GĂłmez – http://www.flickr.com/photos/manugomi/2884678938/
  • 45. _.tap(object, interceptor) _.chain(hand) .sortBy(cardSortValue) .tap(console.log) .reverse() .first(2) .map((card) -> "#{card.value} of #{card.suit}") .value() [{"suit": "diamonds", "value": 8}, {"suit": "spades", "value": 7}, {"suit": "hearts", "value": 3}, {"suit": "spades", "value": 2}] ➠ ["8 of diamonds", "7 of spades"]
  • 46. Array prototype methods Extra methods on wrapper not on _ _.([1, 2]).concat "three" ➠ [1, 2, "three"] concat shift join slice pop sort push splice reverse unshift
  • 48. Name Description Aliases ïŹrst(array) Return ïŹrst element in array, as single value head ïŹrst(array, n) Return ïŹrst elements of array as list head initial(array, [n]) Return everything but last n (default = 1) elements of array last(array) Return last element in array, as single value last(array, n) Return last n (default = 1) elements of array rest(array, [n]) Return array from index n (default = 1) on tail indexOf(array, value, [isSorted]) Index of value inside array, or -1 lastIndexOf(array, value) Last index of value inside array, or -1 Returns copy with all falsey (null, false, 0, undeïŹned, NaN) compact(array) removed ïŹ‚atten(array, [shallow]) Collapses nested arrays down to a single array
  • 49. Set Operations _.without [5, 4, 3, 2, 1], 4, 2 ➠ [5, 3, 1] _.difference [5, 4, 4, 3, 3, 2, 2, 1], [1, 2], [4, 10, 22] ➠ [5, 3, 3] _.union [3, 2, 1, 3, 4, 5], [101, 1], [3, 4], [500] ➠ [3, 2, 1, 4, 5, 101, 500] _.intersection [5, 4, 4, 3, 3, 2, 2, 1],   [1, 2, 3, 4, 5],   [4, 10, 22, 3] ➠ [4, 3]
  • 50. _.uniq(array, [isSorted], [iterator]) _.uniq [1, 30, 50, 40, 30, 1] ➠ [1, 30, 50, 40] _.uniq [1, 30, 50, 40, 30, 1], false, (x) -> "#{x}".length ➠ [1, 30]
  • 51. _.range([start], stop, [step]) _.range 5 ➠ [0, 1, 2, 3, 4] _.range 3, 5 ➠ [3, 4] _.range 1, 20, 3 ➠ [1, 4, 7, 10, 13, 16, 19] _.range 1, 20, -3 ➠ [] _.range 20, 1, -4 ➠ [20, 16, 12, 8, 4]
  • 52. _.zip(*arrays) _.zip(["a", "b", "c"], [1, 2, 3], ["alpha", "bravo", "charlie", "delta"]) ➠ [["a", 1, "alpha"], ["b", 2, "bravo"], ["c", 3, "charlie"], [undefined, undefined, "delta"]]
  • 54. _.bind(fn, context, [*args]) greet = (greeting) -> "#{greeting}: #{this.name}" greet("Hello, unbound this") ➠ "Hello, unbound this: " bgreet = _.bind greet, { name: "Howard" } bgreet "Hello" ➠ "Hello: Howard" fgreet = _.bind greet, { name: "Mr. Lewis Ship" }, "Salutations" fgreet() ➠ "Salutations: Mr. Lewis Ship"
  • 55. _.defer(function) do invokes the function with no parameters do -> _.defer -> console.log "deferred" console.log "immediate" immediate ➠ undefined deferred
  • 56. _.delay(fn, wait, [*arguments]) log = _.bind console.log, console do -> _.delay log, 1000, "delayed" log "immediate" immediate ➠ undefined delayed About 1 second later
  • 57. _.wrap(function, interceptor) timerInterceptor = (wrapped, args...) -> start = Date.now() result = wrapped(args...) elapsed = Date.now() - start console.log "Function call took #{elapsed} ms." return result fib = (x) -> switch x when 0 then 0 when 1 then 1 else fib(x - 1) + fib(x - 2) tfib = _.wrap fib, timerInterceptor tfib 30 Function call took 23 ms. ➠ 832040 tfib 40 Function call took 2674 ms. ➠ 102334155
  • 58. More Functions on Functions bindAll memoize throttle debounce once after compose
  • 59. Underscore Utilities Name Description identity(value) Returns its argument, a default iterator times(n, iterator) Invoke its iterator n times, passing the index to it uniqueId([preïŹx]) Creates a unique id, good for labelling DOM elements escape(string) Converts & < > " ' / in string to HTML entities (&amp; &lt; 
 ) template(string, [context]) Converts the string into a template function, using a <% 
 %> syntax mixin(object) Adds new functions to _ and to the OOP wrapper, for use with _.chain()
  • 63.
  • 64.
  • 65.
  • 66.
  • 67. Twitter Bootstrap Built by and for nerds All skill levels Desktop, tablets 
 even smartphones and IE Custom jQuery Plugins Based on LESS for customizability
  • 68. Minimal Setup <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="/bootstrap/css/bootstrap.css"> <script src="/bootstrap/js/bootstrap.js"></script> </head> <body> 
 </body> </html>
  • 69. 12 Column Grid 1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 8 6 6 12 940px
  • 70. 12 Column Grid <div class="container"> <div class="row"> <div class="span2">Span 2</div> <div class="span8">Span 8</div> <div class="span2">Span 2</div> </div> <div class="row"> <div class="span6 offset1">Span 6 / Offset 1</div> <div class="span5">Span 5</div> </div> </div>
  • 71. 12 Column Grid – Jade .container .row .span2 Span 2 .span8 Span 8 .span2 Span 2 .row .span6.offset1 Span 6 / Offset 1 .span5 Span 5
  • 72. Nested Rows .container .row .span2 Span 2 .span8 Span 8 - Level 1 Add up to .row container .span4 Span 4 - Level 2 span .span4 Span 4 - Level 2 .span2 Span 2
  • 73. Fluid Layout .container-fluid .row-fluid .span2 Span 2 .span8 Span 8 - Level 1 .row-fluid Add up to 12 .span6 Span 6 - Level 2 .span6 Span 6 - Level 2 .span2 Span 2
  • 74. General Bootstrap Approach Basic, semantic, markup Reasonable default look Simple CSS classes: "row", "span3", "offset1" Additiive: more CSS classes to tune
  • 75. Tables .container table.span12 caption Bare Table thead:tr th.span8 Column A th Column B th.span2 Column C tbody each row in [1, 2, 3, 4] tr each cell in ["A", "B", "C"] td Cell #{row}-#{cell}
  • 79. Buttons ‱Use with: ‱ <a> ‱ <button> ‱ <input type="submit"> ‱ <input type="button"> ‱ <input type="reset">
  • 80. Glyphicons <i class="icon-search"/>
  • 82. .container Tab ul.nav.nav-tabs li.active: a(href="#moe", data-toggle="tab") Moe li: a(href="#larry", data-toggle="tab") Larry li: a(href="#curly", data-toggle="tab") Curly .tab-content .tab-pane.active#moe h1 Moe Howard img(src="images/moe.jpg") .tab-pane#larry h1 Larry Fine img(src="images/larry.jpg") .tab-pane#curly h1 Curly Howard img(src="images/curly.jpg") Text Requires jQuery and Twitter Bootstrap.js
  • 83. Dynamic Tabs ex7.jade .container ul.nav.nav-tabs .tab-content != js("ex7") ex7.coffee jQuery ($) -> tabs = $("ul.nav.nav-tabs") tabContent = $(".tab-content") _.each ["Moe Howard", "Larry Fine", "Curly Howard"], (name) -> 
 tabs.find("li:first").addClass "active" tabContent.find(".tab-pane:first").addClass "active in"
  • 84. Dynamic Tabs _.each ["Moe Howard", "Larry Fine", "Curly Howard"], (name) -> firstName = name.split(' ')[0] uid = _.uniqueId "tab" tab = $(""" <li> <a href="##{uid}" data-toggle="tab"> #{firstName} </a> </li> """) content = $(""" <div class="tab-pane fade" id="#{uid}"> <h1>#{name}</h1> <img src="images/#{firstName.toLowerCase()}.jpg"> </div> """) content.appendTo tabContent tab.appendTo tabs
  • 86. Modal Dialogs ex8.jade .container button#danger.btn.btn-danger(data-toggle="modal" data-target=".x-danger-alert") Do Not Press .modal.x-danger-alert.fade .modal-header a.close(data-dismiss="modal") &times; h3 Why did you press it? .modal-body p You pressed the button marked strong Do Not Press . .modal-footer button.btn.btn-warning(data-dismiss="modal") Continue button.btn(data-dismiss="modal") Cancel
  • 87. Alerts ex8.coffee jQuery ($) -> $(".x-danger-alert .btn-warning").on "click", -> alert = $(""" <div class="alert fade in"> <a class="close" data-dismiss="alert">&times;</a> <strong>Well, you pressed it!</strong> </div> """) alert.prependTo $(".container")
  • 88. Other Plugins Popover Tooltip And more: Scrollspy Dropdown Button Collapse Carousel Typeahead
  • 90. Underscore Effective, functional JavaScript Bootstrap Sharp L&F out of the box Very customizable Bootstrap JS Lots of UI pizzaz, effortlessly CoffeeScript Concise, readable JavaScript
  • 92. Q&A