[483] | 1 | define([ |
---|
| 2 | "dojo/_base/declare", |
---|
| 3 | "dojo/_base/lang", |
---|
| 4 | "./getPlainValue", |
---|
| 5 | "./getStateful", |
---|
| 6 | "./ModelRefController" |
---|
| 7 | ], function(declare, lang, getPlainValue, getStateful, ModelRefController){ |
---|
| 8 | // module: |
---|
| 9 | // dojox/mvc/EditModelRefController |
---|
| 10 | |
---|
| 11 | function setRefSourceModel(/*dojox/mvc/EditModelRefController*/ ctrl, /*Anything*/ old, /*Anything*/ current){ |
---|
| 12 | // summary: |
---|
| 13 | // A function called when this controller gets newer value as the data source. |
---|
| 14 | // ctrl: dojox/mvc/EditModelRefController |
---|
| 15 | // The controller. |
---|
| 16 | // old: Anything |
---|
| 17 | // The older value. |
---|
| 18 | // current: Anything |
---|
| 19 | // The newer value. |
---|
| 20 | |
---|
| 21 | if(old !== current){ |
---|
| 22 | ctrl.set(ctrl._refOriginalModelProp, ctrl.holdModelUntilCommit ? current : ctrl.cloneModel(current)); |
---|
| 23 | ctrl.set(ctrl._refEditModelProp, ctrl.holdModelUntilCommit ? ctrl.cloneModel(current) : current); |
---|
| 24 | } |
---|
| 25 | } |
---|
| 26 | |
---|
| 27 | return declare("dojox.mvc.EditModelRefController", ModelRefController, { |
---|
| 28 | // summary: |
---|
| 29 | // A child class of dojox/mvc/ModelRefController. |
---|
| 30 | // Keeps a copy (originalModel) of given data model (sourceModel) so that it can manage the data model of before/after the edit. |
---|
| 31 | // description: |
---|
| 32 | // Has two modes: |
---|
| 33 | // |
---|
| 34 | // - Directly reflect the edits to sourceModel (holdModelUntilCommit=false) |
---|
| 35 | // - Don't reflect the edits to sourceModel, until commit() is called (holdModelUntilCommit=true) |
---|
| 36 | // |
---|
| 37 | // For the 1st case, dojo/Stateful get()/set()/watch() interfaces will work with sourceModel. |
---|
| 38 | // For the 2nd case, dojo/Stateful get()/set()/watch() interfaces will work with a copy of sourceModel, and sourceModel will be replaced with such copy when commit() is called. |
---|
| 39 | // |
---|
| 40 | // NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins. |
---|
| 41 | // example: |
---|
| 42 | // The check box refers to "value" property in the controller (with "ctrl" ID). |
---|
| 43 | // The controller provides the "value" property on behalf of the model ("model" property in the controller, which comes from "sourceModel" property). |
---|
| 44 | // Two seconds later, the check box changes from unchecked to checked, and the controller saves the state. |
---|
| 45 | // Two seconds later then, the check box changes from checked to unchecked. |
---|
| 46 | // Two seconds later then, the controller goes back to the last saved state, and the check box changes from unchecked to checked as the result. |
---|
| 47 | // | <html> |
---|
| 48 | // | <head> |
---|
| 49 | // | <script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script> |
---|
| 50 | // | <script type="text/javascript"> |
---|
| 51 | // | require([ |
---|
| 52 | // | "dojo/dom", "dojo/parser", "dojo/Stateful", "dijit/registry", "dijit/form/CheckBox", "dojox/mvc/EditModelRefController", "dojo/domReady!" |
---|
| 53 | // | ], function(ddom, parser, Stateful, registry){ |
---|
| 54 | // | model = new Stateful({value: false}); |
---|
| 55 | // | setTimeout(function(){ |
---|
| 56 | // | ddom.byId("check").click(); |
---|
| 57 | // | registry.byId("ctrl").commit(); |
---|
| 58 | // | setTimeout(function(){ |
---|
| 59 | // | ddom.byId("check").click(); |
---|
| 60 | // | setTimeout(function(){ |
---|
| 61 | // | registry.byId("ctrl").reset(); |
---|
| 62 | // | }, 2000); |
---|
| 63 | // | }, 2000); |
---|
| 64 | // | }, 2000); |
---|
| 65 | // | parser.parse(); |
---|
| 66 | // | }); |
---|
| 67 | // | </script> |
---|
| 68 | // | </head> |
---|
| 69 | // | <body> |
---|
| 70 | // | <script type="dojo/require">at: "dojox/mvc/at"</script> |
---|
| 71 | // | <span id="ctrl" data-dojo-type="dojox/mvc/EditModelRefController" data-dojo-props="sourceModel: model"></span> |
---|
| 72 | // | <input id="check" type="checkbox" data-dojo-type="dijit/form/CheckBox" data-dojo-props="checked: at('widget:ctrl', 'value')"> |
---|
| 73 | // | </body> |
---|
| 74 | // | </html> |
---|
| 75 | // example: |
---|
| 76 | // The controller with "ctrlSource" ID specifies holding changes until commit() is called (by setting true to holdModelUntilCommit). |
---|
| 77 | // As the change in the second check box is committed two seconds later from the change, the first check box is checked at then (when the change is committed). |
---|
| 78 | // | <html> |
---|
| 79 | // | <head> |
---|
| 80 | // | <script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script> |
---|
| 81 | // | <script type="text/javascript"> |
---|
| 82 | // | require([ |
---|
| 83 | // | "dojo/dom", "dojo/parser", "dojo/Stateful", "dijit/registry", |
---|
| 84 | // | "dijit/form/CheckBox", "dojox/mvc/ModelRefController", "dojox/mvc/EditModelRefController", "dojo/domReady!" |
---|
| 85 | // | ], function(ddom, parser, Stateful, registry){ |
---|
| 86 | // | model = new Stateful({value: false}); |
---|
| 87 | // | setTimeout(function(){ |
---|
| 88 | // | ddom.byId("checkEdit").click(); |
---|
| 89 | // | setTimeout(function(){ |
---|
| 90 | // | registry.byId("ctrlEdit").commit(); |
---|
| 91 | // | }, 2000); |
---|
| 92 | // | }, 2000); |
---|
| 93 | // | parser.parse(); |
---|
| 94 | // | }); |
---|
| 95 | // | </script> |
---|
| 96 | // | </head> |
---|
| 97 | // | <body> |
---|
| 98 | // | <script type="dojo/require">at: "dojox/mvc/at"</script> |
---|
| 99 | // | <span id="ctrlSource" data-dojo-type="dojox/mvc/ModelRefController" data-dojo-props="model: model"></span> |
---|
| 100 | // | <span id="ctrlEdit" data-dojo-type="dojox/mvc/EditModelRefController" |
---|
| 101 | // | data-dojo-props="sourceModel: at('widget:ctrlSource', 'model'), holdModelUntilCommit: true"></span> |
---|
| 102 | // | Source: |
---|
| 103 | // | <input id="checkSource" type="checkbox" data-dojo-type="dijit/form/CheckBox" |
---|
| 104 | // | data-dojo-props="checked: at('widget:ctrlSource', 'value')"> |
---|
| 105 | // | Edit: |
---|
| 106 | // | <input id="checkEdit" type="checkbox" data-dojo-type="dijit/form/CheckBox" |
---|
| 107 | // | data-dojo-props="checked: at('widget:ctrlEdit', 'value')"> |
---|
| 108 | // | </body> |
---|
| 109 | // | </html> |
---|
| 110 | |
---|
| 111 | // getStatefulOptions: dojox/mvc/getStatefulOptions |
---|
| 112 | // The options to get stateful object from plain value. |
---|
| 113 | getStatefulOptions: null, |
---|
| 114 | |
---|
| 115 | // getPlainValueOptions: dojox/mvc/getPlainValueOptions |
---|
| 116 | // The options to get plain value from stateful object. |
---|
| 117 | getPlainValueOptions: null, |
---|
| 118 | |
---|
| 119 | // holdModelUntilCommit: Boolean |
---|
| 120 | // True not to send the change in model back to sourceModel until commit() is called. |
---|
| 121 | holdModelUntilCommit: false, |
---|
| 122 | |
---|
| 123 | // originalModel: dojo/Stateful |
---|
| 124 | // The data model, that serves as the original data. |
---|
| 125 | originalModel: null, |
---|
| 126 | |
---|
| 127 | // originalModel: dojo/Stateful |
---|
| 128 | // The data model, that serves as the data source. |
---|
| 129 | sourceModel: null, |
---|
| 130 | |
---|
| 131 | // _refOriginalModelProp: String |
---|
| 132 | // The property name for the data model, that serves as the original data. |
---|
| 133 | _refOriginalModelProp: "originalModel", |
---|
| 134 | |
---|
| 135 | // _refSourceModelProp: String |
---|
| 136 | // The property name for the data model, that serves as the data source. |
---|
| 137 | _refSourceModelProp: "sourceModel", |
---|
| 138 | |
---|
| 139 | // _refEditModelProp: String |
---|
| 140 | // The property name for the data model, that is being edited. |
---|
| 141 | _refEditModelProp: "model", |
---|
| 142 | |
---|
| 143 | postscript: function(/*Object?*/ params, /*DomNode|String?*/ srcNodeRef){ |
---|
| 144 | // summary: |
---|
| 145 | // Sets certain properties before setting models. |
---|
| 146 | |
---|
| 147 | for(var s in {getStatefulOptions: 1, getPlainValueOptions: 1, holdModelUntilCommit: 1}){ |
---|
| 148 | var value = (params || {})[s]; |
---|
| 149 | if(typeof value != "undefined"){ |
---|
| 150 | this[s] = value; |
---|
| 151 | } |
---|
| 152 | } |
---|
| 153 | this.inherited(arguments); |
---|
| 154 | }, |
---|
| 155 | |
---|
| 156 | set: function(/*String*/ name, /*Anything*/ value){ |
---|
| 157 | // summary: |
---|
| 158 | // Set a property to this. |
---|
| 159 | // name: String |
---|
| 160 | // The property to set. |
---|
| 161 | // value: Anything |
---|
| 162 | // The value to set in the property. |
---|
| 163 | |
---|
| 164 | if(name == this._refSourceModelProp){ |
---|
| 165 | setRefSourceModel(this, this[this._refSourceModelProp], value); |
---|
| 166 | } |
---|
| 167 | this.inherited(arguments); |
---|
| 168 | }, |
---|
| 169 | |
---|
| 170 | cloneModel: function(/*Anything*/ value){ |
---|
| 171 | // summary: |
---|
| 172 | // Create a clone object of the data source. |
---|
| 173 | // Child classes of this controller can override it to achieve its specific needs. |
---|
| 174 | // value: Anything |
---|
| 175 | // The data serving as the data source. |
---|
| 176 | |
---|
| 177 | var plain = lang.isFunction((value || {}).set) && lang.isFunction((value || {}).watch) ? getPlainValue(value, this.getPlainValueOptions) : value; |
---|
| 178 | return getStateful(plain, this.getStatefulOptions); |
---|
| 179 | }, |
---|
| 180 | |
---|
| 181 | commit: function(){ |
---|
| 182 | // summary: |
---|
| 183 | // Send the change back to the data source. |
---|
| 184 | |
---|
| 185 | this.set(this.holdModelUntilCommit ? this._refSourceModelProp : this._refOriginalModelProp, this.cloneModel(this.get(this._refEditModelProp))); |
---|
| 186 | }, |
---|
| 187 | |
---|
| 188 | reset: function(){ |
---|
| 189 | // summary: |
---|
| 190 | // Change the model back to its original state. |
---|
| 191 | |
---|
| 192 | this.set(this.holdModelUntilCommit ? this._refEditModelProp : this._refSourceModelProp, this.cloneModel(this.get(this._refOriginalModelProp))); |
---|
| 193 | }, |
---|
| 194 | |
---|
| 195 | hasControllerProperty: function(/*String*/ name){ |
---|
| 196 | // summary: |
---|
| 197 | // Returns true if this controller itself owns the given property. |
---|
| 198 | // name: String |
---|
| 199 | // The property name. |
---|
| 200 | |
---|
| 201 | return this.inherited(arguments) || name == this._refOriginalModelProp || name == this._refSourceModelProp; |
---|
| 202 | } |
---|
| 203 | }); |
---|
| 204 | }); |
---|