diff --git a/addon/modal.js b/addon/modal.js index e480540e..c8322072 100644 --- a/addon/modal.js +++ b/addon/modal.js @@ -53,21 +53,21 @@ export default Ember.Object.extend({ }); -function currentParams(controller, paramNames) { - var params={}, - foundNonDefault = false, - proto = controller.constructor.proto(), - name, - value; +function currentParams(controller, paramMap) { + var params = {}; + var proto = controller.constructor.proto(); + var foundNonDefault = false; + var to, from, value; - for (var i = 0; i < paramNames.length; i++) { - name = paramNames[i]; - value = controller.get(name); - params[name] = value; - if (value !== proto[name]) { + for (from in paramMap) { + to = paramMap[from]; + value = controller.get(from); + params[to] = value; + if (value !== proto[from]) { foundNonDefault = true; } } + if (foundNonDefault) { return params; } diff --git a/addon/modals.js b/addon/modals.js index dc16f031..1dfaf8cc 100644 --- a/addon/modals.js +++ b/addon/modals.js @@ -19,13 +19,13 @@ export default Ember.Controller.extend({ registerModal: function(config) { var ext = { modals: this, - container: this.container, + container: this.container }; - config.options.withParams.forEach(function(param) { - ext[param + "Observer"] = Ember.observer('controller.' + param, function(){ - this.update(); - }); - }); + + for (var param in config.options.withParams) { + ext[param + "Observer"] = observerForParam(param); + } + this.get('modals').pushObject( Modal.extend(ext).create(config) ); @@ -43,3 +43,7 @@ export default Ember.Controller.extend({ }) }); + +function observerForParam(param) { + return Ember.observer('controller.' + param, function() { this.update(); }); +} \ No newline at end of file diff --git a/addon/router-dsl-ext.js b/addon/router-dsl-ext.js index 14177d32..d8ce5f84 100644 --- a/addon/router-dsl-ext.js +++ b/addon/router-dsl-ext.js @@ -10,9 +10,8 @@ proto.modal = function(componentName, opts) { opts = Ember.copy(opts); - if (!Ember.isArray(opts.withParams)) { - opts.withParams = [opts.withParams]; - } + opts.withParams = expandParamOptions(opts.withParams); + opts.otherParams = expandParamOptions(opts.otherParams); if (typeof(opts.dismissWithOutsideClick) === 'undefined') { opts.dismissWithOutsideClick = true; @@ -39,3 +38,35 @@ Router.reopenClass({ return output; } }); + +// takes string, array of strings, object, or array of objects and strings +// and turns them into one object to map withParams/otherParams from context to modal +// +// "foo" => { foo: "foo" } +// ["foo"] => { foo: "foo" } +// { foo: "bar" } => { foo: "bar" } +// ["foo", { bar: "baz" }] => { foo: "foo", bar: "baz" } +// +function expandParamOptions(options) { + if (!options) { return {}; } + + if (!Ember.isArray(options)) { + options = [options]; + } + + var params = {}; + var option, i, key; + + for (i = 0; i < options.length; i++) { + option = options[i]; + if (typeof option === "object") { + for (key in option) { + params[key] = option[key]; + } + } else { + params[option] = option; + } + } + + return params; + } \ No newline at end of file diff --git a/app/components/liquid-modal.js b/app/components/liquid-modal.js index 06caeb43..873c9f3e 100644 --- a/app/components/liquid-modal.js +++ b/app/components/liquid-modal.js @@ -20,6 +20,18 @@ export default Ember.Component.extend({ self.set('innerViewInstance', this); }); + // set source so we can bind other params to it + args._source = Ember.computed(function() { + return current.get("source"); + }); + + var otherParams = current.get("options.otherParams"); + var from, to; + for (from in otherParams) { + to = otherParams[from]; + args[to] = Ember.computed.alias("_source."+from); + } + var actions = current.get("options.actions") || {}; // Override sendAction in the modal component so we can intercept and diff --git a/tests/acceptance/demos-test.js b/tests/acceptance/demos-test.js index 2856d794..8b9c9b5e 100644 --- a/tests/acceptance/demos-test.js +++ b/tests/acceptance/demos-test.js @@ -173,6 +173,17 @@ test('modal demo', function() { }); }); +test('modal demo with bound otherParams', function() { + visit('/modals'); + click('#basic-modal-demo button'); + andThen(function(){ + fillIn('.modal-input', 'some new text'); + }); + andThen(function(){ + ok(find('.template-input').val() === 'some new text', "Bound value has updated"); + }); +}); + test('warn-popup - dismiss with overlay', function() { visit('/modals?warn=1'); andThen(function(){ diff --git a/tests/dummy/app/controllers/modal-documentation.js b/tests/dummy/app/controllers/modal-documentation.js index 33ebb5cb..dc1da839 100644 --- a/tests/dummy/app/controllers/modal-documentation.js +++ b/tests/dummy/app/controllers/modal-documentation.js @@ -3,6 +3,7 @@ import Ember from "ember"; export default Ember.Controller.extend({ queryParams: ['salutation', 'person'], salutation: null, - person: null + person: null, + modalMessage: "bound text for modal" }); // END-SNIPPET diff --git a/tests/dummy/app/controllers/modal-documentation/index.js b/tests/dummy/app/controllers/modal-documentation/index.js new file mode 100644 index 00000000..02aeb62d --- /dev/null +++ b/tests/dummy/app/controllers/modal-documentation/index.js @@ -0,0 +1,6 @@ +import Ember from 'ember'; + +export default Ember.ObjectController.extend({ + needs: ["modalDocumentation"], + modalMessage: Ember.computed.alias("controllers.modalDocumentation.modalMessage") +}); \ No newline at end of file diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index 81b4fc36..d4f9df35 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -43,6 +43,9 @@ Router.map(function() { // BEGIN-SNIPPET hello-modal-map this.modal('hello-modal', { withParams: ['salutation', 'person'], + otherParams: { + modalMessage: "message" + }, actions: { changeSalutation: "changeSalutation" } diff --git a/tests/dummy/app/templates/components/hello-modal.hbs b/tests/dummy/app/templates/components/hello-modal.hbs index 9ef7e713..0db78872 100644 --- a/tests/dummy/app/templates/components/hello-modal.hbs +++ b/tests/dummy/app/templates/components/hello-modal.hbs @@ -1,5 +1,6 @@ {{!- BEGIN-SNIPPET hello-modal -}}
+ Bound value: {{input value=modalMessage class="template-input"}} +
+ The property names that will be passed to the component. + We will show the component whenever any of these has a non-default value. + This can be a string, an array of strings, an object or an array of strings and objects. +
+
+ If given an object, the key is the property name on the controller and the value
+ will be the name this is accessed as in the modal component.
+ For example, the following will map foo
in the controller to foo
in the modal,
+ and bar
in the controller to baz
in the modal.
+
+withParams: ["foo", { + bar: "baz" +}]+
modal()
.
+ default we use the default controller name for the scope in which
+ you call modal()
.
+