0
votes

I have a few input fields being displayed programatically via the Ember each helper. These inputs are related to data being returned from my database, and I have a corresponding unique ID for each input that I could use if necessary.

My question is how can I store the value of these dynamically generated inputs on my controller so that I can access the user's input data? I was trying to do something like this:

{{#each solutionTypes as |solutionType|}}
    {{input value=inputData[solutionType.id]}}
{{/each}}

However, trying to access an object or array in this manner causes a build error related to the the above syntax in specifying the value (object dot notation causes a build error too).

In short, I am trying to save the value of the input field as a property on an object or in an array instead of as a plain variable on the controller. I would like the input data from all of the inputs in the form to be accessible from the "inputData" variable in the following form:

{
    "1000": "data from first input",
    "1001": "data from second input",
    "1002": "data from third input"
}

The primary issue is utilizing the dynamic keys (from solutionType.id) in the handlebars code without getting a build error.

If this is not possible using the value attribute but you know how to accomplish this with actions or with something else, I'm more than open to your ideas.

2

2 Answers

2
votes

The question is a tad confusing so I'll answer in both ways I interpreted your question.

Two-way binding

The {{input}} helper establishes a two way binding with the value so in your example:

{{input value=solutionType.value}}

will bind the solutionType.value to the input. Not only will it display that value but it means as the user types into the input it will update solutionType.value.

One-way bindings (Data Down Actions Up)

Based on your use of inputData being different then solutionType I assume you want a one way binding.

The community standard is to use Data Down Actions Up in such that the solutionType.value does not change as the user enters data but instead sends an action back up so you can manage it as you see fit.

Unfortunately the current Ember {{input}} helper does not support this. There is an addon called ember-one-way-controls which will do this for you. You might want to experiment with that.

A caveat with the above addon is that you will have to manage the solutionTypes data manually as the actions come back up.

Ultimately you will have to decide just how tightly coupled the data you display via an input field is to the data you expect the user to type and adjust your design accordingly.

1
votes

Yes. You can utilize the dynamic keys (from solutionType.id) in the handlebars code without getting a build error by using get and mut helper it's possible. ember-twiddle

For two way binding,

{{input value=(mut (get inputData (get solutionType 'id'))) }}

For one way binding,

{{input value=(get inputData (get solutionType 'id')) }}

routes/application.js

import Ember from 'ember';

export default Ember.Route.extend({
  model(){
    return [{id:'1000'},{id:'1001'},{id:'1002'}];
  },
  setupController(controller,model){
    this._super(...arguments);
    controller.set('solutionTypes',model);
  }
});

controllers/application.js

import Ember from 'ember';

export default Ember.Controller.extend({
  appName: 'Ember Twiddle',
  inputData:{'1000': "data from first input", '1001': "data from second input",'1002': "data from third input"},  
});

templates/application.hbs

<h1>Welcome to {{appName}}</h1>
<br>

<h1> One way binding </h1>
{{#each solutionTypes as |solutionType|}}
 {{input value=(get inputData (get solutionType 'id')) }}
{{/each}}

<h2> Two way binding </h2>
{{#each solutionTypes as |solutionType|}}
 {{input value=(mut (get inputData (get solutionType 'id'))) }}
{{/each}}
<br>
<h2> Result </h2>
 {{#each solutionTypes as |solutionType|}}     
   <span> {{get inputData (get solutionType 'id')}} </span>
 {{/each}}
 <br />
{{outlet}}
<br>
<br>