Skip to content

Commit

Permalink
feat #285 Created a simple HTML checkbox widget
Browse files Browse the repository at this point in the history
  • Loading branch information
okappes authored and Fabio Crisci committed Jan 8, 2013
1 parent f441d21 commit 0476a8c
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 2 deletions.
101 changes: 101 additions & 0 deletions src/aria/html/CheckBox.js
@@ -0,0 +1,101 @@
/*
* Copyright 2012 Amadeus s.a.s.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

(function() {
/**
* Being a BindableWidget we already have one direction binding of checked (from the datamodel to the widget). This
* function is the callback for implementing the other bind, from the widget to the datamodel. The checked property
* is set in the datamodel on click.
* @param {aria.DomEvent} event click event
* @private
*/
function bidirectionalClickBinding(event) {
var bind = this._bindingListeners.checked;
var newValue = this._transform(bind.transform, event.target.getProperty('checked'), "fromWidget");
aria.utils.Json.setValue(bind.inside, bind.to, newValue, bind.cb);
}

/**
* CheckBox widget. Bindable widget providing bi-directional bind of 'checked'.
*/
Aria.classDefinition({
$classpath : "aria.html.CheckBox",
$extends : "aria.html.Element",
$dependencies : ["aria.html.beans.CheckBoxCfg"],
$statics : {
INVALID_USAGE : "Widget %1 can only be used as a %2."
},
$constructor : function(cfg, context, line) {
this.$cfgBean = "aria.html.beans.CheckBoxCfg.Properties";

cfg.tagName = "input";
cfg.attributes = cfg.attributes || {};
cfg.attributes.type = "checkbox";
cfg.on = cfg.on || {};

this._chainListener(cfg.on, context, 'click', {
fn : bidirectionalClickBinding,
scope : this
});

this.$Element.constructor.call(this, cfg, context, line);
},
$prototype : {
/**
* TextInput can only be used as self closing tags. Calling this function raises an error.
* @param {aria.templates.MarkupWriter} out
*/
writeMarkupBegin : function(out) {
this.$logError(this.INVALID_USAGE, [this.$class, "container"]);
},

/**
* TextInput can only be used as self closing tags. Calling this function does not rais an error
* though because it was already logged by writeMarkupBegin.
* @param {aria.templates.MarkupWriter} out
*/
writeMarkupEnd : Aria.empty,

/**
* Initialization method called after the markup of the widget has been inserted in the DOM.
*/
initWidget : function() {
this.$Element.initWidget.call(this);

var bindings = this._cfg.bind;
if (bindings.checked) {
var newValue = this._transform(bindings.checked.transform,
bindings.checked.inside[bindings.checked.to], "toWidget");
if (newValue != null) {
this._domElt.checked = newValue;
}
}
},

/**
* Function called when a value inside 'bind' has changed.
* @param {String} name Name of the property
* @param {Object} value Value of the changed property
* @param {Object} oldValue Value of the property before the change happened
*/
onbind : function(name, value, oldValue) {
if (name === "checked") {
this._domElt.checked = value;
}
}

}
});
})();
3 changes: 2 additions & 1 deletion src/aria/html/HtmlLibrary.js
Expand Up @@ -20,7 +20,8 @@ Aria.classDefinition({
$prototype : {
widgets : {
"TextInput" : "aria.html.TextInput",
"Template" : "aria.html.Template"
"Template" : "aria.html.Template",
"CheckBox" : "aria.html.CheckBox"
}
}
});
36 changes: 36 additions & 0 deletions src/aria/html/beans/CheckBoxCfg.js
@@ -0,0 +1,36 @@
/*
* Copyright 2012 Amadeus s.a.s. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

Aria.beanDefinitions({
$package : "aria.html.beans.CheckBoxCfg",
$description : "Configuration for CheckBox widget.",
$namespaces : {
"base" : "aria.html.beans.ElementCfg",
"common" : "aria.widgetLibs.CommonBeans"
},
$beans : {
"Properties" : {
$type : "base:Properties",
$description : "Properties of a CheckBox widget.",
$properties : {
"bind" : {
$type : "base:Properties.$properties.bind",
$properties : {
"checked" : {
$type : "common:BindingRef",
$description : "Bi-directional binding. The text input's checked property is set in the bound object."
}
}
}
}
}
}
});
3 changes: 2 additions & 1 deletion src/aria/html/beans/ElementCfg.js
Expand Up @@ -27,7 +27,8 @@ Aria.beanDefinitions({
$properties : {
"id" : {
$type : "json:String",
$description : "Element id"
$description : "Unique id (within the template) to associate to the widget - if not provided, a unique id will automatically be generated by the framework",
$mandatory : false
},
"tagName" : {
$type : "json:String",
Expand Down
1 change: 1 addition & 0 deletions test/aria/html/HTMLTestSuite.js
Expand Up @@ -24,5 +24,6 @@ Aria.classDefinition({
this.addTests("test.aria.html.ElementEventsTest");
this.addTests("test.aria.html.controllers.suggestions.ResourcesHandlerTest");
this.addTests("test.aria.html.textinput.TextInputTestSuite");
this.addTests("test.aria.html.checkbox.CheckBoxTest");
}
});
183 changes: 183 additions & 0 deletions test/aria/html/checkbox/CheckBoxTest.js
@@ -0,0 +1,183 @@
/*
* Copyright 2012 Amadeus s.a.s.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

Aria.classDefinition({
$classpath : "test.aria.html.checkbox.CheckBoxTest",
$extends : "aria.jsunit.TestCase",
$dependencies : ["aria.html.CheckBox", "aria.utils.json", "aria.utils.FireDomEvent"],
$prototype : {
setUp : function () {
var document = Aria.$window.document;
var testArea = document.createElement("div");
testArea.id = "testForCheckBox";

document.body.appendChild(testArea);

this.playgroundTestArea = testArea;
},

tearDown : function () {
this.playgroundTestArea.parentNode.removeChild(this.playgroundTestArea);
this.playgroundTestArea = null;
},

createMockMarkupWriter : function () {
var buffer = [];
return {
write : function (markup) {
buffer.push(markup);
},

getMarkup : function () {
return buffer.join("");
}
};
},

mockEvalCallback : function (transform, retVal) {
return transform(retVal);
},

testInitialValueFalse : function () {
var container = {};

var cfg = {
bind : {
checked : {
inside : container,
to : "checkstate"
}
}
};

var out = this.createMockMarkupWriter();
var widget = new aria.html.CheckBox(cfg, {
tplClasspath : "CheckBox"
});
widget.writeMarkup(out);

this.playgroundTestArea.innerHTML = out.getMarkup();

widget.initWidget();

this.assertEquals(widget._domElt.checked, false, "Checked bound to initial false: " + widget._domElt.checked);

aria.utils.Json.setValue(container, "checkstate", true);
this.assertEquals(widget._domElt.checked, true, "Set checked to true: " + widget._domElt.checked);

widget.$dispose();
},

testInitialValueTrue : function () {
var container = {
checkstate : true
};

var cfg = {
bind : {
checked : {
inside : container,
to : "checkstate"
}
}
};

var out = this.createMockMarkupWriter();
var widget = new aria.html.CheckBox(cfg, {
tplClasspath : "CheckBox"
});
widget.writeMarkup(out);

this.playgroundTestArea.innerHTML = out.getMarkup();

widget.initWidget();

this.assertEquals(widget._domElt.checked, true, "Checked bound to initial true: " + widget._domElt.checked);

aria.utils.Json.setValue(container, "checkstate", false);
this.assertEquals(widget._domElt.checked, false, "Set checked to false: " + widget._domElt.checked);

widget.$dispose();
},

testTransformFromWidget : function () {
var container = {
checkstate : 'checked'
};

var cfg = {
bind : {
checked : {
inside : container,
to : "checkstate",
transform : {
fromWidget : function(v) {return v ? 'checked' : 'not_checked'},
toWidget : function(v) {return v=='checked'}
}
}
}
};

var out = this.createMockMarkupWriter();
var widget = new aria.html.CheckBox(cfg, {
tplClasspath : "CheckBox",
evalCallback : this.mockEvalCallback
});
widget.writeMarkup(out);

this.playgroundTestArea.innerHTML = out.getMarkup();

widget.initWidget();

this.assertEquals(widget._domElt.checked, true, "Transform to widget true: " + widget._domElt.checked);

aria.utils.Json.setValue(container, "checkstate", 'not_checked');
this.assertEquals(widget._domElt.checked, false, "Transform to widget false: " + widget._domElt.value);

widget.$dispose();
},

testReactOnClick : function () {
var container = {};

var cfg = {
bind : {
checked : {
inside : container,
to : "checkstate"
}
}
};

var out = this.createMockMarkupWriter();
var widget = new aria.html.CheckBox(cfg, {
tplClasspath : "CheckBox"
});
widget.writeMarkup(out);

this.playgroundTestArea.innerHTML = out.getMarkup();

widget.initWidget();

aria.utils.FireDomEvent.fireEvent("click", widget._domElt);

this.assertEquals(widget._domElt.checked, true, "Check click on dom: " + widget._domElt.checked);
this.assertEquals(container.checkstate, true, "Check click on data: " + container.checkstate);

widget.$dispose();
}

}
});

0 comments on commit 0476a8c

Please sign in to comment.