Skip to content
Browse files

Support radio, selects, and checkboxes

  • Loading branch information...
1 parent 8f944c7 commit dfb295d3e9ef43019784b39babab291f89323c56 @kriszyp committed Oct 9, 2012
Showing with 133 additions and 26 deletions.
  1. +38 −15 bind.js
  2. +21 −11 tests/testForm.js
  3. +24 −0 tests/testFormBinding.html
  4. +50 −0 tests/testFormBinding.js
View
53 bind.js
@@ -1,4 +1,5 @@
define([], function(){
+ // A basic binding to value, our base class
function Binding(value){
this.value= value;
if(value){
@@ -7,6 +8,7 @@ define([], function(){
}
Binding.prototype = {
then: function(callback){
+ // get the value of this binding, notifying the callback of changes
(this.callbacks || (this.callbacks = [])).push(callback);
this.getValue(callback);
},
@@ -77,7 +79,7 @@ define([], function(){
});
return this;
}
- };
+ };
// StatefulBinding is used for binding to Stateful objects, particularly Diji widgets
function StatefulBinding(stateful){
this.stateful = stateful;
@@ -106,37 +108,58 @@ define([], function(){
function ContainerBinding(element){
return new ElementBinding(element, true);
}
+ ElementBinding.prototype = new Binding({});
var checkable = {radio: 1, checkbox: 1};
- ElementBinding.prototype.is = function(value){
+ ElementBinding.prototype.is = function(value){
+ var element = this.element;
if(this.container || element.tagName == "FORM"){
return Binding.prototype.is.call(this, value);
- };
- if("value" in this.element){
+ };
+ if("value" in element){
+ if(element.type == "radio"){
+ element.checked = element.value == value;
+ }else if(element.type == "checkbox"){
+ element.checked = value;
+ }else{
+ element.value = value || "";
}
- }else{
+ }else{
element.innerText = value || "";
}
};
- ElementBinding.prototype.to = function(source){
+ ElementBinding.prototype.to = function(source){
+ Binding.prototype.to.apply(this, arguments);
source = this.source;
var element = this.element;
- if(element.tagName == "FORM"){
- var inputs = element.getElementsByTagName("input");
- for(var i = 0; i < inputs.length; i++){
- var input = inputs[i];
- if(input.name){
+ if(element.tagName == "FORM"){
+ function findInputs(tag){
+ var inputs = element.getElementsByTagName(tag);
+ for(var i = 0; i < inputs.length; i++){
+ var input = inputs[i];
+ if(input.name){
+ bind(input, this.get(input.name));
}
}
- }
- }else if(element.tagName == "INPUT"){
+ }
+ findInputs("input");
+ findInputs("select");
+ }else if(element.tagName == "INPUT" || element.tagName == "SELECT"){
var value, oldValue, gotOldValue;
element.onchange = function(){
if(!gotOldValue){
gotOldValue = true;
source.getValue(function(value){
oldValue = value;
});
- }
+ }
+ if(element.type == "radio"){
+ if(element.checked){
+ value = element.value;
+ }else{
+ return; // not checked, don't do anything
+ }
+ }else{
+ value = element.type == "checkbox" ? element.checked : element.value;
}
source.put(typeof oldValue == "number" && !isNaN(value) ? +value : value);
};
@@ -210,7 +233,7 @@ define([], function(){
this.source.put(this.reverseFunc(value));
},
is: function(){},
- to: function(source){
+ to: function(source){
source = bind.apply(this, arguments);
this.source = source;
return this;
View
32 tests/testForm.js
@@ -1,13 +1,12 @@
define(['dbind/bind', 'dbind/Validator', 'put-selector/put'], function(bind, Validator, put){
var get = bind.get;
- myObject = {quantity: 3, price: 5};
+ myObject = {quantity: 3, price: 5, discounted: true, color: "red", pattern: "striped"};
return function(form){
// TODO: put this in a model module
var quantity = bind(
new Validator({type:"number", maximum: 20, minimum: 10})).to
(get(myObject, 'quantity'));
- var quantityRow = put(form, 'div');
quantity.get("title").is("Quantity");
@@ -22,18 +21,29 @@ define(['dbind/bind', 'dbind/Validator', 'put-selector/put'], function(bind, Val
bind(put(mainElement, 'span.error-message')).to(binding.get('error'));
return mainElement;
}
+ // create the form elements
+ var quantityRow = put(form, 'div');
var quantityTextBox = ValidationTextBox();
put(quantityRow, quantityTextBox);
bind(quantityTextBox).to(quantity);
- put(form, "div", "Price", "input[type=text]", {name: "price"});
- bind(form, myObject);
-/* bind(put(quantityRow, 'input[type=text][placeholder=number]'), quantity);
- bind(put(quantityRow, 'span.error-message'), quantity.get('error'));
- bind(put(form, 'div label'), quantity.get("title"))
- bind(put(form, 'div span'), quantity);*/
- bind(put(form, 'div label', 'Total Price: ', '< span'), bind(function(quantity, price){
- return "$" + quantity * price;
- }).to([quantity, bind(myObject, "price")]));
+ bind(put(form, "div", "Price", "input[type=text]")).to(myObject, "price");
+
+ bind(put(form, "div", "Discounted", "input[type=checkbox]")).to(myObject, "discounted");
+
+ var patternSelect = put(form, "div", "Pattern", "select");
+ put(patternSelect, "option[value=striped]", "Striped");
+ put(patternSelect, "option[value=solid]", "Solid");
+ bind(patternSelect).to(myObject, "pattern");
+
+ var colorDiv = put(form, "div", "Color");
+ var colorProperty = bind(myObject, "color");
+ bind(put(colorDiv, "div", "Red", "input[type=radio][value=red]")).to(colorProperty);
+ bind(put(colorDiv, "div", "Green", "input[type=radio][value=green]")).to(colorProperty);
+ bind(put(colorDiv, "div", "Blue", "input[type=radio][value=blue]")).to(colorProperty);
+
+ bind(put(form, 'div label', 'Total Price: ', '< span'), bind(function(quantity, price, discounted){
+ return "$" + quantity * price * (discounted ? 0.9 : 1);
+ }).to([quantity, bind(myObject, "price"), bind(myObject, "discounted")]));
}
});
View
24 tests/testFormBinding.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test dbind with a form</title>
+ <style type="text/css">
+ @import "../../dojo/resources/dojo.css";
+ .error-message {
+ color: red;
+ }
+ </style>
+ <script type="text/javascript" src="../../dojo/dojo.js"
+ data-dojo-config="async: true"></script>
+ <script type="text/javascript">
+ require(["./testFormBinding.js", "dojo/dom", "dojo/domReady!"], function(testForm, dom){
+ testForm(dom.byId("my-form"));
+ });
+ </script>
+ </head>
+ <body>
+ <h2>Basic form bindings</h2>
+ <form id="my-form">
+ </form>
+ </body>
+</html>
View
50 tests/testFormBinding.js
@@ -0,0 +1,50 @@
+define(['dbind/bind', 'dbind/Validator', 'put-selector/put'], function(bind, Validator, put){
+ var get = bind.get;
+ myObject = {quantity: 3, price: 5, discounted: true, color: "red", pattern: "solid"};
+ return function(form){
+ // TODO: put this in a model module
+ var quantity = bind(
+ new Validator({type:"number", maximum: 20, minimum: 10})).to
+ (get(myObject, 'quantity'));
+
+
+ quantity.get("title").is("Quantity");
+
+ function ValidationTextBox(){
+ var mainElement = put('div');
+ var binding = new bind.Container(mainElement);
+ // the label
+ bind(put(mainElement, 'label')).to(binding.get('title'));
+ // the main value is bound to the input
+ bind(put(mainElement, 'input[type=text]')).to(binding);
+ // any errors go after it
+ bind(put(mainElement, 'span.error-message')).to(binding.get('error'));
+ return mainElement;
+ }
+ // create the form elements
+ var quantityRow = put(form, 'div');
+ var quantityTextBox = ValidationTextBox();
+ put(quantityRow, quantityTextBox);
+ bind(quantityTextBox).to(quantity);
+
+ put(form, "div", "Price", "input[type=text]", {name: "price"});
+
+ put(form, "div", "Discounted", "input[type=checkbox]", {name: "discounted"});
+
+ var patternSelect = put(form, "div", "Pattern", "select[name=pattern]");
+ put(patternSelect, "option[value=[striped]", "Striped");
+ put(patternSelect, "option[value=[solid]", "Solid");
+
+ var colorDiv = put(form, "div", "Color");
+ put(colorDiv, "div", "Red", "input[type=radio][value=red]", {name: "color"});
+ put(colorDiv, "div", "Green", "input[type=radio][value=green]", {name: "color"});
+ put(colorDiv, "div", "Blue", "input[type=radio][value=blue]", {name: "color"});
+
+ // now bind the form to the object, this will bind the elements to the properties of the object
+ bind(form, myObject);
+
+ bind(put(form, 'div label', 'Total Price: ', '< span'), bind(function(quantity, price, discounted){
+ return "$" + quantity * price * (discounted ? 0.9 : 1);
+ }).to([quantity, bind(myObject, "price"), bind(myObject, "discounted")]));
+ }
+});

0 comments on commit dfb295d

Please sign in to comment.
Something went wrong with that request. Please try again.