Skip to content

Commit

Permalink
feat #921 aria:List widget refresh on datamodel change
Browse files Browse the repository at this point in the history
Now when you use aria.utils.Json.add and aria.utils.Json.removeAt functions to add items to an aria:List widget (or to remove one), the list template is refreshed and it displays the new item.
  • Loading branch information
fab-b authored and Benoit Charbonnier committed Jan 22, 2014
1 parent 93b70b1 commit 1bc334f
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 26 deletions.
50 changes: 26 additions & 24 deletions src/aria/widgetLibs/BindableWidget.js
Expand Up @@ -73,37 +73,39 @@ Aria.classDefinition({
* @protected * @protected
*/ */
_registerBindings : function () { _registerBindings : function () {
var bindings = this._cfg.bind, jsonUtils = aria.utils.Json; var bindings = this._cfg.bind;
if (bindings) { if (bindings) {
for (var property in bindings) { for (var property in bindings) {
if (!bindings.hasOwnProperty(property)) { if (bindings.hasOwnProperty(property)) {
continue; this._registerSingleProperty(property);
} }
}
}
},


var bind = bindings[property]; _registerSingleProperty : function (property) {
if (bind) { var bindings = this._cfg.bind, bind = bindings[property], jsonUtils = aria.utils.Json;
var callback = { if (bind) {
fn : this._notifyDataChange, var callback = {
scope : this, fn : this._notifyDataChange,
args : property scope : this,
}; args : property
};


try { try {
jsonUtils.addListener(bind.inside, bind.to, callback, true); jsonUtils.addListener(bind.inside, bind.to, callback, true);


this._bindingListeners[property] = { this._bindingListeners[property] = {
inside : bind.inside, inside : bind.inside,
to : bind.to, to : bind.to,
transform : bind.transform, transform : bind.transform,
cb : callback cb : callback
}; };


var newValue = this._transform(bind.transform, bind.inside[bind.to], "toWidget"); var newValue = this._transform(bind.transform, bind.inside[bind.to], "toWidget");
this.setWidgetProperty(property, newValue); this.setWidgetProperty(property, newValue);
} catch (ex) { } catch (ex) {
this.$logError(this.INVALID_BEAN, [property, "bind"]); this.$logError(this.INVALID_BEAN, [property, "bind"]);
}
}
} }
} }
}, },
Expand Down
50 changes: 50 additions & 0 deletions src/aria/widgets/form/list/List.js
Expand Up @@ -221,6 +221,56 @@ Aria.classDefinition({
// (but this would not be backward-compatible with current list templates) // (but this would not be backward-compatible with current list templates)
this._subTplCtxt.$refresh(); this._subTplCtxt.$refresh();
} }
},

/**
* Register listeners for the bindings associated to this widget
* @protected
*/
_registerSingleProperty : function (property) {
var bindings = this._cfg.bind, bind = bindings[property];

if (bindings && bind && bindings.hasOwnProperty(property) && property === "items") {
var callback = {
fn : this._notifyDataChange,
scope : this,
args : property
};
try {
aria.utils.Json.addListener(bind.inside, bind.to, callback, true, true);
this._bindingListeners[property] = {
inside : bind.inside,
to : bind.to,
transform : bind.transform,
cb : callback
};

var newValue = this._transform(bind.transform, bind.inside[bind.to], "toWidget");
this._cfg[property] = newValue;
} catch (ex) {
this.$logError(this.INVALID_BEAN, [property, "bind"]);
}
} else {
this.$TemplateBasedWidget._registerSingleProperty.apply(this, arguments);
}
},

/**
* Set property for this widget, and reflect change on itself, but not in the associated datamodel
* @param {String} propertyName in the configuration
* @param {Object} newValue to set
*/
setWidgetProperty : function (propertyName, newValue) {
if (!this._cfg) {
return;
}
if (propertyName === "items" && this._cfg.bind.hasOwnProperty(propertyName)) {
var oldValue = this.getProperty(propertyName);
this._cfg[propertyName] = newValue;
this._onBoundPropertyChange(propertyName, newValue, oldValue);
} else {
this.$TemplateBasedWidget.setWidgetProperty.apply(this, arguments);
}
} }
} }
}); });
2 changes: 1 addition & 1 deletion test/aria/widgets/form/FormTestSuite.js
Expand Up @@ -25,7 +25,7 @@ Aria.classDefinition({
this.addTests("test.aria.widgets.form.GaugeTest"); this.addTests("test.aria.widgets.form.GaugeTest");
this.addTests("test.aria.widgets.form.InputTest"); this.addTests("test.aria.widgets.form.InputTest");
this.addTests("test.aria.widgets.form.InputValidationHandlerTest"); this.addTests("test.aria.widgets.form.InputValidationHandlerTest");
this.addTests("test.aria.widgets.form.ListControllerTest"); this.addTests("test.aria.widgets.form.list.ListTestSuite");
this.addTests("test.aria.widgets.form.numberfield.NumberFieldSuite"); this.addTests("test.aria.widgets.form.numberfield.NumberFieldSuite");
this.addTests("test.aria.widgets.form.PasswordFieldTest"); this.addTests("test.aria.widgets.form.PasswordFieldTest");
this.addTests("test.aria.widgets.form.TextareaTest"); this.addTests("test.aria.widgets.form.TextareaTest");
Expand Down
Expand Up @@ -14,7 +14,7 @@
*/ */


Aria.classDefinition({ Aria.classDefinition({
$classpath : "test.aria.widgets.form.ListControllerTest", $classpath : "test.aria.widgets.form.list.ListControllerTest",
$extends : "aria.jsunit.TestCase", $extends : "aria.jsunit.TestCase",
$dependencies : ["aria.widgets.form.list.ListController", "aria.DomEvent"], $dependencies : ["aria.widgets.form.list.ListController", "aria.DomEvent"],
$constructor : function () { $constructor : function () {
Expand Down
83 changes: 83 additions & 0 deletions test/aria/widgets/form/list/ListTestCase.js
@@ -0,0 +1,83 @@
/*
* 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.widgets.form.list.ListTestCase",
$extends : "aria.jsunit.TemplateTestCase",
$dependencies : ["aria.utils.Json"],
$constructor : function () {
this.$TemplateTestCase.constructor.call(this);
this.listContainer = null;
this.children = null;
this.data = {
italian : [{ value: "D", label: "Donizetti"}, { value: "B", label: "Bellini" }, { value: "V", label: "Verdi" }]
};
this.setTestEnv({
template : "test.aria.widgets.form.list.ListTestCaseTpl",
data : this.data
});
},
$destructor : function () {
this.listContainer = null;
this.children = null;
this.$TemplateTestCase.$destructor.call(this);
},
$prototype : {
runTemplateTest : function () {
this.listContainer = this.getWidgetDomElement("myId", "div");
this.children = this.getElementsByClassName(this.listContainer, "xListEnabledItem_std");

this.assertTrue(this.children.length === 3, "The number of list items is not 3");

if (aria.core.Browser.isIE && aria.core.Browser.majorVersion < 9) {
aria.core.Timer.addCallback({
fn: this.waitForIE,
scope: this,
delay: 500
});
} else {
this.addItem();
this.assertTrue(this.children.length === 4, "The item was not added to the DOM");

this.removeItem();
this.assertTrue(this.children.length === 3, "The item was not removed from the DOM");

this.notifyTemplateTestEnd();
}
},

waitForIE : function () {
this.addItem();
this.listContainer = this.getWidgetDomElement("myId", "div");
this.children = this.getElementsByClassName(this.listContainer, "xListEnabledItem_std");
this.assertTrue(this.children.length === 4, "The item was not added to the DOM");

this.removeItem();
this.listContainer = this.getWidgetDomElement("myId", "div");
this.children = this.getElementsByClassName(this.listContainer, "xListEnabledItem_std");
this.assertTrue(this.children.length === 3, "The item was not removed from the DOM");

this.notifyTemplateTestEnd();
},

addItem : function () {
aria.utils.Json.add(this.data.italian, { value: "p", label: "Puccini"});
},

removeItem : function () {
aria.utils.Json.removeAt(this.data.italian, 3);
}
}
});
40 changes: 40 additions & 0 deletions test/aria/widgets/form/list/ListTestCaseTpl.tpl
@@ -0,0 +1,40 @@
/*
* 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.
*/

{Template {
$classpath : "test.aria.widgets.form.list.ListTestCaseTpl",
$templates : ["aria.widgets.form.list.templates.ListTemplate"]
}}

{macro main()}

<div id="justToGetTheCorrectDom">

<p>List of Italian composers (bound to data model):</p>
{@aria:List {
id: "myId",
minWidth:200,
bind: {
items: {
to: "italian",
inside: data
}
}
}/}

</div>

{/macro}
{/Template}
24 changes: 24 additions & 0 deletions test/aria/widgets/form/list/ListTestSuite.js
@@ -0,0 +1,24 @@
/*
* 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.widgets.form.list.ListTestSuite",
$extends : "aria.jsunit.TestSuite",
$constructor : function () {
this.$TestSuite.constructor.call(this);
this.addTests("test.aria.widgets.form.list.ListControllerTest");
this.addTests("test.aria.widgets.form.list.ListTestCase");
}
});

0 comments on commit 1bc334f

Please sign in to comment.