I have a table that I auto-increment each row with based on the user's selection.
The problem I am faced with is ng-repeat copies the column I cannot differentiate between them. For example, each cell in the column is numbered the same using index. I would like to have a way of identifying where the user clicks on the cell.
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th style="table-layout:fixed; text-align: center;" scope="col" colspan="2">Sales</th>
<th style="table-layout:fixed; text-align: center;" scope="col" colspan="2">Service</th>
<th style="table-layout:fixed; text-align: center;" scope="col" colspan="2">Accounting</th>
<th style="vertical-align:top; text-align: center;" scope="col" colspan="2">Parts</th>
<th style="vertical-align:top; text-align: center;" scope="col" colspan="2">Body Shop</th>
<th style="vertical-align:top; text-align: center;" scope="col" colspan="2">Other</th>
</tr>
<tr>
<th></th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">Start</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">End</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">Start</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">End</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">Start</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">End</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">Start</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">End</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">Start</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">End</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">Start</th>
<th class="start-end-time" style="text-align: center; font-size: .9em; color: #999;">End</th>
</tr>
</thead>
<tr ng-repeat="time in times">
<td>{{weekdays[$index]}}</td>
<td class="start-end-time" updated-row ng-repeat-start="(key,dept) in time" data-index="{{[key]}} start" editable-field time="dept.start"></td>
<td class="start-end-time" updated-row="{{$index}}" data-index="{{[key]}}" ng-repeat-end editable-field time="dept.end"></td>
<!-- {{times[$index][key].start}} -->
Monday Service start time {{times[0] |date: "shortTime"}}
<!-- <div id="HoursTable" newtable></div> -->
My controller
pp.controller('main', ['$scope', '$location', function($scope, $location) {
$scope.times = [];
$scope.timeArr = [];
$scope.timeObj = {};
$scope.clickedIndex;
$scope.departments = ["sales", "service", 'accounting', 'parts', 'bodyShop', 'other'];
$scope.weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
$.each($scope.weekdays, function(index, value) {
var dayTimes = {};
$.each($scope.departments, function(index, value) {
dayTimes[value] = {
start: '',
end: ''
};
});
$scope.times.push(dayTimes);
});
}]);
I have tried to create a data attribute called data-index="{{$index+=1}}"
Hopefully, my example makes a bit of sense. In a nutshell, I would need to give each cell in a column a identifier. As it is now, they all have the same value which stops me from applying any conditional logic.
<-- Updated -->
Located in the hours table page
ng-init="number = countInit()"
controller I added this piece of code as well:
$scope.countInit = function() {
return $scope.totalCount++;
}
When I try to display the results in my table using this syntax data-index={{number}}
My results are empty. How can this be? I almost feel like Angular is playing a practical joke on me. Or it could be my ignorance. I prefer to believe the former.
I thought my solution would work. Wondering where I have gone wrong. Can any humble soul help me?
Have you tried Angular-datatables?
Your html markup for the table looks a bit broken. Angular-datatables took me a while to understand and to wire up but definitely worth the effort, you simply build your JSON data the way you want it and load it into Angular-datatables, the table structure is then generated for you.
Want pagination? or export to PDF/Excel? or you want to search the table or sort it? You still have a lot of work to do before you come close to this library. Here is some of my Angular-datatables code I use to inject a table into the DOM:
// Bind a click handler to each row
var myCallback = function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('td', nRow).off("click").bind('click', function () {
// Do something with the row being clicked
console.log(aData);
});
return nRow;
};
$scope.dtOptions = DTOptionsBuilder.fromSource(json.data)
.withBootstrap()
.withButtons(dt_conf.dt_btns)
.withOption('fnRowCallback', myCallback)
.withOption('order', [[3, "desc"]])
.withOption('bDeferRender', dt_conf.defer_render)
.withOption('iDisplayLength', dt_conf.dt_length)
.withOption("dom", dt_conf.dt_dom)
.withPaginationType(dt_conf.paging_type)
.withOption('lengthMenu', dt_conf.lengthMenu)
.withOption('responsive', true)
.withOption('stateSave', dt_conf.save_state);
//The Columns should match your JSON structure
$scope.dtColumns = [
DTColumnBuilder.newColumn('id').withTitle('Id'),
// DTColumnBuilder.newColumn('file_id').withTitle('File Id').notVisible(),
// DTColumnBuilder.newColumn('file_num').withTitle('File Num').notVisible(),
DTColumnBuilder.newColumn('date_time').withTitle('Date Time'),
DTColumnBuilder.newColumn('payment_type_id').withTitle('Payment Type Id'),
DTColumnBuilder.newColumn('description').withTitle('Description'),
DTColumnBuilder.newColumn('creditor').withTitle('Creditor'),
DTColumnBuilder.newColumn('amount').withTitle('Amount').renderWith(dt_conf.fnRenderMoney),
DTColumnBuilder.newColumn('vat_amount').withTitle('Vat Amount').renderWith(dt_conf.fnRenderMoney),
DTColumnBuilder.newColumn('bank').withTitle('Bank').notVisible(),
DTColumnBuilder.newColumn('branch_name').withTitle('Branch Name').notVisible(),
DTColumnBuilder.newColumn('branch_code').withTitle('Branch Code').notVisible()]
// Inject the table into your DOM at element (el) and compile with your options.
angular.element(el).html("").append($compile('<table id="' + tid + '" datatable="" ' +
'dt-options="{{ dtOptions }}" ' +
'dt-columns="{{ dtColumns }}" ' +
'class="table table-condensed table-hover table-striped" ' +
'style="width:100%"></table>')($scope));
And here is my Factory to configure the options for my DataTables (Took me hours to gather all the options, there are many, and to get this exactly the way I like it! (Internet say 'Thank you!')
app.factory('dt_get', function ($filter) {
return {
conf : function conf(xtitle, xmsg) {
var result = [];
var xtitle = xtitle; // Title for the exported pdf,xls
var xmsg = xmsg; // Subtitle for the exported pdf,xls
result.paging_type = "full_numbers";
result.lengthMenu = [[ 5, 10, 15, 50, -1 ],[ 5, 10, 15, 50, "All" ]];
result.defer_render = true;
result.save_state = true; //Remember table positions and settings
result.dt_dom = "<'container-fluid'<'row'<'col-sm-3 text-left'f><'col-sm-6 center-block'p><'col-sm-3 text-right'i>>" +
//"<'row'<'col-sm-12 dt-bold'i>>" +
"<'row'<'col-sm-12'<'panel panel-default'tr>>>" +
"<'row'<'col-sm-2 text-left'l><'col-sm-6 center-block'p><'col-sm-4 text-right'B>>>";
result.dt_length = 10;
result.fnRenderYesNo = function (data, type, full) {
if (data == "1") {
return "<b class='text-success'>YES</b>"
} else {
return "<b class='text-danger'>NO</b>"
}
};
result.fnRenderYesNoInvert = function (data, type, full) {
if (data == "1") {
return "<b class='text-danger'>NO</b>"
} else {
return "<b class='text-success'>YES</b>"
}
};
result.fnRenderMoney = function (data, type, full) {
if (data < 0) {
return "<b class='text-danger'>" + $filter('currency')(data, 'R ', 2) + "</b>"; //could use currency/date or any angular filter
} else {
return $filter('currency')(data, 'R ', 2); //could use currency/date or any angular filter
}
};
result.dt_btns = [
{
extend: 'colvis',
text: 'Edit Cols'
},
{
extend: 'copyHtml5',
text: 'Copy',
title: xtitle,
message: xmsg,
exportOptions: {
columns: ':visible'
}
},
{
extend: 'print',
text: 'Print',
title: xtitle,
message: xmsg,
exportOptions: {
columns: ':visible'
}
},
{
extend: 'excelHtml5',
text: 'Excel',
title: xtitle,
message: xmsg,
filename: xtitle + ".xlsx",
exportOptions: {
columns: ':visible'
}
},
{
extend: 'pdfHtml5',
text: 'Pdf',
title: xtitle,
message: xmsg,
filename: xtitle + ".pdf",
exportOptions: {
columns: ':visible'
}
}
]
return result;
}
}
});
You can simply do like this,
var index = 1;
countIndex = function () {
return index++;
}
$scope.dtColumns = [
DTColumnBuilder.newColumn(countIndex, "Sr No"),
DTColumnBuilder.newColumn("some_column_name", "ID").notVisible(),
DTColumnBuilder.newColumn("some_column_name", "Data"),
DTColumnBuilder.newColumn("some_column_name", "Status").renderWith(function (data, type) {
return data == null ? 'Clean' : data;
}),
DTColumnBuilder.newColumn("update_date", "Update Date").renderWith(function (data, type) {
return $filter('date')(data.replace('/Date(', '').replace(')/', ''), 'dd-MMM-yyyy HH:mm:ss');
})
];
This is the simplest way to use index with angular datatable.