webui: field and widget binding refactoring

This is a Web UI wide change. Fields and Widgets binding was refactored
to enable proper two-way binding between them. This should allow to have
one source of truth (field) for multiple consumers - widgets or something
else. One of the goal is to have fields and widget implementations
independent on each other. So that one could use a widget without field
or use one field for multiple widgets, etc..

Basically a fields logic was split into separate components:
- adapters
- parsers & formatters
- binder

Adapters
- extract data from data source (FreeIPA RPC command result)
- prepares them for commands.

Parsers
- parse extracted data to format expected by field
- parse widget value to format expected by field

Formatters
- format field value to format suitable for widgets
- format field value to format suitable for adapter

Binder
- is a communication bridge between field and widget
- listens to field's and widget's events and call appropriate methods

Some side benefits:
- better validation reporting in multivalued widget

Reviewed-By: Adam Misnyovszki <amisnyov@redhat.com>
This commit is contained in:
Petr Vobornik
2013-11-13 15:49:25 +01:00
parent 66fb4d5e84
commit 0d05a50e19
25 changed files with 1764 additions and 944 deletions

View File

@@ -24,12 +24,12 @@ define([
'freeipa/jquery',
'freeipa/details',
'freeipa/facet',
'freeipa/field',
'freeipa/reg',
'freeipa/rpc',
'freeipa/entity',
'freeipa/field',
'freeipa/widget'],
function(md, IPA, $, mod_details, mod_facet, reg, rpc) {
function(md, IPA, $, mod_details, mod_facet, mod_field, reg, rpc) {
return function() {
var details_container;
@@ -41,6 +41,7 @@ module('details', {
mod_facet.register();
mod_details.register();
mod_field.register();
IPA.init({
url: 'data',
@@ -255,7 +256,10 @@ test("Testing details lifecycle: create, load.", function(){
ok (load_called, 'load manager called');
var field = facet.fields.get_field('test');
field.set_dirty(true);
field.set_value("foo");
var widget = facet.widgets.get_widget('contact.test');
// simulate user change
widget.emit('value-change', { source: widget, value: "foo" });
facet.update(
function(){update_success_called = true;},