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:
But when I split it into three templates I get the following:
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 ?
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 AbsenceListItemView
s 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:
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.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.this.$()
to find this within your view's el
, this is a shortcut for this.$el.find(...)
that Backbone sets up for you.this.collection.each(...)
instead of mucking around with the collection's models
property with things like _.each(this.collection.models, ...)
.