Question

I have 3 separate templates, one for the head of a table the other for contents and the third for the closing tags. When I created the hole table and place it into a template altogether it looks like so:

enter image description here

But when I split it into three templates I get the following:

enter image description here

The table never forms correctly and the body of the table seem to ignore the head of the table. and never spreads out. If I remove the head template the body dosent change.

Here is the code :

AbsenceList.js

window.AbsenceListView = Backbone.View.extend({
    initialize: function() {
        this.template1 = _.template(tpl.get('tableEnd'));
        this.template2 = _.template(tpl.get('tableStart'));
        this.model.bind("reset", this.render, this);
        var self = this;
        this.model.bind("add", function(absence) {
            $(self.el).append(new AbsenceListItemView({
                model: absence
            }).render().el);
        });
    },
    render: function(eventName) {
        $(this.el).html(this.template2());
        _.each(this.model.models, function(absence) {
            $(this.el).append(new AbsenceListItemView({
                model: absence
            }).render().el);
        }, this);
        $(this.el).append(this.template1());
        return this;
    }
});
window.AbsenceListItemView = Backbone.View.extend({
    initialize: function() {
        this.template = _.template(tpl.get('absence-table_1'));
        this.model.bind("change", this.render, this);
        this.model.bind("destroy", this.close, this);
    },
    render: function(eventName) {
        $(this.el).append(this.template(this.model.toJSON()));
        return this;
    }
});

tableStart.html

<table class="table table-bordered table-striped" id="example-default">
            <thead>
              <tr>
                <th>Name</th>
                <th>Monday</th>
                <th>Tuesday</th>
                <th>Wednesday</th>
                <th>Thursday</th>
                <th>Fridays</th>
              </tr>
            </thead>
            <tbody>

TableEnd.html

 </tbody>
 </table>

AbsenceTable.html

<tr><td><a href='#student/<%= studentidStudent %>'>  <button>Link</button></a></td>

<td><% if (monday == true) { %> <span class="glyphicon glyphicon-ok"></span><%} else if (monday == false) { %><span class="glyphicon glyphicon-remove"></span><%} %></td>
<td><% if (tuesday == true) { %> <span class="glyphicon glyphicon-ok"></span><%} else if (tuesday == false) { %><span class="glyphicon glyphicon-remove"></span><%} %></td>
<td><% if (wednesday == true) { %> <span class="glyphicon glyphicon-ok"></span><%} else if (wednesday == false) { %><span class="glyphicon glyphicon-remove"></span><%} %></td>
<td><% if (thursday == true) { %> <span class="glyphicon glyphicon-ok"></span><%} else if (thursday == false) { %><span class="glyphicon glyphicon-remove"></span><%} %></td>  
<td><% if (friday == true) { %> <span class="glyphicon glyphicon-ok"></span><%} else if (friday == false) { %><span class="glyphicon glyphicon-remove"></span><%} %></td>

</tr> 

What is the reason for the body of the table not aligning with the head ?

Was it helpful?

Solution

jQuery's append is not a simple text concatenation. If you give a string, it will convert that string to a set of DOM nodes and insert those nodes. If you give append a string that contains invalid HTML, then the browser will do its best to fix your HTML before it adds any nodes to the DOM.

You're adding this "HTML":

<table class="table table-bordered table-striped" id="example-default">
    <thead>
        ...
    </thead>
    <tbody>

but that's not valid HTML so the browser will probably convert it to this:

<table class="table table-bordered table-striped" id="example-default">
    <thead>
        ...
    </thead>
    <tbody>
    </tbody>
</table>

before it hits the page. Then you try to add a more invalid stuff through your AbsenceListItemView (i.e. <tr>s that aren't inside <thead>, <tbody>, or <table>) so the browser will try to make sense of that. Finally, you try to append:

    </tbody>
</table>

which the browser will probably convert to:

<table>
    <tbody>
    </tbody>
</table>

and you end up with an incomprehensible mess.

You need to treat your <table> as a single unit. Combine your tableEnd and tableStart into something valid:

<table class="table table-bordered table-striped" id="example-default">
    <thead>
        ...
    </thead>
    <tbody>
    </tbody>
</table>

and then append the AbsenceListItemViews to the <tbody> in there:

render: function (eventName) {
    this.$el.html(this.template()); // This has both pieces.
    this.collection.each(function(model) {
        this.$('tbody').append(new AbsenceListItemView({model: model}).render().el);
    }, this);
    return this;
}

Note a few other changes:

  1. Your model was actually a collection so you should use this.collection instead of this.model inside the view and say new AbsenceListView({ collection: ... }) when instantiating the view.
  2. Use this.$el inside the view instead of creating a new jQuery wrapped version all the time by calling $(this.el) over and over again. Backbone creates this.$el for you so you should use it.
  3. Use this.$() to find this within your view's el, this is a shortcut for this.$el.find(...) that Backbone sets up for you.
  4. Backbone mixes various Underscore methods into collections so you can say this.collection.each(...) instead of mucking around with the collection's models property with things like _.each(this.collection.models, ...).
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top