Ignore:
Timestamp:
03/13/14 22:21:55 (11 years ago)
Author:
hendrikvanantwerpen
Message:
  • Another shot at getting change events right for _ComplexValueMixin. Our previous approach made it impossible to detect if a change was cause during startup. Now we work purely with widget 'change' events. Children are connected during postCreate, addChild. If you add children otherwise you need to call connectChildsChanges yourself. Also to make sure events are generated, use _setValueInternal if you really need to set the value attribute yourself.
  • Removed unused widget.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/client/qed-client/widgets/_ComplexValueMixin.js

    r512 r513  
    2020        },
    2121        buildRendering: function() {
    22             // capture child change events
     22            // capture child events
    2323            this.inherited(arguments);
    24             this.own(on(this.domNode,'change',
    25                         lang.hitch(this,'_handleChange')));
     24            if ( this.domNode.tagName.toLowerCase() !== "form" ) {
     25                console.warn("Not scoping a _ComplexValueMixin in a form element can cause name clashes. E.g. radio buttons might stop working correctly. It is recommended to use <form> as the root element in your template for", this.declaredClass);
     26            }
     27            this.own(on(this.domNode,'submit',
     28                        lang.hitch(this,'_handleSubmit')));
    2629        },
    2730        create: function() {
     
    3033        },
    3134        postCreate: function() {
    32             this.inherited(arguments);
    33             if ( this.domNode.tagName.toLowerCase() !== "form" ) {
    34                 console.warn("Not scoping a _ComplexValueMixin in a form element can cause name clashes. E.g. radio buttons might stop working correctly. It is recommended to use <form> as the root element in your template for", this.declaredClass);
    35             }
    36             this.own(on(this.domNode, 'submit', lang.hitch(this,'_handleSubmit')));
     35            array.forEach(this._getDescendantFormWidgets(),
     36                          this.connectChildsChanges,
     37                          this);
    3738        },
    38         startup: function() {
    39             if (this._started) { return; }
    40             this.inherited(arguments);
    41         },
    42         _setDisabledAttr: function(value) {
    43             this._set("disabled", value);
    44             array.forEach(this._getDescendantFormWidgets(), function(child) {
    45                 child.set("disabled", value);
    46             });
    47         },
    48         _getValueAttr: function() {
    49             this.value = this.inherited(arguments);
    50             return this.value;
     39        connectChildsChanges: function(child) {
     40            this.own(child.on('change',
     41                              lang.hitch(this,'_handleChildChange')));
    5142        },
    5243        // Yuk, _setValueAttr is taken directly from _FromMixin only
    5344        // to add the priorityChange parameter
    5445                _setValueAttr: function(obj, priorityChange) {
    55             this.value = obj;
     46            this._setValueInternal(obj, priorityChange);
    5647
    5748                        var map = { };
     
    8475                                }
    8576                        }
     77           
     78            if ( priorityChange !== null ) {
     79                this._handleOnChange(this.value);
     80            }
    8681                },
    87         _setReadOnlyAttr: function(value) {
    88             this._set("readOnly", value);
    89             array.forEach(this._getDescendantFormWidgets(), function(child) {
    90                 child.set("readOnly", value);
    91             });
     82        // use _setValueInternal instead of 'this.value = ?' or
     83        // 'this._set('value',?)' so proper events will be generated.
     84        _setValueInternal: function(value,priorityChange) {
     85            this._set('value',value);
     86            if ( priorityChange !== null ){
     87                this._handleOnChange(this.value);
     88            }
    9289        },
     90        _setDisabledAttr: function(disabled) {
     91            this.inherited(arguments);
     92            array.forEach(
     93                this._getDescendantFormWidgets(),
     94                function(child) {
     95                    child.set('disabled', disabled);
     96                },this);
     97        },
     98        _setReadOnlyAttr: function(readOnly) {
     99            this.inherited(arguments);
     100            array.forEach(
     101                this._getDescendantFormWidgets(),
     102                function(child) {
     103                    child.set('readOnly', readOnly);
     104                },this);
     105        },
     106
    93107        focus: function() {
    94108            /*var children = this._getDescendantFormWidgets();
     
    97111            }*/
    98112        },
    99         _handleChange: function(evt) {
    100             if ( evt.target !== this.domNode ) {
    101                 this.triggerOnChange();
    102                 if ( evt ) { event.stop(evt); }
    103                 return false;
    104             } else {
    105                 return evt;
    106             }
     113        addChild: function(child) {
     114            this.inherited(arguments);
     115            this.connectChildsChanges(child);
    107116        },
     117
    108118        _handleSubmit: function(evt) {
    109             var node = this.domNode;
    110             var widget;
    111             while ( node ) {
    112                 node = node.parentNode;
    113                 widget = registry.byNode(node);
    114                 if ( widget && typeof widget._onSubmit === "function" ) {
    115                     widget._onSubmit(evt);
    116                     break;
     119            if ( this._started ) {
     120                var node = this.domNode;
     121                var widget;
     122                while ( node ) {
     123                    node = node.parentNode;
     124                    widget = registry.byNode(node);
     125                    if ( widget &&
     126                         typeof widget._onSubmit === "function" ) {
     127                        widget._onSubmit(evt);
     128                        break;
     129                    }
    117130                }
    118131            }
     
    120133            return false;
    121134        },
    122         triggerOnChange: function() {
     135        _handleChildChange: function() {
     136            this._setValueInternal(this.get('value'));
     137            return false;
     138        },
     139        _handleOnChange: function(value) {
    123140            if ( this._onChangeActive &&
    124141                 !(this.readOnly || this.disabled) ) {
    125142                if ( this._onChangeHandle ) {
    126                     this._onChangeHandle.cancel();
     143                    this._onChangeHandle.remove();
    127144                }
    128145                this._onChangeHandle = this.defer(function(){
    129146                    this._onChangeHandle = null;
    130                     on.emit(this.domNode,'change',{
    131                         target: this.domNode,
    132                         value: this.get('value'),
    133                         bubbles: true,
    134                         cancellable: true
    135                     });
     147                    this.onChange(value);
    136148                });
    137149            }
    138         }
     150        },
     151        onChange: function() {}
    139152    });
    140153});
Note: See TracChangeset for help on using the changeset viewer.