ember-view wrapper is breaking my table - javascript

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.

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

AngularJS: nest directive in ng-repeat for using smart-table with dynamic table fields

I'm trying to use angular-smart-table for grid in my new AngularJS app. According to the document, to sort a column, I should use the st-sort directive like bellow:
<th st-sort="firstName">first name</th>
<th st-sort="lastName">last name</th>
However, I'm trying to re-use the piece of code for not only one table, so I don't know the table field names in advance until the run-time. I'm doing something like bellow:
<script type="text/ng-template" id="content1">
<div ng-repeat="table in $ctrl.tables">
<h2>{{table._tableName}}</h2>
<table st-table="table._data" class="table table-striped">
<tr>
<th ng-repeat="fieldName in table._fieldNames" st-sort="{{fieldName}}">{{fieldName}}</th>
</tr>
<tr ng-repeat="data in table._data">
<td ng-repeat="fieldName in table._fieldNames">{{$ctrl.formatCell(table, data, fieldName)}}</td>
</tr>
</table>
</div>
</script>
And this cannot work (cannot sort, other functions OK). I tried bellow it does not work, seems the st-sort has to be in the <th> tag.
<th ng-repeat="fieldName in table._fieldNames"><span st-sort="{{fieldName}}">{{fieldName}}</span></th>
And bellow does not work as well:
<tr>
<span ng-repeat="fieldName in table._fieldNames">
<th st-sort="{{fieldName}}">{{fieldName}}</th>
</span>
</tr>
Today I tried to develop a directive and use it in the comment by setting restrict to "M" to solve the above. Then I got a new problem: I'm using UI-Router in this app and I cannot get the table contents in my directive, because UI-Router states have isolated scopes and it only supports controllers but does not support directives. The author may think supporting directives is not necessary (yes in most cases, but this kind of assumptions are always dangerous).
I'm Trying two possible ways: 1., put the field names to the session/local storage for sharing as a work-around; 2., abandon UI-Router. Appreciate anyone providing a better solution.

How to create grouped table rows in Marionette 3

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/

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

Categories

Resources