Why I get gap in table rows? - angularjs

I work on my angularjs project.
I use ng-repeat to create rows in table.
Here is plunker.
Here is html template:
<table class="table table-responsive table-hover">
<thead>
<tr>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="object in arr1 track by object.id">
<td class="pull-left" ng-bind="object.name"></td>
<td ng-class="{'wrapper':showReview != $index }">
<div ng-class="{'slide':showReview != $index}">
<a class=" btn btn-default btn-xs" ng-click="showReview = showReview == $index ? -1 : $index;"><i class="glyphicon glyphicon-camera"></i></a>
<a class=" btn btn-default btn-xs" ng-click="showInspections = !showInspections; showReview = showReview == $index ? -1 : $index;"><i class=" glyphicon glyphicon-list-alt"></i></a>
</div>
</td>
</tr>
<tr ng-repeat-end ng-if="showInspections && showReview == $index">
<td colspan="">
{{t}}-{{$index}}
</td>
</tr>
</tbody>
</table>
Here is controller:
app.controller('MainCtrl', function($scope) {
$scope.arr1 = [{id:'124',name:'qqq'},
{id:'589',name:'www'},
{id:'45',name:'eee'},
{id:'567',name:'rrr'}];
$scope.t=100;
});
Here how it looks in the view:
You can see in picture above I have gap between the rows and I cant figure out why I get this gap?

You have one th in head and one td in second row you need to add colspan="2" on both of them.
Also do not use class="pull-left" with td take another element inside td and make it pull-left

Related

Angular nested Data Tables with dynamic headers issue

I am using Angular DataTables in my application and trying to create nested datatables with dynamic headers.
Here is my Html code.
<table datatable="ng" class="table table-striped table-bordered table-hover" dt-instance="dtInstance2" id="dtInvoicingData2" dt-options="dtOptions2" dt-column-defs="dtColumnDefs2">
<thead>
<tr>
<th ng-repeat="col in dtColumnDefs2">{{col.aTargets[0].sTitle | translate}} </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(index,client) in lstInvoiceDetail" class="clickableRow" style="cursor: pointer;" title="Click to toggle collapse/expand day summaries for this store.">
<td ng-repeat="col in headerList2" ng-switch="col">
<span ng-switch-when="lstDetail"> <button type="button" ng-click="btnViewDetails_Click(index)" class="btn btn-sm btn-info">+</button></span>
<span ng-switch-default>{{ client[col] }}</span>
</td>
</tr>
<tr ng-show="showViewDetail">
<div class="span12 pull-right" ng-show="showViewDetail">
<table datatable="ng" class="table table-striped table-bordered table-hover" dt-instance="dtInstance3" id="dtInvoicingData3" dt-options="dtOptions3" dt-column-defs="dtColumnDefs3">
<thead>
<tr>
<th ng-repeat="col3 in dtColumnDefs3">{{col3.aTargets[0].sTitle | translate}} </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(index,client) in lstInvoiceDetail" class="clickableRow" style="cursor: pointer;" title="Click to toggle collapse/expand day summaries for this store.">
<td ng-repeat="col3 in headerList3" ng-switch="col">
<span ng-switch-when="lstDetail"> <button type="button" ng-click="btnViewDetails_Click(index)" class="btn btn-sm btn-info">+</button></span>
<span ng-switch-default>{{ client[col3] }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</tr>
</tbody>
</table>
Here is javascript Code
function makeDetailTable(data) {
var header = data[0],
dtColumns = [];
$scope.headerList2 = [];
var i = 0;
var key = "";
//create columns based on first row in Parent Datatable
for (var key in header) {
dtColumns.push(DTColumnDefBuilder.newColumnDef(i).withTitle(key));
$scope.headerList2.push(key);
i = i + 1;
}
$scope.dtColumnDefs2 = dtColumns;
$scope.dtOptions2 = DTOptionsBuilder.newOptions()
.withPaginationType('full_numbers')
.withButtons([
'excel',
{
text: 'Reset',
action: function (e, dt, node, config) {
$("#dtInvoicingData2").DataTable().search("").draw();
}
}
]);
}
$scope.btnViewDetails_Click = function (rowIndex) {
var detailList = $scope.lstInvoiceDetail[rowIndex]['lstDetail'];
var header3 = detailList[0],
dtColumns3 = [];
$scope.headerList3 = [];
var i = 0;
var key = "";
//create columns based on first row in child datatable
for (var key in header3) {
dtColumns3.push(DTColumnDefBuilder.newColumnDef(i).withTitle(key));
$scope.headerList3.push(key);
i = i + 1;
}
$scope.dtColumnDefs3 = dtColumns3;
$scope.dtInstance2 = null;
$scope.dtOptions3 = DTOptionsBuilder.newOptions()
.withPaginationType('full_numbers')
.withButtons([
'excel',
{
text: 'Reset',
action: function (e, dt, node, config) {
$("#dtInvoicingData3").DataTable().search("").draw();
}
}
]);
$scope.showViewDetail = true;
when I try to add child datatable it doesn't work and show console error
TypeError: Cannot set property '_DT_CellIndex' of undefined
I did search on this error but i have not find proper solution
Here is a little info related to this error
it says the problem is
Basically this issue came out because of miss matching count of th to td. be sure for number of th matches to td. hope this will help you.
Update:
Now i have trying this.
<table datatable="ng" class="table table-striped table-bordered table-hover" dt-instance="dtInstance2" id="dtInvoicingData2" dt-options="dtOptions2" dt-column-defs="dtColumnDefs2">
<thead>
<tr>
<th ng-repeat="col in dtColumnDefs2">{{col.aTargets[0].sTitle | translate}} </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(index,client) in lstInvoiceDetail" class="clickableRow" style="cursor: pointer;" title="Click to toggle collapse/expand day summaries for this store.">
<td ng-repeat="col in headerList2" ng-switch="col">
<span ng-switch-when="lstDetail"> <button type="button" ng-click="btnViewDetails_Click(index)" class="btn btn-sm btn-info">+</button></span>
<span ng-switch-default>{{ client[col] }}</span>
</td>
</tr>
<tr>
<td colspan="3">
<table class="table table-striped table-bordered table-hover" dt-instance="dtInstance3" id="dtInvoicingData3" dt-options="dtOptions3" dt-column-defs="dtColumnDefs3">
<thead>
<tr>
<th ng-repeat="col3 in headerList3">{{col3 | translate}} </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(index,client) in lstChildInvoiceDetail" class="clickableRow" style="cursor: pointer;" title="Click to toggle collapse/expand day summaries for this store.">
<td ng-repeat="col3 in headerList3" ng-switch="col">
<!-- <span ng-switch-when="lstDetail"> <button type="button" ng-click="btnViewDetails_Click(index)" class="btn btn-sm btn-info">+</button></span> -->
<span ng-switch-default>{{ client[col3] }}</span>
</td>
</tr>
</tbody>
</table>
</td>
<td style="display:none;"> </td>
<td style="display:none;"></td>
</tr>
</tbody>
</table>
Child Table is created on first row, i want to created on each row.
Do you have any idea about it?
Because you are trying to create two rows with different structures instead of nested tables.
Row 1 :
<tr ng-repeat="(index,client) in lstInvoiceDetail" class="clickableRow" style="cursor: pointer;" title="Click to toggle collapse/expand day summaries for this store.">
<td ng-repeat="col in headerList2" ng-switch="col">
<span ng-switch-when="lstDetail"> <button type="button" ng-click="btnViewDetails_Click(index)" class="btn btn-sm btn-info">+</button></span>
<span ng-switch-default>{{ client[col] }}</span>
</td>
</tr>
And Row 2 :
<tr ng-show="showViewDetail">
<div class="span12 pull-right" ng-show="showViewDetail">
<table datatable="ng" class="table table-striped table-bordered table-hover" dt-instance="dtInstance3" id="dtInvoicingData3" dt-options="dtOptions3" dt-column-defs="dtColumnDefs3">
<thead>
<tr>
<th ng-repeat="col3 in dtColumnDefs3">{{col3.aTargets[0].sTitle | translate}} </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(index,client) in lstInvoiceDetail" class="clickableRow" style="cursor: pointer;" title="Click to toggle collapse/expand day summaries for this store.">
<td ng-repeat="col3 in headerList3" ng-switch="col">
<span ng-switch-when="lstDetail"> <button type="button" ng-click="btnViewDetails_Click(index)" class="btn btn-sm btn-info">+</button></span>
<span ng-switch-default>{{ client[col3] }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</tr>
and as far error states, data in both rows has different count for header and columns. It means your lists dtColumnDefs2, headerList2, dtColumnDefs3, and headerList3 have different counts.

ng-repeat and collapse table

I am trying to display information inside a table using a button to show and hide the data in each row using the row's id, but since I have 2 ng-repeat, the first loop is completed before the second and therefore all the data is displayed in the same row : here is my code :
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th></th>
<th>Projet</th>
<th>Responsable Apitech</th>
<th>Temps Passé</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="p in projetsListe" >
<td>
<button class="btn btn-xs" ng-click="expanded = !expanded" expand data-toggle="collapse" id="{{p.IdProjet}}" data-target=".{{p.IdProjet}}">
<span ng-bind="expanded ? '-' : '+'"></span>
</button>
</td>
<td>{{p.NomProjet}}</td>
<td>{{p.ResponsableApitech}}</td>
<td>Temps Passé</td>
</tr>
<tr ng-repeat-end ng-show="expanded">
<td></td>
<td colspan="6">
<table class="table table-condensed table-bordered">
<thead>
<th></th>
<th>Tache</th>
<th>Collaborateur</th>
<th>Date</th>
<th>Temps Passé</th>
</thead>
<tbody>
<tr ng-repeat= "ft in ftListesorted" ng-show="expanded" class="collapse {{ft.IdProjet}}">
<td><i class="glyphicon glyphicon-plus"></i></td>
<td>{{ft.NomTache}}</td>
<td>{{ft.NomCollaborateur}}</td>
<td>{{ft.Datefeuillestemps | date : 'dd/MM/yyyy' }}</td>
<td>{{ft.TempsPasse}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
This is what im trying to achieve : http://embed.plnkr.co/qqNGSbw6oLUZbKqVQVpG/?show=preview
In my case :
This is what I get instead :
If you noticed in the second image get the information of the first and the second row while i want the information of each row seperatly.
Here is a plunker with an example of the problem : https://plnkr.co/edit/pPcPipLK0TltnOC60SSf
create expanded property for each row. Change this lines
<button class="btn btn-xs" ng-click="p.expanded = !p.expanded" expand data-
toggle="collapse" id="{{p.IdProjet}}" data-target=".{{p.IdProjet}}">
and
<tr ng-repeat-end ng-show="p.expanded">

How can I set the first accordion item in the ngRepeat to be open while the rest are not?

I'm creating a list of tables with collapsible tbodys. This code works fine but I want to have the first tbody open on default. I've tried ng-init="showReports0" on the table tag, but this doesn't work. I've also tried to predefine $scope.showReports0 = true; in the controller. Can anyone help me out here?
<table ng-repeat="set in reportsData" class="table table-striped hover-table report-list" id="reportList-{{$index}}" ng-init="showReports0">
<thead>
<tr>
<th colspan="3" class="trigger-man" ng-model="showReports[$index]" ng-click="showReports[$index] = !showReports[$index]" style="width: 100%;">{{set.type}}<span class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': showReports[$index], 'glyphicon-chevron-right': !showReports[$index]}"></span></th>
</tr>
</thead>
<tbody ng-hide="!showReports[$index]">
<!-- Start Dynamic Reports Content -->
<tr class="hover-check" ng-class="{'compare-row disabled': item.type=='Comparative' && selectionData.length == 1, 'rep-checked': item.checked}" ng-repeat="item in set.reports | orderBy : 'sequence'">
<td class="no-pad"><div href="" class="popup pop-details no-match" uib-popover-template="nomatchPopover.templateUrl" popover-trigger="outsideClick" popover-placement="auto"></div>
<label class="checkbox checky">
<input type="checkbox" ng-change="reportPush(item.checked, item)" ng-true-value="true" ng-false-value="false" ng-model="item.checked" class="hidden">
</label></td>
<td class="rep-list-td"><div href="" class="popup pop-details no-compare" uib-popover-template="comparePopover.templateUrl" popover-trigger="outsideClick" popover-placement="auto"></div>
{{item.name}}</td>
<td class="cell-details">Details</td>
</tr>
</tbody>
</table>

AngulaJS Hide/Show tablerows depending on several conditions/hide all

I have a table, in which i would like to only show rows that match some variables, as well as hide/show all rows.
So, with additional variables to add later, how would i implement a hide/show all functionallity preferably with keeping the <"a> tags
<span class="glyphicon glyphicon-triangle-bottom"></span> Expand all
<span class="glyphicon glyphicon-triangle-right"></span> Hide all
<table style="width: 50%" class="table table-striped table-bordered table-hover">
<colgroup>
<col class="col-xs-1">
<col class="col-xs-3">
<col class="col-xs-3">
<col class="col-xs-1">
</colgroup>
<thead>
<th>ID</th>
<th> name</th>
<th> name</th>
<th>Action</th>
</thead>
<tbody>
<tr class="{{ a.b ? 'danger' : 'success' }}" ng:repeat:start="entity in entities">
<td>{{a.id}}</td>
<td>{{a.name}}</td>
<td>{{a.asd.name}}</td>
<td>
<a class="glyphicon glyphicon-pencil" href="#project/{{project.id}}"></a>
<a class="glyphicon glyphicon-triangle-bottom" href="" class="rowtrigger" data-toggle="collapse" data-target="#detail_{{project.id}}"></div>
</td>
</tr>
<tr ng:repeat:end>
<td colspan="4" class="collapse-row">
<div id="detail_{{a.id}}" class="collapse statuslabel">
<span ng:repeat="version in a.versions" class="label label-{{ version.b ? 'danger' : 'success' }}">
{{version.version}}
</span>
</div>
</td>
</tr>
</tbody>
</table>
You could put a click event on the Hide/Show all and have that set a boolean property in the controller. Then bind that boolean property to the ngHide attribute on the rows. You could do something like ng-hide="hideAll || <whatever other conditions you want>"

Indexing ng-repeat to only edit one

I am trying to index my ng-repeat so that I can edit a row by making the one with text disappear and the one with inputs appear.
<div ng-controller="BusinessGoalsCtrl">
<table class="table table-hover">
<tr>
<th>Type:</th>
<th>Timeframe:</th>
<th>Goal:</th>
<th>Edit:</th>
</tr>
<tr ng-class="editMode ? 'ng-hide' : ''" ng-repeat="details in businessGoalDetails track by $index">
<td style="width:30%;">{{details.display_name}} {{$index}}</td>
<td style="width:30%;">{{details.timeframe}}</td>
<td style="width:30%;">{{details.threshold}}</td>
<td style="width:10%;"><i ng-click="toggleEdit(true, $index)" class="fa fa-pencil-square-o"></i></td>
</tr>
<tr ng-class="editMode ? '' : 'ng-hide'" ng-repeat="inputs in businessGoalDetails track by $index">
<td style="width:30%;"><input ng-model="inputs.display_name"/></td>
<td style="width:30%;"><input ng-model="inputs.timeframe"/></td>
<td style="width:30%;"><input ng-model="inputs.threshold"/></td>
<td style="width:10%;"><i ng-click="toggleEdit(false, $index)" class="fa fa-check"></i></td>
</tr>
</table>
</div>
Angular Code
$scope.editMode = false;
$scope.details = 0;
$scope.toggleEdit = function (showEdit, $index) {
console.log("editing view");
$scope.editMode = showEdit;
}
You could probably just use ng-if/ng-show instead of ng-class and use ng-repeat-start/end instead of creating 2 different ng-repeats. Also you could just make a single row editable by setting property on its child scope or on the object under iteration. In your code you are setting the property editMode at the parent scope level and not only that it is not specific to each row.
<tr ng-show="!details.editMode" ng-repeat-start="details in businessGoalDetails track by $index">
<!-- ... -->
<td style="width:10%;"><i ng-click="details.editMode=true" class="fa fa-pencil-square-o"></i></td>
</tr>
<tr ng-show="details.editMode" ng-repeat-end>
<td style="width:30%;"><input ng-model="details.display_name"/></td>
<!-- ... -->
<td style="width:10%;"><i ng-click="details.editMode=false" class="fa fa-check"></i></td>
</tr>
Or
<tr ng-show="!editMode" ng-repeat-start="details in businessGoalDetails track by $index">
<!-- ... -->
<td style="width:10%;"><i ng-click="toggleEdit(true)" class="fa fa-pencil-square-o"></i></td>
</tr>
<tr ng-show="editMode" ng-repeat-end>
<td style="width:30%;"><input ng-model="details.display_name"/></td>
<!-- ... -->
<td style="width:10%;"><i ng-click="toggleEdit(false)" class="fa fa-check"></i></td>
</tr>
and
$scope.toggleEdit = function (showEdit) {
this.editMode = showEdit; //'this' here is the child scope
}

Resources