I've got two tables (table1,table2) that are structurally the same, but fed from different sources. Both tables share the class 'display' which I use to initialise the plugin for both tables. This works great for the most part, however the column filters select menu for table2 is duplicated on table1.
I've tried to fix this by using 'this' keyword to indicate a particular instance of the toolbar each of the filters need applying to, but not had much success.
The code that works is:
HTML:
<table id="table1" class="display table-striped table-borded table-hover" cellspacing="0" width="100%">
<thead>
<tr>
<th>Report Name</th>
<th>Year</th>
<th>Montly Snapshot</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date of Last Refresh --var from warehouse-- </th>
</tr>
</tfoot>
</table>
<table id="table2" class="display table-striped table-borded table-hover" cellspacing="0" width="100%">
<thead>
<tr>
<th>Report Name</th>
<th>Year</th>
<th>Montly Snapshot</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date of Last Refresh --var from warehouse-- </th>
</tr>
</tfoot>
</table>
JS:
//initialise data tables plugin and apply custom settings.
var reportstable = $('table.display').DataTable({
"sDom": '<"toolbar">Bfrtlp',
"searchCols": [
null, {
'sSearch': 'Current'
}
],
language: {
search: "_INPUT_",
searchPlaceholder: "Search for a Report..."
},
// create select form controls
initComplete: function() {
this.api().columns([1, 2]).every(function() {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($('.toolbar'))
.on('change', function() {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function(d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
if ($('#info').css('display') == 'block') {
$("#reports_wrapper").css('display', 'none');
}
// add bootstrap classes and placeholder property to form controls to add style
$('.toolbar select').addClass('selectpicker');
$('.dt-button').addClass('btn btn-danger').removeClass('dt-button');
$('.toolbar select').attr('id', 'year');
$('#year').prop('title', 'Financial Year');
$("#year option:contains('Current')").remove();
$('.toolbar select:nth-of-type(2)').attr('id', 'month');
$('#month').prop('title', 'Monthy Snapshot');
$("#month option:contains('undefined')").remove();
});
});
},
// create clear filter button
buttons: [
{
text: 'Clear Filters',
action: function(e, dt, node, config) {
$('select').val('').selectpicker('refresh');
// set Current Year as default filter
reportstable
.search('')
.columns([1]).search('Current')
.columns([2]).search('')
.draw();
}
}
],
//hide specified columns
"columnDefs": [
{
"targets": [1],
"visible": false,
"searchable": true
}, {
"targets": [2],
"visible": false,
"searchable": true
}
]
});
I've updates your jsfiddle and created a new jsfiddle. It's now appending 2 select menus in both tables's wrapper div. I've found why it's appending 4 select menus instead of 2 on the table1's wrapper div. It's because of this code: .appendTo($('.toolbar')). When initComplete callback function is called for table1 there is only one div with class=toolbar, and when the initComplete callback function is called for table2 there is two div with class=toolbar, one in table1's wrapper div and one in table2's wrapper div. that's why on table2's initComplete callback function it append select menus to all divs with class=toolbar. We should rather append to the current table wrapper's div with class=toolbar.
Related
I data in this format in my angular controller. These are dummy datas and will be fetched from some sort of services later.
$scope.attendanceLog =
{
attendances:
[
{
date:'12.12.17',
entries:
[
{
time:'12PM',
device:'1212',
location:'katabon'
},
{
time:'1PM',
device:'1212',
location:'katabon'
},
{
time:'2PM',
device:'1321',
location:'katabon'
}
]
},
{
date:'13.12.17',
entries:
[
{
time:'12PM',
device:'1212',
location:'katabon'
},
{
time:'1PM',
device:'1212',
location:'katabon'
},
{
time:'2PM',
device:'1321',
location:'katabon'
},
{
time:'5PM',
device:'1321',
location:'katabon'
}
]
}
]
};
Now I designed the table to view this data like this. Here is the html code
for the table
<table class="table table-bordered">
<thead>
<th>Date</th>
<th class="text-center">Time</th>
<th class="text-center">Device</th>
<th class="text-center">Location</th>
</thead>
<tbody>
<tr ng-repeat-start="attendance in attendanceLog.attendances">
<td rowspan="{{attendance.entries.length}}" class="date">{{attendance.date}}</td>
<td>{{attendance.entries[0].time}}</td>
<td>{{attendance.entries[0].device}}</td>
<td>{{attendance.entries[0].location}}</td>
</tr>
<tr ng-repeat-end ng-repeat="entries in attendance.entries" ng-if="$index>0">
<td>{{entries.time}}</td>
<td>{{entries.device}}</td>
<td>{{entries.location}}</td>
</tr>
</tbody>
I want to make every other instance of the highlighted sections' background a diffrent color.Here is the reference image.
So if there are 5 dates then the 1st, 3rd and 5th date cell and all the other cells on their right side would have a different color.
Now is there any way to do this with angular. I am sorry if its a stupid question. I am new to front end development.
You could change it to have one expression for the table entries and use ng-class-odd and ng-class-even:
<tbody>
<tr ng-repeat="..."
ng-class-odd="'someOddClass'" ng-class-even="'someEvenClass'">
</tr>
</tbody>
Then you'd just need to change your styling.
Instead of printing new rows in the table I created a new table for every date. And then I applied the css class on every odd numbered table.
<table class="table table-bordered" ng-repeat="...." class =
ng-class ="$index % 2 == 0 ? 'table table-bordered striped':'table table-bordered'" >
.......
.......
</table>
Here striped is the class I used to highlight the odd numbered records background a different color
I have this table
<table id="vehicleParamTable" class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
When a click on a link, I add a row. That work fine.
In the first column of the row, I add an jquery-typehead
Selector is not working, also would like to avoid it for first row (th header)
$('#vehicleParamTable tr td:first-child').typeahead({
minLength: 2,
display: "name",
mustSelectItem: true,
emptyTemplate: function(query) {
//must reset current element here
return 'No result for "' + query + '"';
},
source: {
vehicleParam: {
ajax: {
url: "/rest/vehicleparam",
path: "content"
}
}
},
callback: {
onEnter: function(node, a, item, event) {
//must assign item.id to current current element id
},
onResult: function(node, query, result, resultCount, resultCountPerGroup) {
if (resultCount < 1) {
//must reset current element here
}
}
}
});
Edit
$('#vehicleParamTable tr td:first-child')
seem good, but with the rest(typeahead init..) that return undefined
Edit 2 because I add dynamicly row, need to refresh typehead...
I am assuming you are using this https://github.com/running-coder/jquery-typeahead?
This plugin needs to be initialized on an input field.
So, given that your input field is in the first column of the first row after the header, the selector would be
$('#vehicleParamTable tbody tr td:first-child input').typeahead({ ...options })
I'm using this data table.
I need to get both ProductID & ProductStatus from the selected row where ProductID is embedded in the TR ID of each row.
I'm not displaying the productStatus in the table. But I need to get the status when the row is selected. Where can i add them ?
Please Guide me ....
CODE
function loadClick() {
const databaseRef = firebase.database().ref('S01/Products');
var query = databaseRef.orderByKey().startAt("C09M03S03").endAt("C09M03S04").limitToFirst(6);
query.once("value")
.then(function (snapshot) {
snapshot.forEach(function (childSnapshot) {
var t = $('#products_table').DataTable();
var key = childSnapshot.key;
var MID = childSnapshot.child("productMID").val();
var SID = childSnapshot.child("productSID").val();
var ProductID = childSnapshot.child("productID").val();
var name = childSnapshot.child("productName").val();
var unit = childSnapshot.child("productUnit").val();
var productMRP = childSnapshot.child("productMRP").val();
var price = childSnapshot.child("productSellingPrice").val();
var buying_price = childSnapshot.child("productBuyingPrice").val();
var productstatus = childSnapshot.child("productStatus").val();
var row = "";
t.row.add(['<td class="cell-60 responsive-hide"></td><td class="cell-300"><a class="avatar" href="javascript:void(0)"><img class="img-responsive" src="../../../global/portraits/1.jpg"alt="..."></a></td>', '<td>' + name + '</td>',
'<td>' + unit + '</td>', '<td tabindex="1">' + productMRP + '</td>', '<td tabindex="2">' + price + '<\/td>',
'<td tabindex="3">' + buying_price + '<\/td>']).node().id = ProductID;
t.draw(false);
});
});
}
function EditProdStatus(ProductID, ProductStatus) {
var statusRef = firebase.database().ref('S01/Products').child(ProductID).child("productStatus");
statusRef.set(!ProductStatus);
console.log("Product Status changed to " + ProductStatus);
}
$(document).ready(function () {
loadClick();
var table = $('#products_table').DataTable({
'columnDefs': [{
orderable: false,
className: 'select-checkbox',
targets: 0
},
{
'targets': 3,
'createdCell': function (td, cellData, rowData, row, col) {
$(td).attr('tabindex', '1');
}
},
{
'targets': 4,
'createdCell': function (td, cellData, rowData, row, col) {
$(td).attr('tabindex', '2');
}
},
{
'targets': 5,
'createdCell': function (td, cellData, rowData, row, col) {
$(td).attr('tabindex', '3');
}
}
],
select: {
style: 'os',
selector: 'td:first-child'
},
order: [[1, 'asc']]
});
});
function productDisable() {
var oTable = $('#products_table').dataTable();
$(".select-checkbox:checked", oTable.fnGetNodes()).each(function () {
console.log($(this).val());
});
}
HTML
<table id="products_table" class="table is-indent tablesaw" cellspacing="0" width="100%">
<thead>
<tr>
<th class="pre-cell"></th>
<th class="cell-300" scope="col" data-tablesaw-sortable-col data-tablesaw-priority="3">Product Name</th>
<th class="cell-300" scope="col" data-tablesaw-sortable-col data-tablesaw-priority="4">Product Unit</th>
<th class="cell-300" scope="col" data-tablesaw-sortable-col data-tablesaw-priority="4">Product MRP</th>
<th class="cell-300" scope="col" data-tablesaw-sortable-col data-tablesaw-priority="4">Selling Price</th>
<th class="cell-300" scope="col" data-tablesaw-sortable-col data-tablesaw-priority="4">Buying Price</th>
</tr>
</thead>
</table>
jsFiddle Demo
For those td which you don't want to display in DataTable, you just need to provide Visible:false in your columnDefs. They will be hidden but you can retrieve their data if they are in selected rows.
$('#example').DataTable({
columnDefs: [{
orderable: false,
className: 'select-checkbox',
targets: 0
}, {
"targets": [2],
"visible": false,
"searchable": false
}]
})
Another thing is you are using fnGetNodes which is a legacy function for datatable v1.9 on selection which is not going to work for DataTable 10.1. You can get selected rows as follow:
table.rows('.selected').data();
This is going to return selected rows even if you have selected multiple rows in different pages.
You can find a Demo here.
As you can see in demo that for Employees data, their position column in not visible in DataTable but its data is available while retrieving data of selected rows.
Documentation here for Hidden columns
Update
I have updated your Fiddle. Updated Fiddle .
Try this, it helps you
var table = $('#example').DataTable();
$('#example tbody').on( 'click', '.checkbox', function () {
if(this.checked==true)
{
console.log( table.row( this.closest('tr') ).data() );
}
} );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.5/js/jquery.dataTables.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.5/css/jquery.dataTables.css" rel="stylesheet"/>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>check</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" class="checkbox" ></td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox" ></td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
</tr>
</tbody>
</table>
Try this ...
Add your productStatus column to the HTML :
'<td>' + productStatus + '</td>'
Let's say that's at column index 8. So add the following to the dataTables columnDefs :
{
'targets': 8,
'visible': false,
}
Now, in productDisable(), you can get productID & productStatus from each selected row as follows :
function productDisable() {
table.rows(".selected").every(function() {
var row = this.node();
var productID = row.id;
var productStatus = this.data()[8];
console.log(productID, productStatus);
// do whatever with productID and productStatus
});
}
Demo
I a using Datatable 1.10 and this Code is Working for me
"btnSubmit" is the Id of the Button when you click on the button selected checkbox data you will get
// Handle form submission event
$('#btnSubmit').on('click', function() {
//Hold the Object Data what are the checkbox selected
var tblData = table.api().rows('.selected').data();
var tmpData;
//Iterate the Object and extract you one one by one row data With Hidden Id Also
$.each(tblData, function(i, val) {
tmpData = tblData[i];
alert(tmpData);
});
})
//You can use this one.
$( $('#example').DataTable().$('.checked').map(function ()
{
return $(this).closest('tr');
//want to get attribute
//var id = $(this).closest('tr').find('td.Select').attr('id');
}));
I'm using bootstrap-table where one of the columns is a drop-down menu:
<table data-toggle="table" id="table" data-unique-id="id">
<thead>
<tr>
<th data-field="type">type</th>
<th data-field="id">id</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
However, when appending a new row using:
$('#table').bootstrapTable('append', {
id: newId,
type: '<select name="type" class="select-type"><option value="foo">foo</option><option value="bar">bar</option></select>'
})
The option selected in previous rows isn't saved.
Demo
Update: The method in my answer works well for small tables, but using it in tables of 100+ rows is awfully slow, so I'm still looking for a solution.
I've added an event listener that uses bootstrap-table's api to update values after the option is selected.
$('#table').on('change', '.select-type', function(eventt) {
const elem = eventt.target;
elem[elem.selectedIndex].setAttribute('selected', true);
const tr = elem.parentNode.parentNode;
const rowId = tr.getAttribute("data-uniqueId");
const row = $('#table').bootstrapTable('getRowByUniqueId', rowId);
row['type'] = elem.outerHTML;
$('#table').bootstrapTable('updateByUniqueId', [{id: rowId, row: row}]);
});
I found out how to delete a row with this jQuery code. While clicking on a td with the class delete and a garbage icon.
HTML
<table id="foo" class="display" cellspacing="0" width="100%">
<tbody>
<tr>
<td>Foo1</td>
<td>Foo2</td>
<td>Foo3</td>
<td class="delete">IMAGE src here</td>
<td><img src="http://placehold.it/20x20"></td>
</tr>
</tbody>
JAVASCRIPT
$('#foo tbody').on( 'click', 'tr .delete', function () {
$(this).closest('tr').fadeOut("slow", function(){
$(this).remove();
})
} );
But I did not find anything about duplicating rows. I just want to click on a td with another icon in it and the row is duplicated below.
To duplicate a row, you'll need to copy all of its data into an array, then call row.add() to insert this data as a new row.
Something like:
<table id="foo" class="display" cellspacing="0" width="100%">
<tbody>
<tr>
<td>Foo1</td>
<td>Foo2</td>
<td>Foo3</td>
<td class="delete">IMAGE src here</td>
<td class="copy">IMAGE src here</td>
<td><img src="http://placehold.it/20x20"></td>
</tr>
</tbody>
$('#foo tbody').on( 'click', 'tr .copy', function () {
var row_data = [];
$(this).closest('tr').find('td').each(function() {
row_data.push($(this).text());
});
// you'll need a reference to your DataTable here
table.row.add(row_data).draw();
});
To get a reference to your DataTable, assign the result of the DataTable() method to a var.
$(document).ready(function() {
var table = $('#foo).DataTable( { "paging": false, "info": false });
// set up your event handlers, etc.
});
If you append a row with jQuery instead of DataTables method like row.add(), you'll lose the row when you sort or page the table.
Here's the jQuery that adds a row duplicate right underneath it, where DataTables is concerned. It has a caveat that this method may not retain any sorting or filtering set by the user.
$('#formtable tbody').on( 'click', 'button.btn-success', function () {
//destroy instance of DataTables
table.destroy(false);
//script assumes button is clicked on the line that needs to be duplicated
var btn = this;
//copy and insert row right below the original
var line = $(btn).parents('tr');
line.after(line.clone());
//since clone retains only input field values, but not dropdown selections,
//each dropdown value must be assigned individually
line.next().find("select.shape").val(line.find("select.shape").val());
line.next().find("select.material").val(line.find("select.material").val());
line.next().find("select.supplied").val(line.find("select.supplied").val());
//re-creating DataTables instance
//notice that "table" has no "var" in front - that's because it is pre-defined.
table = $('#formtable').DataTable({
"columnDefs": [ {
"searchable": false,
"orderable": false,
"targets": "_all"
} ],
"paging": false,
"info": false,
"ordering": true,
"searching": false,
"rowReorder": true
});
//"Index Column" values re-calculation
table.column(0).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
});
});
Hope this helps.
Try this:
HTML
<table id="foo" class="display" cellspacing="0" width="100%">
<tbody>
<tr>
<td>Foo1</td>
<td>Foo2</td>
<td>Foo3</td>
<td class="delete">IMAGE src here</td>
<td class="duplicate"><img src="http://placehold.it/20x20"></td>
</tr>
</tbody>
</table>
SCRIPT
$('#foo tbody').on( 'click', 'tr .delete', function () {
$(this).closest('tr').fadeOut("slow", function(){
$(this).remove();
})
} );
$('#foo tbody').on( 'click', 'tr .duplicate', function () {
var myTr = $(this).closest('tr');
var clone = myTr.clone();
myTr.after(clone);
} );