Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember TextField valueBinding with dynamic property

Tags:

ember.js

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

like image 740
Scott Rankin Avatar asked Mar 01 '13 16:03

Scott Rankin


3 Answers

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.

like image 150
ahmacleod Avatar answered Sep 22 '22 14:09

ahmacleod


@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}}
like image 26
Seosamh Avatar answered Sep 21 '22 14:09

Seosamh


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
like image 22
Manu Benjamin Avatar answered Sep 22 '22 14:09

Manu Benjamin