title: Backbone click event binding not being bound to DOM elements
body: <p>I have these divs called beats, and I want to register when they are clicked.   However, I can't seem to get them to register a click at all, either by clicking them, or calling a JQuery click event on a specific div in the console.  Either way, nothing is getting registered.</p>
  
  <p>The measureView.js creates this beatView, which creates a beat inside the parent measure.</p>
  
  <p>beatView.js :</p>
  
  <pre><code>//filename: views/beats/beatView.js
  /*  This is the view for a single beat, which is contained in a measure view. */
  define([ 'jquery', 'underscore',      'backbone',      'backbone/models/beat',      'text!backbone/templates/measures/audioMeasures.html',      'text!backbone/templates/beats/linearBarBeats.html',      'text!backbone/templates/beats/linearBarSVGBeats.html',      'text!backbone/templates/beats/circularPieBeats.html',      'app/dispatch',      'app/log'
  ], function($, _, Backbone, BeatModel, audioMeasuresTemplate, linearBarBeatsTemplate, linearBarSVGBeatsTemplate, circularPieBeatsTemplate, dispatch, log){
    return Backbone.View.extend({
      //registering backbone's click event to our toggle() function.
      events : {
        'click' : 'toggle'
      },
  
      //The constructor takes options because these views are created by measuresView objects.
      initialize: function(options){
        if (options) {
          console.log('options :');
          console.warn(options);
          this.model = options.model;
          // this.parentEl should be measure.cid
          this.measureBeatHolder = options.parentElHolder;
        } else {
          console.log('never really getting here');
          this.model = new BeatModel;
        }    
        this.render();
      },
  
      //We use css classes to control the color of the beat. A beat is essentially an empty div.
      render: function(toggle){
        var state = this.getSelectionBooleanCSS();
        if (toggle) {
          $('#beat'+toggle).removeClass(state);
          $('#beat'+toggle).addClass(this.switchSelectionBooleanValue());
        } else {
          var compiledTemplate = _.template(this.representations[this.currentBeatRepresentation], {beat: this.model, beatAngle: this.beatAngle, state: state});
          $(this.measureBeatHolder).append( compiledTemplate );
          return this;
        }
      },
  
      getSelectionBooleanCSS: function(){
        if (this.model.get("selected")) {
          return "ON";
        } else {
          return "OFF";
        }
      },
  
      switchSelectionBooleanValue: function(){
        if (this.model.get('selected') == true) {
          this.model.set('selected', "false");
        } else {
          this.model.set('selected', "true");
        }
        return this.model.get('selected');
      },
  
      /*
        This is called when a beat is clicked.
        It does a number of things:
        1. toggles the model's selected field.
        2. re-renders the beat.
        3. prints a console message.
        4. tells log to send a log of the click event.
        5. triggers a beatClicked event.
      */
  
      toggle: function(){
        console.log('getting to toggle function');
        var selectedBool = this.model.get("selected");
        this.model.set("selected", !selectedBool);
        var newBool = this.model.get("selected");
        this.render(this.model.cid);
        dispatch.trigger('beatClicked.event');
      }
    });
  });
  </code></pre>
  
  <p>For referencing:</p>
  
  <p>beatModel:</p>
  
  <pre><code>//filename: models/beat.js
  /*
    This is the beat model.
    It only knows about whether or not it
    is selected.
  */
  define([
    'underscore',
    'backbone'
  ], function(_, Backbone) {
    var beatModel = Backbone.Model.extend({
      defaults: {
        selected: false,
        state: 'OFF'
      },
      initialize: function(){
      },
      getStyleClass: function() {
        if (this.selected) {
          return 'ON';
        }
        else {
          return 'OFF';
        }
      }
    });
  
    return beatModel;
  });
  </code></pre>
  
  <p>measureModel:</p>
  
  <pre><code>//filename: models/measure.js
  /*
    This is the measure model.
    A component has a collection of these models.
    these models have a collection of beats.
  */
  define([
    'underscore',
    'backbone',
    'backbone/collections/beats'
  ], function(_, Backbone, beatsCollection) {
    var measureModel = Backbone.Model.extend({
      defaults: {
        label: '0/4',
        beats: beatsCollection,
        numberOfBeats: 0,
        divisions: 8
      },
      initialize: function(){     
      }
  
    });
  
    return measureModel;
  });
  </code></pre>
  
  <p>measureView.js:</p>
  
  <pre><code>// Filename: views/measures/measuresView.js
  /*
    This is the MeasuresView.
  
    This is contained in a ComponentsView.
  */
  define([
    'jquery',
    'underscore',
    'backbone',
    'backbone/collections/measures',
    'backbone/collections/beats',
    'backbone/models/measure',
    'backbone/views/beats/beatView',
    'text!backbone/templates/measures/audioMeasures.html',
    'text!backbone/templates/measures/linearBarMeasures.html',
    'text!backbone/templates/measures/linearBarSVGMeasures.html',
    'text!backbone/templates/measures/circularPieMeasures.html',
    'app/dispatch',
    'app/state',
    'app/log'
  ], function($, _, Backbone, MeasureModel, BeatsCollection, MeasuresCollection, beatView, audioMeasuresTemplate, linearBarMeasuresTemplate, linearBarSVGMeasuresTemplate, circularPieMeasuresTemplate, dispatch, state, log){
    return Backbone.View.extend({
      // el: $('.component'),
  
      // The different representations
      representations: {
        "audio": audioMeasuresTemplate,
        "linear-bar": linearBarMeasuresTemplate,
        "linear-bar-svg": linearBarSVGMeasuresTemplate,
        "circular-pie": circularPieMeasuresTemplate
      },
  
      currentMeasureRepresentation: 'linear-bar',
  
      //registering click events to add and remove measures.
      events : {
        'click .addMeasure' : 'add',
        'click .delete' : 'remove'
      },
  
      initialize: function(options){
        //if we're being created by a componentView, we are
        //passed in options. Otherwise we create a single
        //measure and add it to our collection.
        if (options) {
          this.measuresCollection = options.collection;
          this.parent = options.parent;
          this.el = options.el;
        }
        // else {
        //   this.measure = new BeatsCollection;
  
        //   for (var i = 0; i &lt; 4; i++) {
        //     this.measure.add();
        //   }
  
        //   this.measuresCollection = new MeasuresCollection;
        //   this.measuresCollection.add({beats: this.measure});
        // }
  
        if (options["template-key"]) {
          this.currentBeatRepresentation = options["template-key"];
        }
  
        //registering a callback for signatureChange events.
        dispatch.on('signatureChange.event', this.reconfigure, this);
        //Dispatch listeners
        dispatch.on('measureRepresentation.event', this.changeMeasureRepresentation, this);
  
        this.render();
  
        //Determines the intial beat width based on the global signature. Has to be below this.render()
        this.calcBeatWidth(this.parent.get('signature'));
      },
  
      changeMeasureRepresentation: function(representation) {
        this.currentMeasureRepresentation = representation;
        this.render();      
      },
  
      render: function(){
        $(this.el).html('&lt;div class="addMeasure"&gt;+&lt;/div&gt;');
        var measureCount = 1;
        //we create a BeatsView for each measure.
        _.each(this.measuresCollection.models, function(measure) {
          // when representation button changes, the current representation template will get updated
          var compiledTemplate = _.template( this.representations[this.currentMeasureRepresentation], {measure: measure, beatHolder:"beatHolder"+measure.cid, measureCount:measureCount, measureAngle: 360.0 } );
          $(this.el).find('.addMeasure').before( compiledTemplate );
            console.log('measure beats: ');
            console.warn(measure.get('beats').models);
              _.each(measure.get('beats').models, function(beat) {
                // console.warn("#beat"+beat.cid.toString());
                new beatView({model:beat, parentElHolder:'#beatHolder'+measure.cid, parentCID:measure.cid, singleBeat:"#beat"+beat.cid});
              }, this);
          measureCount ++;
        }, this);
        return this;
      },
  
      /*
        This is called when the user clicks on the plus to add a new measure.
  
        It creates a new measure and adds it to the component.
        It generates a string representing the id of the measure and the ids of
        its beats and logs the creation.
  
        Lastly, it triggers a stopRequest, because we can't continue playing until
        all the durations get recalculated to reflect this new measure.
      */
      add: function(){
          console.log('add measure');
          var newMeasure = new BeatsCollection;
  
          for (var i = 0; i &lt; this.parent.get('signature'); i++) {
            newMeasure.add();
          }
  
          this.measuresCollection.add({beats: newMeasure});
  
          //Logging
          name = 'measure' + _.last(this.measuresCollection.models).cid + '.';
          _.each(newMeasure.models, function(beats) {
            name = name + 'beat'+ beats.cid + '.';
          }, this);
          log.sendLog([[3, "Added a measure: "+name]]);
  
          //Render
          this.render();
          //Dispatch
          dispatch.trigger('stopRequest.event', 'off');
      },
  
      /*
        This is called when the user clicks on the minus to remove a measure.
      */
      remove: function(ev){
        if ($('#measure'+this.measuresCollection.models[0].cid).parent()) {
          //removing the last measure isn't allowed.
          if(this.measuresCollection.models.length == 1) {
            console.log('Can\'t remove the last measure!');
            return;
          }
          console.log('remove measure');
  
          //we remove the measure and get its model.
          var model = this.measuresCollection.get($(ev.target).parents('.measure').attr('id').replace('measure',''));
          this.measuresCollection.remove(model);
  
          //send a log event showing the removal.
          log.sendLog([[3, "Removed a measure: measure"+model.cid]]);
  
          //re-render the view.
          this.render();
  
          //trigger a stop request to stop playback.
          dispatch.trigger('stopRequest.event', 'off');
          dispatch.trigger('signatureChange.event', this.parent.get('signature'));
        }
      },
      // This is triggered by signatureChange events.
      reconfigure: function(signature) {
        console.log('MeasureView.reconfigure(signature) : signature=' +signature);
        /* if the containing component is selected, this
           triggers a request event to stop the sound.
  
           Then this destroys the beat collection and creates
           a new collection with the number of beats specified
           by the signature parameter.
        */
        if ($(this.parent).hasClass('selected')) {
          dispatch.trigger('stopRequest.event', 'off');
          this.measure.reset();
  
          for (var i = 0; i &lt; signature; i++) {
            this.measure.add();
          }
          //re-render the view.
          this.render();
  
          //recalculate the widths for each beat.
          this.calcBeatWidth(signature);
          dispatch.trigger('signatureChange.event', this.parent.get('signature'));
  
        }
      },
  
      //This determines the width of each beat based on the
      //number of beats per measure or 'signature'.
      calcBeatWidth: function(signature) {
        if ($(this.el).hasClass('selected')) {
          var px = 100/$('.measure').css('width').replace(/[^-\d\.]/g, '');
          var beatWidth = (100 - ((signature*1+1)*px))/signature;
  
          $(this.el).children('.beat').css({
            'width' : beatWidth+'%'
          });
        }
      }
    });
  });
  </code></pre>