Search code examples
javascriptjquerybackbone.js

Backbone render template in side el's nested id


I have my html setup like this.

<div id="product-module">
   <ul id="product">
      <li><input name="product" type="radio"/></li>
      <li><input name="product" type="radio"/></li>
      <li><input name="product" type="radio"/></li>
   </ul>
   <table id="quantities"/>

   <script id="myTemplate" type="text/x-handlebars-template">
        {{#each this}}
        <tr>
            <td class="quantity">
                <label class="checked" for="quantity_{{id}}">
                    <input type="radio" value="" name="quantity"> 
                    {{quantity}}
                </label>
            </td>
        </tr>
    {{/each}}
   </script>
</div>

I'm trying to setup an event handler that listens for clicks on li and renders the template within the quantities element.

My backbone view

el: '#product-module',

template: Handlebars.compile($("#myTemplate").html()),

events: {
    "click #product li": "liClicked",
},

initialize: function(){
    this.listenTo(this.collection, 'reset', this.render);
},

render: function() {
    console.log('model ' + this.template(this.collection.toJSON()))
    this.$el.html( this.template(this.collection.toJSON()));
},

liClicked: function(event, callback){
    console.log('liClicked')
},

If I change el to #quantities, then my event handlers don't work outside of the el. If i change my el to #product-module, then everything gets replaced. How do I get my event handlers to listen and the template to render within the #quantities element?

I've also tried this with no success

$('#quantities', this.el)

TypeError: $(...) is not a function


Solution

  • HTML

    <script id="myTemplate" type="text/x-handlebars-template">
        {{#each this}}
        <tr>
            <td class="quantity">
                <label class="checked" for="quantity_{{id}}">
                    <input type="radio" value="" name="quantity"> 
                    {{quantity}}
                </label>
            </td>
        </tr>
        {{/each}}
    </script>
    
    <div id="product-module">
       <ul id="product">
          <li><input name="product" type="radio"/></li>
          <li><input name="product" type="radio"/></li>
          <li><input name="product" type="radio"/></li>
       </ul>
       <table id="quantities"/>
    </div>
    

    View

    el: '#product-module',
    
    template: Handlebars.compile($("#myTemplate").html()),
    
    events: {
        "click #product li": "liClicked",
    },
    
    initialize: function(){
        this.listenTo(this.collection, 'reset', this.render);
    },
    
    render: function() {
        var markup = this.template(this.collection.toJSON());
        // this.$() is short for this.$el.find()
        this.$('#quantities').html(markup);
    },
    
    liClicked: function(event, callback){
        console.log('liClicked')
    },