Code Monkey home page Code Monkey logo

o_o's Introduction

                         ,ad8888ba,            
                        d8"'    `"8b           
                       d8'        `8b     
  ,adPPYba,            88          88          
 a8"     "8a           88          88     
 8b       d8           Y8,        ,8P          
 "8a,   ,a8"            Y8a.    .a8P           
  `"YbbdP"'              `"Y8888Y"'            

            888888888888                       

Funnyface.js

HTML binding for teh lulz

  • Elegantly binds objects to HTML
  • Proxies through jQuery, Ender, or whatever $ is
  • Automatic dependency resolution
  • Plays well with others

Examples

The Basics

o_O properties

Use o_O(...) to create an evented o_O property:

name = o_O('Homer Simpson')

// read a value
name() // => 'Homer Simpson'

// write a value
name('Bart Simpson')

o_O properties are evented, so it's possible to bind to a change event:

name.change(function(new_name, old_name) {
  console.log('my name changed from', old_name, 'to', new_name)
})

Computed properties

o_O can also create computed properties:

firstName = o_O('Homer')
surName = o_O('Simpson')
fullName = function() {
  return firstName() + ' ' + surName()
}

fullName() // => 'Homer Simpson'

A computed property automatically determines it's dependencies and is recalculated whenever a dependency changes:

firstName('Bart')

fullName() // => 'Bart Simpson'

HTML binding with o_O.bind

Bind an object to a section of HTML with the o_O.bind(...) method, and bind parts of that HTML section to o_O properties with the data-bind attribute:

person = {
  firstName: o_O('Michael'),
  surName: o_O('Jackson'),
  fullName: function() {
    return person.firstName() + ' ' + person.surName()
  },
  age: o_O(50)
}
o_O.bind(person, '#person');
<div id="person">
  <div data-bind="text: fullName()"></div>
  <div data-bind="text: age()"></div>
</div>

This will render the HTML and retrigger the bindings whenever a dependency changes. So e.g calling person.firstName('Miss') will update the HTML.

The binding names are associated with jQuery (or whatever $ is), so css will call $.fn.css. There are also some custom bindings:

  • foreach : renders the innerHTML for a list of items
  • value : two-way binding for forms
  • visible : hides an element if falsey
  • if/unless : removes/shows the inner HTML
  • with : rebinds the context (similar to javascript with)
  • options: options for a select
  • log: outputs to console.log
  • onbind: general purpose

Event handlers will also work, e.g. click: handleClick.

NB if there's no corresponding binding found, it will simply update the attribute on the element; this is especially useful for attributes such as id, class, src, href

Digging Deeper

Besides creating basic javascript objects containing o_O properties, you can also create an o_O model (using o_O.model(...)) that creates o_O properties for you out of the box as well as giving you access to event aggregation:

var homer = o_O.model({
  name: 'Homer Simpson',
  age: 40
});

homer.on('set:name', function(character, name_new, name_old){
  console.log("Homer's name changed.");
});

You can also create an o_O evented array that lets you create an array of items (can be anything) and if the items support it (i.e. they are o_O models) aggregates events across all of them:

var cast = o_O.array();

cast.push(o_O.model({name: 'Homer', age: 40}));
cast.push(o_O.model({name: 'Marge', age: 36}));
cast.push(o_O.model({name: 'Bart', age: 10}));
cast.push(o_O.model({name: 'Lisa', age: 8}));
cast.push(o_O.model({name: 'Maggie', age: 2}));

cast.on('set:age', function(character, age_new, age_old){
  console.log(character.name + "'s age changed from " + age_old + " to " + age_new + ".");
});

// this will trigger the above 'set:' event for each character:
cast.forEach(function(character){
  character.age(character.age() + 1);
});

cast.on('add', function(new_character){
  console.log(new_character);
});

// this will trigger the above 'add' event:
cast.push(new Character({name: 'Mr. Burns', age: 99}));

The special foreach binding will render this list:

<ul id="cast" data-bind='foreach: cast'>
  <li data-bind="text: fullName() +',' + age()" ></li>
</ul>

<script>
o_O.bind(cast, '#cast')
</script>

Running Tests

Make sure you have installed o_O's development dependencies via npm:

npm install

A subset of tests can be run via the console:

npm test

Or, if you have mocha install (npm install -g mocha) you can just run:

mocha

Other tests (that rely on the browser's DOM) must be run in the browser:

open test/mocha.html

Browser Compatability

Tested in:

  • Chrome 16-18
  • Firefox 4-10
  • Internet Explorer 7-9
  • Safari 5
  • Node 6.0

Other browsers should work, (eg IE6) but are currently untested

Importing to alternate namespace

It's possible to import o_O to an alternative namespace by appending ?mynamespace to the script, for example

<script src="../o_O.js?oO"></script>

will import the library to window as oO

Contributers

  • Jonah Fox aka weepy
  • Troy Goode

License

o_O is released under the MIT license:

The MIT License (MIT)

Copyright (c) 2012 Jonah Fox <[email protected]> (https://github.com/weepy)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

o_o's People

Contributors

weepy avatar troygoode avatar ricket avatar thadclay avatar

Stargazers

Kolja avatar Kushal Billaiya avatar Patrick G avatar  avatar Logan King (DarkComet) avatar Robert Schiriac avatar Richard avatar Shanyu Thibaut Juneja avatar Rihan avatar Pankaj Patel avatar David Boureau avatar  avatar Alex Fox avatar aric avatar Filipe Herculano avatar Ilya Myasin avatar Dmitriy Kepov avatar Hans Felde avatar Rob Cherny avatar Michael Anthony avatar  avatar  LB avatar Tormod Vold Mikkelsen avatar DANIEL SIMON JR avatar Brad Ward avatar  avatar Smooth Operator avatar Vadym Borodin avatar green avatar Andrea Parodi avatar Chris Morris avatar Pablo Damian Cotoia avatar Naheev Tinkah avatar Albert Abril avatar 朱一 avatar Brad Jones avatar Frank Lin avatar Ken Post avatar Alex Riedler avatar Fazal avatar Corentin Kerisit avatar Tim Lossen avatar Emily Marigold Klassen avatar Tung Dao avatar Ahmet Abdi avatar Victor Teixeira avatar Colin Bate avatar Rowan Manning avatar Eric Lawrence avatar Warnar Boekkooi avatar Shannon Duncan avatar Timm Preetz avatar Ciaran McNulty avatar Pascal Opitz avatar Daichi Sakai avatar Stuart Robinson avatar Evan Hahn avatar julien brunet avatar nick comer avatar coderaiser avatar Sean.J avatar Paul Ferruggiaro avatar torzborz avatar Alexander Bihary avatar  avatar Milton Colwell avatar Steven Olsen avatar Chris Aquino avatar Mathias Wulff avatar Dr_rOot avatar Michał Rączka avatar Kevin Butler avatar Brian Springer avatar Dinesh Kr. Choudhary avatar Angelos Pikoulas avatar HIRAKI Satoru avatar Mariano Vicente avatar  avatar hamlet avatar Kevin Lanni avatar Sylvain Faucherand avatar Ahmet Vurgun avatar Alive.Kuo avatar Yiran Sheng avatar ianva avatar Collin Schneider avatar Philip Stewart avatar Neville Franks avatar andreas.karlsson avatar Lele avatar Sander Houttekier avatar Christian Roman avatar Rob Horvath avatar  avatar hacfi avatar JT5D avatar Cam Pedersen avatar Joseph Reisinger avatar Dmitry Demenchuk avatar fejustin avatar

Watchers

 avatar Brad Jones avatar Tormod Vold Mikkelsen avatar James Cloos avatar Informationatlas GmbH avatar Smooth Operator avatar Michael Anthony avatar kokujin avatar Hans Felde avatar  avatar  avatar

o_o's Issues

onbind binding

should remove the onbind magic function and replace with a binding onbind or once

NB - I should only run once - even if calls dependant functions

multiple arguments

I can do animation like :

<div class=level bind='animate: css()' ></div>

how to handle the case of wanting to pass an extra argument in to set the animation speed ?

docs

badly needs some docs

what's the best format and style ?

Multiple data-binds on an element

I tried:

<button data-bind="text:promptDlgOk" data-bind="visible:has_ok_button"></button>

and couldn't get it to work. It appears as though a given element can only have one data-bind. Can you confirm that's the case or am I doing something wrong?

Thanks, Neville

alternate model behaviour

allow models to work without settings their properties? The current behaviour could be used for setting defaults. E.g.

var a = new o_O.Model({x: 1})
a.x() == 1 // true
var sub = o_O.Model.extend({type: 'sub', x: 2})
var b = new sub()

b.type == 'sub'
b.x() == 2  // true

o_O.arrays don't seem to unbind correctly

when rebinding an o_O.array to some html with a foreach binding, the array doesn't seem to unbind correctly. It still seems to fire an old binding, which causes an error in o_O.bind when trying to reference el.bindings, as el is undefined

o_O.once

perhaps it would be useful for a o_O.helper to turn off dependencies

API to get the element bound to a model property.

Given:

person = {
  firstName: o_O('Michael'),
  surName: o_O('Jackson'),
}
o_O.bind(person, '#person');

<div id="#person">
  <div data-bind="text: fullName()"></div>
  <div data-bind="text: age()"></div>
</div>

is there a way I can get the dom element bound to person.firstname?

Thanks,
Neville

TODOs tutorial is broken

http://weepy.github.com/o_O/examples/todos/index.html

Error:

Uncaught TypeError: Object function o_O() {} has no method 'collection'

Being thrown from:

var ViewModel = function(todos) {
        var self = this;
        //map array of passed in todos to an observableArray of Todo objects
        self.todos = o_O.collection(todos)

Sorry, didn't have time to investigate further yet.

.length or .length() for o_O.array

We could bring back .count() and then update .length as necessary for near complete parity with Array, rather than the .length()

Is it worth it ?

How to unbind / destroy a binding.

Hi, I just found o_O today and it looks like a great fit for a project I'm working on.

I want to use o_O with Twitter Bootstrap dialogs and I want to unbind / destroy the binding when the dialog closes. I've looked through the code and docs and can't see any method to accomplish this.

Thanks,
Neville

add thottle to o_O properties

Should be really easy: add a value to a property .timeout or .throttle (or another name). This is the minimum time before the property will fire.

emitProperty will then be called with this value where necessary. It defaults to zero - i.e. next event loop, but can be another integer, or null which means it will be called immediately (sync).

So then just timer = timer || o_O.nextTick(run) would need to be changed to handle this

oO

is oO any easier to type or look at ?

window.requestAnimationFrame

experiment to see if it's better to use this than setTimeout(0)

Only issue is chained events which will take more than a frame to occur. Ideally event should occur quickly, but bindings only fired slowly. Is this possible to fix ? ... main question is --- how does a binding know that it is already queued to fire ? If we know that, then we're half way there.

This might change properties so they were fired synchronously by default.

dynamic binding to child html

sometimes a binding might write html to an element and then we want to control the css of a child element. E.g.

<div data-bind='html: html;'></div>

o = {
  html: '<p></p>',
  paragraph_css: { color: 'red'}
}

bind(o, 'div')

question is - how to bind the paragraph_css to the <p> tag that's created ?

o_O.store / o_O.factory

It might be worth removing the logic in the model that deals with .id and .type , and moving them to a store.

It would be a memory store by default, but easy enough to plugin different stores.

.save would probably assign an id

inserting bound array correctly

current implementation rerenders the whole list upon each write regardless ?? :

proto.renderOne = function(item, $el) {
  $(getTemplate($el)).each(function(i, elem) {
    var $$ = $(elem)
    $$.appendTo($el)
    o_O.bind(item, $$)
  })
}

Ideally we'd like to insert after the previous element

TODOMVC

  • Can you resubmit the pull request against the labs branch? ALso make sure to submit from a topic branch (NOT master). See wiki.
  • Remove the app.css file
  • Remove the base.css and bg.png, you should instead reference it from the assets folder. See app spec.
  • Reference jquery from the assets folder too, delete the local one. See app spec.
  • You app should be in js folder not lib and put frameworks and other libs in a lib folder inside the js folder. See app spec.
  • scripts should be at the bottom. See template.
  • Remove HTML comments. See app spec.
  • Editing state should not be persisted. See app spec.
  • New todo: trim input, and only add if it's not empty.
  • Can't edit a todo.
  • Mark all as complete checkbox:

The checkbox should also be updated when single todo items are checked/unchecked. Eg. When all the todos are checked it should also get checked.

  • Hide when no todos:

When there are no todos, #main and #footer should be hidden.

Make sure you read through the App Spec thoroughly. Everything is in there.

Redis style collections

Instead of making a one size fits all collection, we could go down the route of having more simpler collection models. E.g.

o_O.array( ... )   // array with pop/push etc
o_O.list( ... )       // i.e. list (set)  with add, remove
o_O.zlist( ... )     // i.e. sorted list (set) with add, remove

jquery plugin

would it be useful to be able to proxy through jQuery ?

$('#myElement').dataBind(object)

$('#myElement').o_O(object)

List browser compatability

It would be nice if you could test and list browser compatibility somewhere. For example, this works in Chrome 16.x but not IE7.

Recipes

One nice way to learn/document o_O might be to assemble a collection of o_O recipes. These would be similar to the current 'guide' but much more comprehensive and could be added to over time.

I.e.
Listing resources
Creating a compound property that only fires once
Creating a twitter style list.

etc...

add o_O.current

would simply point to the current $el being bound.

useful for slightly hacking things

Is this project still active?

I was looking for an alternative to Knockout and I found this, it looks very interesting. Is it still being actively developed? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.