I'm trying to write a generic view that handles custom fields in my app, but I'm having a hard time getting this to work. Here's the scenario - I have a fieldDef
object which defines the custom fields, and a valueObject
which has an array, customFields
, which has the values. What I'm trying to do is something like this:
{{view Ember.TextField valueBinding="valueObject.customFields.[fieldDef.name]"}}
Obviously that doesn't work because it treats fieldDef.name
as a literal. I've tried overriding the TextField class, but can't seem to get it to bind.
Any suggestions on how to accomplish this?
Thanks, Scott
Ember can't bind to an array index, so you'll have to work around it. One solution is to limit yourself to a one-way binding, where your textfield updates the values hash. If you're planning to submit the form after the user presses a button, this should do the trick.
Define an array of field ids in your controller and a hash for their values to go in.
App.ApplicationController = Ember.Controller.extend({
fieldIds: ['name', 'email', 'whatever'],
fieldValues: {} // {name: 'user', email: 'user@...', ...}
});
Now extend Ember.TextField
to update your values hash when a text field changes. You'll need to pass each instance a fieldId
and a reference to the values
hash from your controller.
App.TextField = Ember.TextField.extend({
fieldId: null,
values: null,
valueChange: function() {
var fieldId = this.get('fieldId');
var values = this.get('values');
if (values && fieldId) values[fieldId] = this.get('value');
}.observes('value')
});
The template is simple.
{{#each fieldId in fieldIds}}
<label>{{fieldId}}</label>
{{view App.TextField fieldIdBinding="fieldId" valuesBinding="fieldValues"}}
<br/>
{{/each}}
Here it is fleshed out in a jsfiddle.
@ahmacleod great answer man. Just in case anyone is interested it works great extending select too:
import Ember from 'ember';
export default Ember.Select.extend({
fieldId: null,
values: null,
valueChange: function() {
var fieldId = this.get('fieldId');
var values = this.get('values');
if (values && fieldId) values[fieldId] = this.get('value');
}.observes('value')
});
Call it as an normal component (components/dynamic-select.js)
{{#each id in fieldIds}}
{{dynamic-select content=fieldIds fieldIdBinding="header"
valuesBinding="fields"}}
{{/each}}
You can bind input values with dynamic keys(variables) of objects with help of mut helper now.
https://guides.emberjs.com/v2.6.0/templates/input-helpers/#toc_binding-dynamic-attribute
You can access it like this,
var Object = {};
var key = "firstName";
We can bind key in input helper like this,
{{input value=(mut (get Object key))}}
{{Object.firstName}} // Prints the dynamic value in textbox
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With