How to force javascript variable to be interpreted as an attribute in underscore patterns

Suppose I have the following attributes being passed to the underscore pattern: name

and animaltype

. I also have an attribute that depends on the type of animals. So, for example, if animaltype is CAT, then the attribute is named cat_id

. If animaltype is DOG, then attribute dog_id

, etc.

I'm creating an input field for each of the animal type IDs, but only the field with the corresponding animal type ID needs to be filled in (displayed via attributes). This ID input field is one I cannot get to match the attribute value because I am using javascript to generate the attribute name to be expected. So instead of the name of the corresponding attribute value that matches the javascript variable name, the actual javascript variable name is inserted.

Here is a fiddle http://jsfiddle.net/leopardy/fev4vqmg/1/

What should I get - Name: Furry
Type: CAT
CAT ID: 005
DOG ID:
BIRD ID:

What I actually get - Name: Fluffy
Type: CAT
CAT ID: cat_id
DOG ID:
BIRD ID:
where the cat_id attribute was not allowed in the template.

As a main note in my real code, I am hiding other ID input fields that do not match the type of animal, but for the sake of simplicity, I did not include hiding / showing.

+3


source to share


2 answers


You have a common problem "I have a variable in another variable" and the solution is the same as always: supply the things you need to look for by name in the lookup table (ie an object in JavaScript).

In your case, I wouldn't _.extend(attributes, {animalTypes:animalTypes});

dump everything in one heap, I would separate attributes

and animalTypes

separate so that your call _.template

looks like this:

var tmpl = _.template(template);
var html = tmpl({
    animalTypes: animalTypes,
    attributes: attributes
});

      

Now you can say things like attributes['cat_id']

in your template. Of course, you will have to address everything through animalTypes

or attributes

, but this is rather minor. Your template will look something like this:



<table>
    <tbody>
            <tr>
                <td>Name:</td>
                <td>
                    <input name="name" type="text" value="<%= attributes.name %>"/>
                </td>
            </tr>
            <tr>
                <td>Type:</td>
                <td>
                    <input name="animal_type" type="text" value="<%= attributes.animaltype %>"/>
                </td>
           </tr>
           <% for (var key in animalTypes) { %>
               <% var typeID= (key).toLowerCase() +"_id" %>
               <tr>
                   <td><%= key %> ID:</td>
                   <% if (attributes.animaltype === key) { %> 
                       <td>
                           <input value="<%= attributes[typeID] %>" name="<%= typeID %>" type="text"/>
                       </td>
                   <% } else { %>
                       <td>
                           <input value="" name="<%= typeID %>" type="text"/>
                       </td>
                   <% } %>
               </tr>
           <% } %>
    </tbody>
</table>

      

The part that solves your immediate problem:

<input value="<%= attributes[typeID] %>" name="<%= typeID %>" type="text"/>

      

Demo updated: http://jsfiddle.net/ambiguous/qj3ru1mL/1/

+1


source


It's actually pretty straight forward

EDIT use arguments [0] [typeId]

 <input value="<%= arguments[0][typeID] %>" name=<%= (key).toLowerCase() +"_id"%> type="text"/>

      



Don't use eval even if no one yells at you;) Here's a link to a working fiddle: http://jsfiddle.net/j872q5gm/1/

Thanks to @Adrian Lynch for reminding me that I am a good JS citizen;)

+1


source







All Articles