Skip to content

Releases: dmytroyarmak/backbone-contact-manager

Step 9 - Edit contact page

03 Feb 10:37
Compare
Choose a tag to compare
  1. Add edit buttons to contact template:

        <div class="media-heading">
          <h3>
            <%- name %>
            <small>
              <a href="#contacts/edit/<%- id %>"><span class="glyphicon glyphicon-pencil"></span></a>
              <a href="#contacts/delete/<%- id %>" class="delete-contract">
                <span class="glyphicon glyphicon-trash"></span>
              </a>
            </small>
          </h3>
        </div>
    
  2. Show ContactForm on #/contacts/edit/1:

      router.on('route:editContact', function(id) {
        var contact = contacts.get(id),
            editContactForm;
    
        if (contact) {
          editContactForm = new ContactManager.Views.ContactForm({
              model: contact
          });
    
          $('.main-container').html(editContactForm.render().$el);
        } else {
          router.navigate('contacts', true);
        }
      });
    
  3. To be consistent pass empty contact model on newContact route:

    var newContactForm = new ContactManager.Views.ContactForm({
    model: new ContactManager.Models.Contact()
    });
    
  4. Show model's attributes in form:

    render: function() {
    var html = this.template(_.extend(this.model.toJSON(), {
      isNew: this.model.isNew()
    }));
    this.$el.append(html);
    return this;
    },
    
    <h2 class="page-header text-center"><%= isNew ? 'Create' : 'Edit' %> Contact</h2>
    ...
    <input type="text" class="form-control contact-name-input" value="<%- name %>">
    ...
    <input type="email" class="form-control contact-email-input" value="<%- email %>">
    ...
    <input type="tel" class="form-control contact-tel-input" value="<%- tel %>">
    
  5. Update contact on form:submitted:

    editContactForm.on('form:submitted', function(attrs) {
    contact.set(attrs);
    router.navigate('contacts', true);
    });
    

Difference

Step 8 - Add new contact

03 Feb 10:17
Compare
Choose a tag to compare
  1. Add new contact button under contacts list:

      <script type="text/template" id="tpl-contacts">
        <h2 class="page-header text-center">List of contacts</h2>
        <p class="text-center">
          <a href="#contacts/new" class="btn btn-lg btn-outline">Add Contact</a>
        </p>
        <ul class="media-list row contacts-container"></ul>
      </script>
    
  2. Add Contact Form view and template
    js/views/contactForm.js

    ContactManager.Views.ContactForm = Backbone.View.extend({
    template: _.template($('#tpl-new-contact').html()),
    render: function() {
      var html = this.template();
      this.$el.append(html);
      return this;
    }
    });
    

    index.html:

      <script src="app/js/views/contactForm.js"></script>
    

    template:

      <script type="text/template" id="tpl-new-contact">
        <h2 class="page-header text-center">Create Contact</h2>
        <form role="form" class="form-horizontal contract-form">
          <div class="form-group">
            <label class="col-sm-4 control-label">Full name:</label>
            <div class="col-sm-6">
              <input type="text" class="form-control contact-name-input">
            </div>
          </div>
          <div class="form-group">
            <label class="col-sm-4 control-label">Email address:</label>
            <div class="col-sm-6">
              <input type="email" class="form-control contact-email-input">
            </div>
          </div>
          <div class="form-group">
            <label class="col-sm-4 control-label">Telephone number:</label>
            <div class="col-sm-6">
              <input type="tel" class="form-control contact-tel-input">
            </div>
          </div>
          <div class="form-group">
            <div class="col-sm-offset-4 col-sm-3">
              <button type="submit" class="btn btn-outline btn-lg btn-block">Submit</button>
            </div>
            <div class="col-sm-3">
              <a href="#contacts" class="btn btn-outline btn-lg btn-block">Cancel</a>
            </div>
          </div>
        </form>
      </script>
    
  3. Render ContactForm view on #/contacts/new route:

      router.on('route:newContact', function() {
        var newContactForm = new ContactManager.Views.ContactForm();
    
        $('.main-container').html(newContactForm.render().$el);
      });
    
  4. Listen to form submit and trigger event with form's data:

    events: {
      'submit .contract-form': 'onFormSubmit'
    },
    
    /* ... */
    
    onFormSubmit: function(e) {
      e.preventDefault();
    
      this.trigger('form:submitted', {
        name: this.$('.contact-name-input').val(),
        tel: this.$('.contact-tel-input').val(),
        email: this.$('.contact-email-input').val()
      });
    }
    
  5. Create new Contact on form submitted:

      router.on('route:newContact', function() {
        var newContactForm = new ContactManager.Views.ContactForm();
    
        newContactForm.on('form:submitted', function(attrs) {
          attrs.id = contacts.isEmpty() ? 1 : (_.max(contacts.pluck('id')) + 1);
          contacts.add(attrs);
          router.navigate('contacts', true);
        });
    
        $('.main-container').html(newContactForm.render().$el);
      });
    

Difference

Step 7 - Delete contact button

03 Feb 09:34
Compare
Choose a tag to compare
  1. Add delete link to contact's template:

        <div class="media-heading">
          <h3>
            <%- name %>
            <small>
              <a href="#contacts/delete/<%- id %>" class="delete-contract">
                <span class="glyphicon glyphicon-trash"></span>
              </a>
            </small>
          </h3>
        </div>
    
  2. Add click event handler to contact view and make console log on click:

    events: {
      'click .delete-contract': 'onClickDelete'
    },
    
    /* ... */
    
    onClickDelete: function(e) {
      e.preventDefault();
      console.log('Delete');
    }
    
  3. Delete contact from collection on click:

    onClickDelete: function(e) {
      e.preventDefault();
      this.model.collection.remove(this.model);
    }
    
  4. Remove view on model remove:

    initialize: function() {
      this.listenTo(this.model, 'remove', this.remove);
    },
    

Difference

Step 6 - Add Router

03 Feb 09:15
Compare
Choose a tag to compare
  1. Create js/router.js file with our router:

    ContactManager.Router = Backbone.Router.extend({
    routes: {
      '': 'home',
      'contacts': 'showContacts',
      'contacts/new': 'newContact',
      'contacts/edit/:id': 'editContact'
    }
    });
    

    and in index.html:

      <script src="app/js/router.js"></script>
    
  2. Instantiate router in app start method and start backbone history:

      var router = new ContactManager.Router();
    
      router.on('route:home', function() {
        console.log('Home');
      });
    
      router.on('route:showContacts', function() {
        console.log('Show contacts');
      });
    
      router.on('route:newContact', function() {
        console.log('New contact');
      });
    
      router.on('route:editContact', function(id) {
        console.log('Edit contact');
      });
    
      Backbone.history.start();
    
  3. Redirect from home to contacts using router.navigate():

      router.on('route:home', function() {
        router.navigate('contacts', {
          trigger: true,
          replace: true
        });
      });
    
  4. Show contacts only on contacts path:

    router.on('route:showContacts', function() {
      var contactsView = new ContactManager.Views.Contacts({
        collection: contacts
      });
    
      $('.main-container').html(contactsView.render().$el);
    });
    

Difference

Step 5 - Render All Conracts

03 Feb 09:01
Compare
Choose a tag to compare
  1. Create start method in app.js

    start: function() {
      console.log('Contact Manager started!');
    }
    
  2. Add application initialization block in index.html:

    <script>
      $(function() {
        ContactManager.start();
      });
    </script>
    
  3. Check in DevTools

  4. Pass bootstrapping data to start method:

      <script>
        $(function() {
          ContactManager.start({
            contacts: [
              {
                id: 1,
                name : 'Terrence S. Hatfield',
                tel: '651-603-1723',
                email: 'TerrenceSHatfield@rhyta.com'
              },
              {
                id: 2,
                name : 'Chris M. Manning',
                tel: '513-307-5859',
                email: 'ChrisMManning@dayrep.com'
              },
              {
                id: 3,
                name : 'Ricky M. Digiacomo',
                tel: '918-774-0199',
                email: 'RickyMDigiacomo@teleworm.us'
              },
              {
                id: 4,
                name : 'Michael K. Bayne',
                tel: '702-989-5145',
                email: 'MichaelKBayne@rhyta.com'
              },
              {
                id: 5,
                name : 'John I. Wilson',
                tel: '318-292-6700',
                email: 'JohnIWilson@dayrep.com'
              },
              {
                id: 6,
                name : 'Rodolfo P. Robinett',
                tel: '803-557-9815',
                email: 'RodolfoPRobinett@jourrapide.com'
              }
            ]
          });
        });
      </script>
    
  5. Create contacts model from passed data in show method and check in DevTolls

  6. Create simple contacts view (views/contacts.js):

    ContactManager.Views.Contacts = Backbone.View.extend({
      template: _.template($('#tpl-contacts').html()),
    
      render: function() {
        var html = this.template();
        this.$el.html(html);
        return this;
      }
    });
    
    

    and add template to index.html:

    <script type="text/template" id="tpl-contacts">
      <h2 class="page-header text-center">List of contacts</h2>
      <ul class="media-list row contacts-container"></ul>
    </script>
    

    and

      <script src="app/js/views/contacts.js"></script>
    
  7. Add class to main container and render contacts view to it on app start:

    in index.html:

    <div class="container">
      <div class="row">
        <div class="col-xs-12 main-container">
        </div>
      </div>
    </div>
    

    in js/app.js:

      var contactsView = new ContactManager.Views.Contacts({
        collection: contacts
      });
    
      $('.main-container').html(contactsView.render().$el);
    
  8. Add template for Contact View:
    in index.html:

    <script type="text/template" id="tpl-contact">
      <div class="thumbnail">
        <img class="media-object" src="app/img/faces/<%- avatar %>">
      </div>
      <div class="media-heading">
        <h3>
          <%- name %>
        </h3>
      </div>
      <div class="media-body">
        <dl>
          <dt>Phone Number:</dt>
          <dd><%- tel %></dd>
          <dt>Email:</dt>
          <dd><%- email %></dd>
        </dl>
      </div>
      <hr>
    </script>
    

    and js/views/contact.js:

    ContactManager.Views.Contact = Backbone.View.extend({
    tagName: 'li',
    className: 'media col-md-6 col-lg-4',
    template: _.template($('#tpl-contact').html()),
    
    render: function() {
      var html = this.template(this.model.toJSON());
      this.$el.append(html);
      return this;
    }
    });
    
  9. Render each contact in Contacts view:

    ContactManager.Views.Contacts = Backbone.View.extend({
    template: _.template($('#tpl-contacts').html()),
    
    renderOne: function(contact) {
      var itemView = new ContactManager.Views.Contact({model: contact});
      this.$('.contacts-container').append(itemView.render().$el);
    },
    
    render: function() {
      var html = this.template();
      this.$el.html(html);
    
      this.collection.each(this.renderOne, this);
    
      return this;
    }
    });
    
    

Difference

Step 4 - Simple Contact view

03 Feb 08:01
Compare
Choose a tag to compare
  1. Create file app/js/views/contact.js with view:

    ContactManager.Views.Contact = Backbone.View.extend({
    render: function() {
      var html = '<h1>' + this.model.get('name') + '</h1>';
      this.$el.html(html);
      return this;
    }
    });
    

    and add to index.html:

    <script src="app/js/views/contact.js"></script>
    
  2. Show in console how to render and view's root element (el)

    var bob = new ContactManager.Models.Contact({name: 'Bob'})
    var bobView = new ContactManager.Views.Contact({model: bob})
    bobView.render()
    bobView.$el
    
    
  3. Append view to body:

    $('body').append(bobView.$el)
    

Difference

Step 3 - Contacts Collection

03 Feb 07:39
Compare
Choose a tag to compare
  1. Add collections/contacts.js with collection:

    ContactManager.Collections.Contacts = Backbone.Collection.extend({
    model: ContactManager.Models.Contact
    });
    

    and to index.html:

    <script src="app/js/collections/contacts.js"></script>
    
  2. Create collections with few models in DevTools and show some methods

    var contacts = new ContactManager.Collections.Contacts([
    {
      id: 1,
      name : 'Terrence S. Hatfield',
      tel: '651-603-1723',
      email: 'TerrenceSHatfield@rhyta.com'
    },
    {
      id: 2,
      name : 'Chris M. Manning',
      tel: '513-307-5859',
      email: 'ChrisMManning@dayrep.com'
    },
    ])
    
  3. All underscore.js methods for Collection

Difference

Step 2 - Contact Model

03 Feb 07:30
Compare
Choose a tag to compare
  1. Add app.js file with main namespace

    window.ContactManager = {
    Models: {},
    Collections: {},
    Views: {}
    };
    
  2. Add models/contact.js with empty model:

    ContactManager.Models.Contact = Backbone.Model.extend({
    });
    

    and to index.html:

    <script src="app/js/models/contact.js"></script>
    
  3. Show initialization, accessors, toJSON in console

  4. Add defaults to contact model:

    defaults: {
      name: null,
      tel: null,
      email: null,
      avatar: null
    }
    
  5. Add random avatar generation:

    initialize: function() {
      this.set('avatar', _.random(1, 15) + '.jpg');
    }
    
  6. Create some method and show in DevTools

Difference

Step 1 - Add dependencies

03 Feb 07:24
Compare
Choose a tag to compare
  1. Install dependencies. Execute in console:
    bower install backbone jquery underscore --save

  2. Add to index.html:

    <script src="vendor/jquery/jquery.js"></script>
    <script src="vendor/underscore/underscore.js"></script>
    <script src="vendor/backbone/backbone.js"></script>
    
  3. Check in DevTools

Difference

Step 0 - Initialization of project

03 Feb 07:22
Compare
Choose a tag to compare
  1. Execute in console to initialize project:
git clone https://github.com/dmytroyarmak/backbone-contact-manager.git
cd backbone-contact-manager
git checkout step-0
bower install
python -m SimpleHTTPServer