4
\$\begingroup\$

I currently have what seems to be a very overly complicated underscore template full of conditionals and as the data grows I'm worried the conditions are going to get more and more extreme. Can anyone advise how I could make this template logic a little easier for my inputs, right now I'm running if...else just to make sure a value is either present or not!

An example model would look like:

{
        "id": "4V6",
        "name": "LATOUR TRADING LLC",
        "exchanges": [
            {
                "code": "BMD",
                "clearingFirm": {
                    "id": "CF-1",
                    "name": "ABN AMRO"
                }
            },
            {
                "code": "CBOT",
                "clearingFirm": {
                    "id": "AA-7",
                    "name": "ABN Agro"
                }
            }],
       "contacts": [
          {
            "clearingFirmId": "CF-1",
            "name": "Joe Bloggs",
            "email": "joe.bloggs@abnamro.com",
            "phone": "0800 ABN ROCKS"
         }
       ]
}

An example exchange would look like:

[ {
  "id" : "CF-1",
  "name" : "ABN Amro"
}]

The task is to map the model clearingFirm with the exchange, if no clearingFirm currently exists in the models exchange then null is assigned.

Template Snippet

<div class="contact-screen screen tt is-hidden js-contact">
            <% if((exchange.clearingFirm === null)) { %>
                <div class="input-field">
                    <label class="input-field__label" for="name">Name</label>
                    <input class="input-field__input js-input-field" type="text" name="name">
                </div>

                <div class="input-field">
                    <label class="input-field__label" for="telephone">Telephone Number</label>
                    <input class="input-field__input js-input-field" type="text" name="telephone">
                </div>

                <div class="input-field">
                    <label class="input-field__label" for="email">Email Address</label>
                    <input class="input-field__input js-input-field" type="email" name="email">
                </div>
            <% } %>


            <% if (exchange.clearingFirm !== null) {
                _.each(model.contacts, function(contact) { %>
                    <div class="input-field">
                        <label class="input-field__label" for="name">Name</label>
                        <% if((contact.clearingFirmId === exchange.clearingFirm.id)) { %>
                            <input class="input-field__input js-input-field" type="text" name="name" value="<%= contact.name %>">
                        <% } else { %>
                            <input class="input-field__input js-input-field" type="text" name="name">
                        <% } %>
                    </div>

                    <div class="input-field">
                        <label class="input-field__label" for="telephone">Telephone Number</label>
                        <% if((contact.clearingFirmId === exchange.clearingFirm.id)) { %>
                            <input class="input-field__input js-input-field" type="text" name="telephone" value="<%= contact.phone %>">
                        <% } else { %>
                            <input class="input-field__input js-input-field" type="text" name="telephone">
                        <% } %>
                    </div>

                    <div class="input-field">
                        <label class="input-field__label" for="email">Email Address</label>
                        <% if((contact.clearingFirmId === exchange.clearingFirm.id)) { %>
                            <input class="input-field__input js-input-field" type="email" name="email" value="<%= contact.email %>">
                        <% } else { %>
                            <input class="input-field__input js-input-field" type="text" name="email">
                        <% } %>
                    </div>
                <% }); %>
            <% } %>

            <div class="actions">
                <input type="submit" class="actions__action action action--submit">
            </div>
        </div>
\$\endgroup\$
  • 1
    \$\begingroup\$ As someone who's not well-acquainted with JS, could you expand further upon what precisely the code is meant to be accomplishing? \$\endgroup\$ – Kaz Aug 30 '15 at 17:51
  • 1
    \$\begingroup\$ Added to my post, hoping this makes things a little clearer \$\endgroup\$ – styler Aug 30 '15 at 17:59
2
\$\begingroup\$

I don't completely understand the code, but here's a jsFiddle with a simplified version of it.

The main problem with your code is that you have quite a lot of repetition. This makes it harder to read and also harder to change in the future, for example if you want to add another class to the div.

You can use a template helper method to make your code more readable. The code below creates a helper called inputField that's based on the same HTML every time.

HTML:

<script type="text/template" id="input-field-template">
    <div class="input-field">
        <label class="input-field__label" for="<%= name %>"><%= label %></label>
        <input class="input-field__input js-input-field" type="text" name="<%= name %>" value=<%= value %> >
    </div>
 </script>

JavaScript:

var helpers = {
    inputFieldTemplate: _.template($("#input-field-template").html()),
    inputField: function(label, name, value){
        return this.inputFieldTemplate({
            name: name,
            label: label,
            value: value === undefined ? "" : value
        });
    }
}

var template = $("#template2").html();
$("body").append(_.template(template)({
    helpers: helpers,
    exchange: {id: 5},
    contact: {id: 5}
}));

Inside your main template you can then use it like this:

<%= helpers.inputField("Email Address", "email") %>

The second part of the template you provided has code that's a little bit more complex, but something similar to this should work:

<%= helpers.inputField("ID", "id", exchange.id === contact.id ? exchange.id : "222") %>

Using a helper method is one way to do this, but it means that you'll have to split up your template into two pieces.

If you prefer not to do that, you could also create a list of input fields similar to this and then iterate over it in your template:

var fields = [
   {
       label: "Telephone",
       name: "telephone"
   },...
]

And then in your template you iterate over it with something like this:

<% .each(fields, function(field) { %>
    <div class="input-field">
        ...
        <input type="text" name="<%= field.name%>"></input>
    </div>
<% } %>
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.