2w gives you a simple, small, library-agnostic 2-way data binding API, inspired by angularjs'.
<div data-controller="quickdemo">
<input type="text" data-model="name" placeholder="Type your name...">
<span>{{ greet() }}{{ name }}!</span>
</div>
$2w.controller('quickdemo', function(scope){
scope.greet = function() {
return 'Hello' + (scope.name ? ', ' : '');
}
});
Just add 2w.js before all other scripts using 2w.
<script src="/javascripts/2w.js"></script>
And you're ready to go.
Controllers are callbacks bound to active DOM elements. Any element with a controller attached will listen to data changes and re-render itself whenever a change occurs.
You create and set a controller using the data-controller attribute.
Once you add some controllers to the html markup, you can initialize some behaviour, using $2w.controller().
This is a simple {{text}}.
This is an active {{text}}.
<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body> <p>This is a simple {{text}}.</p> <p data-controller="paragraph">This is an active {{text}}.</p> <script src="2w.js"></script> <script src="demo.js"></script> </body> </html>
$2w.controller('paragraph', function(p){ p.text = 'text set dynamically'; });
$2w.controller() setter takes two arguments: a controller name, and a behaviour callback. This callback is executed passing the controller scope as argument. Everytime a property of the scope changes, the view is updated automatically.
If you want to change a scope property from outside the controller callback, you can access it via the $2w.controller() getter:
<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body> <p>This is a simple {{text}}.</p> <p data-controller="paragraph2">This is an active {{text}}.</p> <a id="link">Change paragraph2 text</a> <script src="2w.js"></script> <script src="demo.js"></script> </body> </html>
$2w.controller('paragraph2', function(p){ p.text = 'text set dynamically'; }); document.getElementById('link').addEventListener('click', function(){ var $p = $2w.controller('paragraph2'); $p.text = 'different text'; }, false);
Template expressions are simply good ol' javascript expressions. This means that you can add more than string variables to templates.
<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body data-controller="expressions"> <ul> <li>This is a string: {{string}}</li> <li>This is a math operation: {{2+2}}</li> <li>This is a function call: {{func()}}</li> <li>This is a ternary expression: {{func() ? 'foo' : 'bar'}}</li> <li>This is a assign expression: {{result = 5}}</li> <li>And this is the assignment: {{result}}</li> </ul> <script src="2w.js"></script> <script src="demo.js"></script> </body> </html>
$2w.controller('expressions', function(ctrl){ ctrl.string = 'some text'; ctrl.func = function() { return Math.random()*10 < 5; } ctrl.result = 1; // This gets overwritten });
You can also bootstrap a callback for several controllers. Pass space-separated controller names to $2w.controller() and the callback will be invoked with all of them passed as arguments.
This is {{ctrl}}
This is {{ctrl}}
<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body> <div data-controller="ctrlOone"> <p>This is {{ctrl}}</p> </div> <div data-controller="ctrlTwo"> <p>This is {{ctrl}}</p> </div> <script src="2w.js"></script> <script src="demo.js"></script> </body> </html>
$2w.controller('ctrlOone ctrlTwo', function(one, two){ one.ctrl = 'controller number one'; two.ctrl = 'controller number two'; });
You can create a controller dynamically and attach it to any document element using $2w.attachController() passing a dom element and a controller name. If the controller doesn't exist, it'll be created on the go.
This is an {{op}}: {{2+2}}
<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body> <div id="dynamic"> <p>This is an {{op}}: {{2+2}}</p> </div> <a id="link">Attach controller</a> <script src="2w.js"></script> <script src="demo.js"></script> </body> </html>
$2w.controller('myCtrl', function(scope){ scope.op = 'exprssion'; }); document.getElementById('link').addEventListener('click', function(){ $2w.attachController(document.getElementById('dynamic'), 'myCtrl'); }, false);
There are some events tied to certain attributes. For example, you can use data-click to fire an expression:
Some text: {{text}}
Change text<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body> <div data-controller="clickCtrl"> <p>Some text: {{text}}</p> <a data-click="text = 'bar'">Change text</a> </div> <script src="2w.js"></script> <script src="demo.js"></script> </body> </html>
$2w.controller('clickCtrl', function(scope){ scope.text = 'foo'; });