Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Column names not showing when setting columns dynamically #12

Closed
paulopontovaz opened this issue Apr 27, 2016 · 11 comments
Closed

Column names not showing when setting columns dynamically #12

paulopontovaz opened this issue Apr 27, 2016 · 11 comments

Comments

@paulopontovaz
Copy link

paulopontovaz commented Apr 27, 2016

Hello,

I made a directive and put the your table in it (a table with 'wt-responsive-table' directive), but I am setting the columns dynamically with ng-repeat on a list of column names. When I size down the screen (to 'responsive mode'), the column names don't appear. Here's part of the code I used:

var table = $('div.table-holder > table');
var thead = $('<thead></thead>');
var tr = $('<tr></tr>');

for(var i in $scope.columnNames)
   tr.append('<th>' + $scope.columnNames[i] + '</th>');

I prepend the thead to the table, afterwards.

@awerlang
Copy link
Owner

Hi

It is a supported use case adding columns at runtime, with help of ng-repeat. But the code you pasted here don't make use of ng-repeat, it's plain DOM access, and this is not supported.

You can solve this requirement with plain Angular:

<thead>
  <tr>
    <th ng-repeat="column in columnNames">{{column}}</th>
  </tr>
</thead>

@paulopontovaz
Copy link
Author

Ok, I tried using plain Angular, but it didn't work either =/... Here's the code:

The directive:

.directive('myTableDirective', ['URL', function(URL){
    return {
        restrict: 'E',
            templateUrl: URL.tableComponent,
            scope: {
                itemList: '=',
                columnNames: '=',
                attributeNames: '='
            },
            controller: 'MyTableController'
        };
    }]);

The template:

<table wt-responsive-table>
            <thead>
                <tr>
                    <th ng-repeat="columnin columnNames">{{column}}</th>
                </tr>
            </thead>
            <tbody ng-show="itemList && itemList.length > 0">
                <tr ng-repeat="itemList in itemList" ng-init="item.checked = false" ng-click="item.checked = !item.checked">
                    <td ng-repeat="attribute in attributeNames">{{item[attribute]}}</td>
                </tr>
            </tbody>
        </table>

The element:

<my-table-directive
        item-list="itemList"
        column-names="['First Name','Last Name']"
        attribute-names="['firstname','lastname']">
    </my-table-directive>

The controller sets

itemList =  [
                {
                    firstname: 'test11',
                    lastname: 'test12'
                },
                {
                    firstname: 'test21',
                    lastname: 'test22'
                }
            ];

The table shows the values correctly at first. Everything ok. The problem is when I size down the screen and the table enters responsive mode. When the table's layout changes, the column names disappear.

@awerlang
Copy link
Owner

Could it be a typo in the template where you have: <th ng-repeat="columnin columnNames">{{column}}</th>?

Other than that, I don't see why it wouldn't work. Can you please provide a plunker?

@paulopontovaz
Copy link
Author

I made this one without using directives, but I got the same result: https://embed.plnkr.co/QH65eaSF15yeZkT48XrA/

@awerlang
Copy link
Owner

It may be some scoping issue. If there's some static text around where there's that {{column}}, that static text shows up in responsive mode.

I see nothing that should prevent you from using this solution. One thing you may want to try is creating a directive with a higher precedence than this component (priority > 0) to render each <th> in place before this component has a chance to run.

@paulopontovaz
Copy link
Author

I tried changing the priority of my directive. I never needed to set the priority of a directive before, so I set 'priority' to 1. It didn't work =/

Should I create another directive that will contain my current one?

@awerlang
Copy link
Owner

I don't think that will help. ng-repeat already has a higher priority.

My best guess is that when the ng-repeat runs producing this:

<th>{{column}}</th>
<th>{{column}}</th>

it fails somewhere to retrieve the correct column name during interpolation. Each DOM element should have a separate $scope with a column property by that point. This component takes this text to produce a data-title attribute on each tbody td.

@paulopontovaz
Copy link
Author

I see. Indeed data-title is not being set. I'll try to figure something out. Maybe generating the whole table on runtime.

Thanks!

@paulopontovaz
Copy link
Author

I worked around it by adding data-title="{{columnNames[$index]}}" to the <td></td>

@awerlang
Copy link
Owner

There's an incompability with the ng-repeat inside a <th>. Usually, the headers will be expanded & linked after this directive has opportunity to run. Ideally, every time the ng-repeat runs, we should reapply the directive binding code.

To work around this limitation, either use static <th>'s or use the data-title attribute as explained above. Interpolation and filters should work just fine.

There's a quick and dirty check that could be applied but still wouldn't solve most dynamic setups. So I'll leave this open for anyone interested in tackling this as an enhancement.

@awerlang
Copy link
Owner

awerlang commented Sep 1, 2016

Fix released in v0.2.0. plunker updated: https://embed.plnkr.co/pSoSnRzf0gNMVsH5nFs4/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants