How to create grouped table rows in Marionette 3 - javascript

I have a collection of models which I have passed into Marionette to generate a HTML table, but every row of the table needs to be expandable with additional hidden details.
This is very much like this question aimed at the deprecated CompositeView: How to show CompositeView with multiple children view in Backbone Marionette
The HTML structure that I'm trying to reproduce:
<table>
<thead>
<tr>
<th>Qty</th>
<th>Product</th>
<th>Price</th>
</tr>
</thead>
<!-- first item -->
<tbody>
<tr class="row-parent">
<td>1x</td>
<td>Fruit Bowl</td>
<td>£9.99</td>
</tr>
<tr class="row-child">
<td colspan="3">Some additional hidden info</td>
</tr>
</tbody>
<!-- second item -->
<tbody>
<tr class="row-parent">
<td>2x</td>
<td>Banana</td>
<td>£0.50</td>
</tr>
<tr class="row-child">
<td colspan="3">Some additional hidden info</td>
</tr>
</tbody>
</table>
As each group can be an ItemView with a tagName of tbody the grouping isn't so much of the issue. It's the injecting the CollectionView into the table which I can't figure out.
I'm ending up with tbody inside the CollectionView's el. I'm not too sure how to get around that?
JSFiddle here: https://jsfiddle.net/mzsgo3ay/5/

Related

Is there any way to reference a Handlebars inline partial programmatically?

Consider the following table template.hbs:
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{{#* inline "testTableRowTemplate"}}
<tr>
<td>{{Id}}</td>
<td>{{Name}}</td>
<td>{{Value}}</td>
</tr>
{{/inline}}
{{#* inline "testTableEmptyTemplate"}}
<tr>
<td colspan="99">There are no rows</td>
</tr>
{{/inline}}
{{#* inline "testTableLoaderTemplate"}}
<tr>
<td colspan="99">
<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>
<span class="sr-only">Loading...</span>
</td>
</tr>
{{/inline}}
</tbody>
</table>
From code, I am loading this template with an ajax call and compiling it to a HandlebarsTemplateDelegate which I use to dynamically refresh the table when new data is available. However, I would like to be able to target just a row, so I need a HandlebarsTemplateDelegate of just the "testTableRowTemplate" partial to be able to do this. Is there any way to do this from code? I've tried each of the following after compiling the main template but can't get access to the partial.
var rowPartial = Handlebars.partials["testTableRowTemplate"]; //doesn't work
And
var rowPartial = Handlebars.compile("{{>testTableRowTemplate}}"); //doesn't work
I'm hoping to avoid having multiple .hbs files for the table so ideally I'd be able to define reusable partials in the same file. Any ideas?
It does not appear that you can reference these from code. My workaround is as follows:
Table.hbs
You'll notice a make use of a custom helper registerPartial here. This allows me to dynamically register a handlebars helper.
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{{#registerPartial "testTableRowTemplate"}}
<tr>
<td>{{Id}}</td>
<td>{{Name}}</td>
<td>{{Value}}</td>
</tr>
{{/registerPartial}}
</tbody>
</table>
Page.ts
At the page level, I define the helper registerPartial. It's important to note that this will be registered to the global Handlebars environment. Therefore all partial names need to be unique. This could be solved by declaring a Handlebars environment for each component, i.e. Table, List, etc. but that is beyond the scope of what I need.
Handlebars.registerHelper('registerPartial', (name, options) => Handlebars.registerPartial(name, options.fn));
Table.ts
Following loading the Table.hbs template by way of Handlebars.compile(templateContentFromTablehbs), I can now get compile references to the row partials by doing this:
this._rowTemplate = Handlebars.compile(`{{>${this._rowPartialName}}}`);
Now I can re-use this._rowTemplate to do partial refreshes of table rows without having to refresh the whole thing.

Handlebars is iterating but not displaying values

So I am trying to render an array of objects with handlebars in my node app, and it seems to be picking up the objects since table rows are being added to the DOM, but none of the inner values are displaying for some reason. Also, I only have 4 results but there are 6 rows. I tried many different tweaks after going through documentation and similar questions, to no avail.
Here is the html
Course Catalog
<table class="jsonTable">
<thead>
<tr>
<th id="year">Year</th>
<th id="term">Term</th>
<th id="code">Code</th>
<th id="title">Title</th>
</tr>
</thead>
<tbody>
{{#each this}}
<tr>
<td>{{year}}</td>
<td>{{term}}</td>
<td>{{code}}</td>
<td>{{title}}</td>
</tr>
{{/each}}
</tbody>
</table>
main.js
$(".jsonTable").hide();
$("#catalog").on("click", function(){
console.log('catalog button clicked');
$.get('/catalog', function(data){
console.log(data);
$("#catalog").hide();
$(".jsonTable").show();
});
});
});
Console
DevTools

Creating an Ember.js component for each table row causes the width to change?

In my Ember.js application, I have a standard HTML table inside a Hanldebars template like this:
<table>
<thead>
<tr>
<th>Name</th>
<th>Email Address</th>
<th>Number</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john.d#gmail.com</td>
<td>111-111-1111</td>
</tr>
<tr colspan="3">
<td><!-- Loads of other markup --></td>
</tr>
</tbody>
</table>
This works fine but, I have to turn each table row into a component in order to add some logic etc. Instead of directly adding the rows, I now have:
<table>
<thead>
<tr>
<th>Name</th>
<th>Email Address</th>
<th>Number</th>
</tr>
</thead>
<tbody>
{{#each people as |person|}}
{{table-row person=person}}
{{/each}}
</tbody>
</table>
As you can see, I now have a component called table-row which has the entire first and second (with colspan="3") <tr> elements from the above HTML. The problem is, when I insert it as a component, Ember wraps the two rows in a <div> and this causes the rows to show up awkwardly. It doesn't take the width of the table and the table head. How can I fix this?
In your component definition, override tagName property.
The following sample code is from my data-grid-row component:
export default Ember.Component.extend({
tagName:'',
...
});
If you don't override this tagName, a div will be created for you.
Have a look at the resource from Ember Guide

ember-view wrapper is breaking my table

I am new to ember and working on a simple test app. I am trying to render the rows of a table dynamically from json data. The task is relatively simple. However each row is a component and ember wraps the element in a div with class ember-view. I believe this is preventing my table from rendering properly. How would this typically be handled in ember?
//contact-listing.hbs
<tr>
<th scope="row">{{contact.employee_id}}</th>
<td>{{contact.firstName}}</td>
<td>{{contact.lastName}}</td>
<td>{{contact.email}}</td>
<td>{{contact.telephone}}</td>
<td>{{contact.department}}</td>
</tr>
//contacts.hbs
<h1>Employees</h1>
<table class="table">
<thead>
<tr>
<th>Employee ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Telephone</th>
<th>Department</th>
</tr>
</thead>
<tbody>
{{#each model as |_contact|}}
{{contact-listing contact=_contact}}
{{/each}}
</tbody>
</table>
Now here is the markup I am getting back - in the browser all the td data is rendered as inline with no table formatting. I think this is due to the insertion of ember wrapper divs.
<div id="ember438" class="ember-view">
<tr>
<th scope="row"><!----></th>
<td><!----></td>
<td><!----></td>
<td>john#company.com</td>
<td>416-555-1111</td>
<td>finance</td>
</tr>
</div>
This is what gets rendered out visually:
Use:
tagName: '',
in your component definition.

Drilldown functionality with AngularJS using ng-repeat property and jQuery

I want to do the exact same thing as this Fiddle (The example is mine) but using angular. In the normal HTML I have a parent tr with its own child tr so when I run the example I can see
that the child records that are related to its parent tr
Then I start doing this in Angular but now Im confused because I'm using ng-repeat and a JSON structure to populate the data so now I only have this piece of code, I put this as the parent but I don't know how to deal with the "child":
<tbody>
<tr ng-repeat="d in category" class="parent">
<td class="expand"></td>
<td ng-bind="d.cat"></td>
<td ng-bind="d.LW$"></td>
<td ng-bind="d.LW"></td>
<td ng-bind="d.L4W"></td>
<td ng-bind="d.L13W"></td>
<td ng-bind="d.L52W"></td>
</tr>
</tbody>
Here is my code with the angular version: https://jsfiddle.net/228wkfej/

Categories

Resources