Template splitting

Editing will require doing something similar to creating. We'll make it so there is an 'isEditingTeam' helper and in the DOM we'll switch the team name for a text field for the user to make their changes.

However this brings us to a new lesson - one about templates and when to create new ones. Technically we could probably create the whole app with one template, but it would have a lot of code in it and it'd be hard to manage. To combat this issue of code obesity, we break them down into smaller templates.

Think of it like a chest of drawers for your clothes. You could just have one massive drawer and throw all your clothes in, or you could have several drawers - one for underwear, one for t-shirts, one for shorts etc. Currently our 'teams' template is growing into a big draw, and we should probably split it up.

A good way to do this is to keep asking "what is this template's responsibility?". Our 'teams' template is currently responsible for creating teams, showing teams, and removing teams. Should it be responsible for editing them too? Perhaps. It's always up to the developer of course.

But I think now is a good time to create a new template called 'team' (singular). A team template can be responsible for editing the team. We could even move the 'remove team' logic down to the 'team' template, lessening the burden of the 'teams' template.

Proposed template structure.

Firstly we'll create team.html:

client/views/team.html

<template name="team">
  <li>{{name}} <a class="remove" href="#">(x)</a></li>
</template>

And then reference it in teams.html:

client/views/teams.html

<template name="teams">
  <h3>Teams</h3>
  {{#if isCreatingTeam}}
    <form class="create-team">
      <input name="name" type="text">
      <button type="submit">Submit</button>
      <a class="cancel" href="#">Cancel</a>
    </form>
  {{else}}
    <a class="create" href="#">Create</a>
  {{/if}}

  <ul>
    {{#each teams}}
      {{> team}}
    {{/each}}
  </ul>
</template>

Even with this change you will find the app still works. This is because the {{> team}} template inherits the data context it's in. So for each team object (eg. {name: 'Barcelona'}) the template will have the data available for use (hence {{ name }} works).

Let's now move our 'click a.remove' event handler to the team template:

client/views/team.js

Template.team.events({
  'click a.remove': function(e, tpl){
    e.preventDefault();
    Teams.remove(this._id);
  }
});

Since the data context is the same, it's a simple copy and paste job.

Now let's add the edit functionality. It'll be a big chunk of new code, but it's nothing new - take your time reading through it and it should make sense:

client/views/team.html

<template name="team">
  <li>
    {{#if isEditingTeam}}
      <form class="form-edit">
        <input name="name" type="text" value="{{name}}">
        <button type="submit">Submit</button>
        <a class="cancel" href="#">Cancel</a>
      </form>
    {{else}}
      {{name}}
      <a href="#" class="edit">edit</a>
      <a href="#" class="remove"> (x)</a>
    {{/if}}
  </li>
</template>

client/views/team.js

Template.team.helpers({
  isEditingTeam: function(){
    return Session.get('editedTeamId') === this._id;
  }
});

Template.team.events({
  "click a.edit": function(e, tpl){
    e.preventDefault();
    Session.set('editedTeamId', this._id);
  },

  "submit form.form-edit": function(e, tpl){
    e.preventDefault();

    var teamName = tpl.$('input[name="name"]').val();
    if(teamName.length){
      Teams.update(this._id, {$set: {name: teamName}});
      Session.set('editedTeamId', null);
    }
  },

  "click a.cancel": function(e, tpl){
    e.preventDefault();
    Session.set('editedTeamId', null);
  },

  'click a.remove': function(e, tpl){
    e.preventDefault();
    Teams.remove(this._id);
  }
});

Now we can edit team names.

The main new thing here is that our Session variable is now given an ID rather than a boolean ( Session.set('editedTeamId', this._id); instead of Session.set('editedTeamId', true);). The reason for this is that if we set it to true, every single team name will turn into a text field. By setting it to an _id only one team template will switch isEditingTeam to true; the one you clicked.

Now that we have our teams sorted, it's time to create our "Games" feature, where users can create games between two teams and score them.