3

Lets say I have a the following attributes being passed in to an underscore template: name and animaltype. I also have an attribute that varies based on the animaltype. So for example, if animaltype is CAT, then the attribute is called cat_id. If is the animaltype is DOG, then the attribute is dog_id and so on.

I create an input box for each of the animaltype ids but only the box that has an id of the corresponding animaltype should be populated(mapped in via attributes). This ID input box is the one I cannot get to map to the attribute value because I am using javascript to create the name of the attribute is should be expecting. Therefore the actual javascript variable name is being inserted instead of the corresponding resolved attribute value that matches the javascript variable name.

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

What I should get is
Name: Fluffy
Type: CAT
CAT ID: 005
DOG ID:
BIRD ID:

What I really get is
Name: Fluffy
Type: CAT
CAT ID: cat_id
DOG ID:
BIRD ID:
where the cat_id attribute did not resolve in the template.

As a side note, in my real code I am hiding the other ID input boxes that don't correspond to the animal type but for the sake of keeping things simpler, I didn't including the hiding/showing.

1
  • 1
    Can you change the data before it's passed to the template? Commented Sep 15, 2014 at 5:16

2 Answers 2

1

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

In your case, I would not _.extend(attributes, {animalTypes:animalTypes}); to mash everything into one pile, I would leave attributes and animalTypes separate so that your _.template call would look 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'll have to refer to everything through animalTypes or attributes but that's pretty minor. Your template would 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 the solves your immediate problem is:

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

Updated demo: http://jsfiddle.net/ambiguous/qj3ru1mL/1/

Sign up to request clarification or add additional context in comments.

1 Comment

I believe making code more readable and understandable is a better approach and this is the cleanest way to do it, in my eyes, which is why I made this the answer.
1

It's actually quite 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 screams at you ;) Here's a link to the working fiddle: http://jsfiddle.net/j872q5gm/1/

Thanks @Adrian Lynch for reminding me to be a good JS citizen ;)

2 Comments

If anyone screams at you for using eval(), you could always access it as: arguments[0][key.toLowerCase() + "_id"]
I had a difficult time deciding which answer to accept. This is a good answer. Thank you. Overall I feel like my problems stemmed from the "variable name in another variable" issue I introduced and figured fixing that issue first would solve my original problem in a very clean and understandable way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.