ts-repeat-start ts-repeat-end problem
YoavNordmann opened this issue · 7 comments
Hi
Foer some reason I cannot use the ts-repeat-start ts-repeat-end tags.
I get the following error:
Error: [$compile:uterdir] http://errors.angularjs.org/1.4.2/$compile/uterdir?p0=ts-repeat-start&p1=ts-repeat-end
And the relevant code is:
<table class="table table-condensed table-bordered table-striped" ts-wrapper>
<thead>
<tr>
<th></th>
<th ts-criteria="id">Transaction #</th>
<th ts-criteria="completionDate|date">Date</th>
<th ts-criteria="userId">User</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="row in ctrl.exchangeTransactions | filter:ctrl.searchString" ts-repeat-start>
<td>
<button ng-if="row.expanded" ng-click="row.expanded = false">-</button>
<button ng-if="!row.expanded" ng-click="row.expanded = true">+</button>
</td>
<td>{{row.id}}</td>
<td ng-bind="row.completionDate | date"></td>
<td>{{row.userId}}</td>
</tr>
<tr ng-if="row.expanded" ng-repeat-end="" ts-repeat-end>
<td colspan="4">We shall see this</td>
</tr>
</tbody>
</table>
Could you help me out here ?
Thanks
I think the problem ist the ng-if directive used with ng-repeat-end / ts-repeat-end. If "row.expanded" is false the dom element will not exist, and therefore there is also no ng-repeat-end or ts-repeat-end. Try using ng-show, ng-hide instead.
Thanks for the prompt response.
You are right. I am using ng-hide now and it truly works... untill:
I want more information in the hidden row. As soon as I insert a DIV or another TABLE inside the hidden row (instead of the text "We shall see this") the data (including the HTML tags) is nowhere to be found. SImple text works...
I tested this of course without the ts-repeat-start/end tags and it works as expected.
Any thoughts on that ?
@YoavNordmann Can you post an updated example?
Updated example of the code
<table class="table table-condensed table-bordered table-striped" ts-wrapper>
<thead>
<tr>
<th></th>
<th ts-criteria="id">Transaction #</th>
<th ts-criteria="completionDate|date">Date</th>
<th ts-criteria="userId">User</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="row in ctrl.exchangeTransactions | filter:ctrl.searchString" ts-repeat-start>
<td>
<button ng-if="row.expanded" ng-click="row.expanded = false">-</button>
<button ng-if="!row.expanded" ng-click="row.expanded = true">+</button>
</td>
<td>{{row.id}}</td>
<td ng-bind="row.completionDate | date"></td>
<td>{{row.locationId}}</td>
<td>{{row.userId}}</td>
<td>{{row.primaryCustomerId}}</td>
</tr>
<tr ng-show="row.expanded" ng-repeat-end="" ts-repeat-end>
<td colspan="4">
<table class="table table-condensed table-striped" ng-repeat="details in row.exchangeStatements">
<tr>
<td>Register: </td>
<td>{{details.registerId}}</td>
</tr>
<tr>
<td>Rate: </td>
<td>{{details.rate}}</td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
Unfortunately, the way that ts-repeat has to alter the compilation of the DOM alongside ng-repeat makes compilation of nested ng-repeat not function correctly. I have a very similar situation and my solution was to make the nested table a separate custom element directive which will get compiled correctly. In your case you'd have something like a <exchange-state-table>...</exchange-state-table>
directive inside your expandable row. The added benefit is that you can make the sub-table ts-sortable as well.
Wow... this sucks !
This module is so small and sweet, exactly what I am looking for...
I would like to know if there is a possibility for a fix in the near future before I downgrade my stuff to a simple filtering solution.
Thank you very much for your help, I love your work !
Yoav
It really only affects the the ts-repeat-end with nested ng-repeat situation. I tried to figure it out (disclosure: I'm the one who added the multi-element support to this module), but somebody smarter than me will have to take a look and see if it can be fixed 😕.
It's really not that big a deal to make a simple directive of your own to workaround this issue (also good design to make more modular elements). Here's an example of one of mine I made to work around this and still get to use the awesome functionality of angular-tablesort:
Directive
.directive('transactionsTable', ['COMPONENTS_ROOT', function (COMPONENTS_ROOT) {
return {
restrict: 'E',
templateUrl: COMPONENTS_ROOT + 'contacts/templates/transactions-table.html',
link: function (scope, elem, attrs) {
scope.transactions = [];
scope.transactions = scope.$eval(attrs.transactions);
},
controller: ['$scope', function ($scope) {
$scope.getTransactionTotal = function () {
if (!$scope.transactions) return 0;
var total = 0, i = 0, amount;
for (; i < $scope.transactions.length; i++) {
amount = parseFloat($scope.transactions[i].TransactionTotal);
total += amount || 0;
}
return total;
};
}]
};
}])
Directive Template (edited for brevity)
<table ts-wrapper>
<thead>
<tr>
<th class="col-xs-2" ts-criteria="TransactionDate" ts-default>{{'DATE' | translate}}</th>
<th class="col-xs-2" ts-criteria="FiscalYear">{{'FINANCIAL_YEAR' | translate}}</th>
<th class="col-xs-3" ts-criteria="Reference">{{'REFERENCE' | translate}}</th>
<th class="col-xs-3" ts-criteria="Memo">{{'MEMO' | translate}}</th>
<th class="col-xs-2 align-right" ts-criteria="TransactionTotal | parseFloat">{{'AMOUNT' | translate}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="transaction in transactions" ts-repeat>
<td>{{::transaction.TransactionDate | date:DATE_FORMAT}}</td>
<td>{{::transaction.FiscalYear}}</td>
<td>{{::transaction.Reference}}</td>
<td>{{::transaction.Memo}}</td>
<td class="align-right">{{::transaction.TransactionTotal | absValue | currency}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="align-right" colspan="4"><strong>{{'TOTAL' | translate}}:</strong></td>
<td class="align-right"><strong>{{getTransactionTotal() | absValue | currency}}</strong></td>
</tr>
</tfoot>
</table>
Outer template (edited for brevity)
<table ts-wrapper>
<thead>
<tr>
<th class="col-xs-1">
...
</th>
<th class="col-xs-2" ts-criteria="CustomId">{{'ID' | translate}}</th>
<th class="col-xs-3" ts-criteria="ui.lastNameFirstName | lowercase" ts-default>{{'NAME' | translate}}</th>
<th class="col-xs-4" ts-criteria="ui.preferred.addresses.labelFormat()">{{'ADDRESS' | translate}}</th>
<th class="col-xs-2 align-right" ts-criteria="ui.getTotal1099Transactions() | parseFloat">{{'TOTAL' | translate}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="contact in filteredList" ts-repeat-start>
<td>
...
</td>
<td>{{::contact.CustomId}}</td>
<td>{{::contact.ui.lastNameFirstName}}</td>
<td ng-bind-html="..."></td>
<td class="align-right">{{::contact.ui.getTotal1099Transactions() | currency}}</td>
</tr>
<tr ng-repeat-end uib-collapse="contact.ui.detailsAreCollapsed" ts-repeat-end>
<td></td>
<td colspan="4">
<transactions-table transactions="contact.transactions1099"></transactions-table>
</td>
</tr>
</tbody>
...
</table>