Question

I have a main Backbone view for my app and I'm having trouble rendering a template based on a button click.

If the user clicks the submit button, it should display template2, otherwise it should display template1. Right now, when I click the submit button, template2 only displays for a second and then disappears before template1 appears again.

Here's a simplified version of the code without the other app functionalities

app.viewExample = Backbone.View.extend({
  el: "#in",
  template1: _.template( $('#one').html() ),
  template2: _.template( $('#two').html() ),

  events: {
    'click .submit': 'result',
  },

  initialize: function() {
    var bool = false;
    this.listenTo(app.col, 'all', this.render);
  },

  render: function() {
    if (this.bool) {
      var rand = Math.floor(Math.random() * app.opts.length);
      var value = app.col.at(rand).get("title");
      this.$el.html(this.template2( {
        result: value
      }));
    }      
    else if (!this.bool) {
      var total = app.col.length;
      this.$el.html(this.template1( {
        total: total
      }));
    }   
  },

  result: function() {
    this.bool = true; 
    this.render(); 
  }
});

*app.col is the collection for this app

Template:

<script type="text/template" id="template1">
    <span id="count"> Currently <%= total %> <%= total === 1 ? 'option' : 'options' %>
    </span>
    <button id="clear-all">Clear all</button>
</script>
<script type="text/template" id="template2">
    <div class="result">
    Result: <%= result %>
    </div>
    <button class="restart">Restart</button>
</script>    

HTML:

<section id="in">
    //stuff
    <button class="submit">Submit</button>
</section>
Was it helpful?

Solution

You have a lot of little problems here.

  1. Your view is looking for the wrong templates, you have:

    template1: _.template( $('#one').html() ),
    template2: _.template( $('#two').html() ),
    

    but <script id="template1"> and <script id="template2">. Those need to agree with each other.

  2. var bool = false in your initialize does not set this.bool, that just declares and initializes a local variable inside initialize. You'd want this.bool = false to initialize an object property.

  3. Your view's events are looking for clicks on class="submit":

    events: {
      'click .submit': 'result',
    }
    

    but your HTML starts out with a class="submit" element and the templates have id="clear-all" and class="restart" so the buttons in the templates won't do anything. If you only have one <button> per template then you can say:

    events: {
      'click button': 'result',
    }
    
  4. Some browsers get the default type wrong for <button> so you should always specify it explicitly: <button type="button"> instead of <button>.

Once you fix up those issues, it seems to work okay: http://jsfiddle.net/ambiguous/ThQ8V/3/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top