Ok so I have a table with information. Inside of this table are the columns namer and date (DD-MM-YYYY).
I need to restrict the table to only showing rows in my table that have a date that is equal to the current date. So if there are 10 rows and only 5 of them have today's date in the date column, only those 5 should show.
So I wondered if anyone knew of any code that would show only the rows on todays date, and change date automatically everyday.
Current HTML
<table class="tablesorter">
<thead>
<tr>
<th>Name</th>
<th>Release Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>Peter Parker</td>
<td>11/07/2015</td>
</tr>
<tr>
<td>John Hood</td>
<td>12/07/2015</td>
</tr>
<tr>
<td>Clark Kent</td>
<td>12/07/2015</td>
</tr>
<tr>
<td>Bruce Almighty</td>
<td>13/07/2015</td>
</tr>
<tr>
<td>Bruce Evans</td>
<td>14/07/2015</td>
</tr>
</tbody>
</table>
Current Javascript
$(document).ready(function () {
$("table").tablesorter({
headers: {
0: {
sorter: false
},
1: {
sorter: false
},
2: {
sorter: false
}
}
});
});
I'd suggest doing this before they appear in the HTML, but here is how to do it with jQuery.
$("document").ready(function () {
var t = new Date();
$("tr td:nth-child(2)").each(function () {
var text = $(this).text().match(/(\d+)/g);
var d = new Date(text[2], text[1] - 1, text[0]);
if (d.toDateString() == t.toDateString()) {
var d = new Date(text[2], text[1] - 1, text[0]);
$(this).closest('tr').addClass('hidden');
};
});
});
Today's dat eis defined. The function will cycle through the second TD in each TR, define a date from the text inside (using regex-match to separate the date components), compare that to today's date, and if they are the same it will add the hidden class to the whole row.
JSFiddle
Hope that helps.
EDIT: Forgive me, I didn't read the question properly! It seems you want to hide those that don't have today's date. In that case change the == in the if block to !=. This will do the opposite. JSFiddle 2
Related
I am adding a new row in the datatable and its working correctly, I am ordering the table by a field (which is timestamp) which means the newly created row should have index 0 and the rows should be 1,2,3...
however the problem is that the new row is giving -1 when I check its index. So, how can I actually re-order the table when I add a new row so that the newly created row should have index 0?
var myTable = $('#myTable').DataTable();
var rowNode = myTable
.row.add([ btnHtml1, btnHtml ])
.draw();
when I check the index after it has been added:
rowindex = tr.index(); //this gives -1 for the newly created row
Can anyone suggest why is it giving the wrong index?
UPDATE:
function myFunction(this_) {
var tr = $(this_).closest("tr");
rowindex = tr.index(); //this gives the displayed index of the row, NOT the real index
}
I call it from the datatable row like this:
<td>
<button type="button" id="edit_button" onclick='myFunction(this)' name="edit_button">Edit</button>
</td>
I am not able to recreate your problem.
But I am not sure where the tr variable is defined - so, that may be causing an issue.
For a simple test, here is some data:
<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Row Index</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>0</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>1</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>2</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>3</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>4</td>
</tr>
<tr>
<td>Haley Kennedy</td>
<td>5</td>
</tr>
</tbody>
</table>
And here is a test for the data:
<script type="text/javascript">
$(document).ready(function() {
var table = $('#example').DataTable();
var rowNode = table.row.add( ['Quinn Flynn', '?'] ).draw();
console.log(rowNode.index());
});
</script>
This prints 6 to the browser console - the new row has an index of 6, as expected.
Another way to verify this is to loop through all the rows, showing the index of each one:
<script type="text/javascript">
$(document).ready(function() {
var table = $('#example').DataTable();
var rowNode = table.row.add( ['Quinn Flynn', '?'] ).draw();
table.rows().every( function () {
console.log(this.index());
});
});
</script>
This generates the following output in the browser console:
Here we can see that the row for "Quinn Flynn" has the expected index: 6.
Update
Some additional notes based on comments in the answer:
The row index assigned to a row does not change, once it has been assigned, until the row is deleted, or if the data is replaced and refreshed.
Index values are assigned based on the order of the data provided to DataTables - so, for example, in my case, the first row in my HTML table is for "Tiger Nixon" - so that is assigned row index 0. The same applies to data provided by a JSON object.
The row index is independent of the display order of the row (due to sorting and/or filtering).
When you add a new row to DataTables, it is added to the end of the existing rows inside DataTables - and is indexed accordingly. So, my new row is assigned index 6.
It sounds like you want to take the first row as displayed in the table regardless of what its index number is.
There is a shortcut you can use to get that:
console.log(table.row().data());
In my example, this returns an array:
[ "Airi Satou", "4" ]
It works because it uses row() - not rows() and therefore defaults to fetching only one row (the first row!) from the displayed table.
Be aware that if you provide your data as objects, you may not get an array like my example - you may get an object - for example, something like this:
{ "firstName": "Airi Satou", "index": "4" }
I want to highlight the row before month of domain expiry based on the TH Date and time as <td>2017-04-14 17:21:00</td> using javascript or jquery
<table>
<tr>
<th>Domain</th>
<th>Renewal Date</th>
</tr>
<tr>
<td>mydomain.com</td>
<td>2017-04-14 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td>2017-08-14 17:21:00</td>
</tr>
</table>
Here's what we're doing:
Create a Date object for today.
Get all td that have a date. Currently determined by being the second td.
Get the expire date and create a Date object with that string.
Create a Date object for a month from now by using the Date object for today and add 1 month to that date.
Check to see if the expire date is prior to today or within the next month and assign appropriate highlight class.
Check if highlight has been set, if so, add the class to the element.
Please note that this solution adds two different highlights.
Expire dates within a month from now.
Expired dates.
var today = new Date(),
toISO8601 = function ( dateStr, offset ) {
return dateStr.replace( ' ', 'T' ) + ( offset ? offset : 'Z' );
};
$( 'td:nth-child( 2 )' ).each( function( i, el ) {
var $el = $( el ),
expireStr = toISO8601( $.trim( $el.text() ), '-05:00' ),
expires = new Date( expireStr ),
inAMonth = new Date( today.getTime() ),
highlight;
inAMonth.setMonth( inAMonth.getMonth() + 1 );
highlight = expires < today ? 'has-expired' :
expires < inAMonth ? 'about-to-expire' :
false;
if ( highlight ) {
$el
.parent()
.addClass( highlight );
}
} );
.has-expired {
background-color: indianred;
}
.about-to-expire {
background-color: pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<th>Domain</th>
<th>Renewal Date</th>
</tr>
<tr>
<td>mydomain.com</td>
<td>2017-04-14 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td>2017-08-14 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td>2017-03-10 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td>2017-04-15 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td>2018-06-28 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td>2017-04-17 10:21:00</td>
</tr>
</table>
You could use toISOString(), i.e. expires.toISOString(), instead of my toISO8601() method but toISOString() will return the time in UTC where my function allows you to determine the the offset for your own timezone (with fallback to UTC).
Time can be a tricky thing to handle and depending on your needs you might need a library like moment.js.
You can do this by adding an id to the element you want to change so can access it in your javascript code:
<tr>
<td id="expiryDate">mydomain.net</td>
<td>2017-08-14 17:21:00</td>
</tr>
Then in your javascript:
expiryDate = document.getElementById("expiryDate");
// convert expiryDate.innerHTML to date and check if it's within a month is so do:
expiryDate.innerHTML = "<mark>" + expiryDate.innerHTML + "</mark>"
What you can do is create a JS function that will:
Iterate the relevant dom elements (the ones that hold the date text) and get their text value
Create a date object from each date text and compare it to today's date
If the difference between two dates is less than a month add a highlight css class to the parent tr element of the td element that you're checking
Make sure that the highlight css class is defined as you want
Run the JS function on document ready
Run the below example. Cheers...!!!
$(document).ready(function() {
$("table tr").each(function(i) {
var _this = $(this);
if (i != 0) {
var selectDate = $(_this).children("td").eq(1).text();
if (Date.parse($.trim(selectDate)) < Date.parse(new Date())) {
$(_this).addClass('highlight');
}
}
});
});
.highlight {
background-color: #ffdd00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<table>
<tr>
<th>Domain</th>
<th>Renewal Date</th>
</tr>
<tr>
<td>mydomain.com</td>
<td>2017-04-14 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td>2017-02-19 17:21:00</td>
</tr>
<tr>
<td>mydomain.org</td>
<td>2017-08-16 17:21:00</td>
</tr>
<tr>
<td>mydomain.edu</td>
<td>2017-02-15 17:21:00</td>
</tr>
<tr>
<td>mydomain.co.in</td>
<td>2017-08-22 17:21:00</td>
</tr>
</table>
A javascript solution (answer edited as a result in edit in question)
First add a class tag named "date" to all td cell that has a date.
//get all cells with date
today_date = new Date()
expiration_date = new Date().setFullYear(2100, 01, 14)
all_date_td = document.getElementsByClassName("date");
//loop over each html elements
for (var x = 0; x < all_date_td.length; ++x) {
var content = all_date_td[x].innerHTML;
year = Number(content.replace(/[ ].*/, "").split(/-| /)[0])
month = Number(content.replace(/[ ].*/, "").split(/-| /)[1].replace("0", ""))
day = Number(content.replace(/[ ].*/, "").split(/-| /)[2].replace("0", ""))
expiration_date = new Date()
expiration_date.setFullYear(year, month, day)
if (today_date < expiration_date) {
all_date_td[x].style.backgroundColor = "yellow"
}
}
<table>
<tr>
<th>Domain</th>
<th>Renewal Date</th>
</tr>
<tr>
<td>mydomain.com</td>
<td class="date">2017-04-14 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td class="date">2017-08-14 17:21:00</td>
</tr>
<tr>
<td>mydomain.net</td>
<td class="date">2015-08-14 17:21:00</td>
</tr>
</table>
I have a DataTable that sums over each column using footerCallback. This works perfectly given the data in each column, but I also want to add the ability to change each cell's value that is being summed. I've tried adding "contenteditable" to those cells, but making a change does not affect the sum in the footer.
Here is a simple jsfiddle showing the behavior I'm experiencing: https://jsfiddle.net/rantoun/552y9j90/6/
HTML:
<table id="table1">
<thead>
<tr>
<th>Fruit</th>
<th># Eaten</th>
<th># Remaining</th>
</tr>
</thead>
<tfoot>
<tr>
<th align="right">Count</th>
<th align="left"></th>
<th align="left"></th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Apples</td>
<td contenteditable>3</td>
<td contenteditable>8</td>
</tr>
<tr>
<td>Oranges</td>
<td contenteditable>6</td>
<td contenteditable>5</td>
</tr>
<tr>
<td>Bananas</td>
<td contenteditable>2</td>
<td contenteditable>9</td>
</tr>
</tbody>
</table>
jQuery:
$("#table1").DataTable({
"paging": false,
"searching": false,
"info": false,
"footerCallback": function ( row, data, start, end, display ) {
var columns = [1, 2];
var api = this.api();
_.each(columns, function(idx) {
var total = api
.column(idx)
.data()
.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0)
$('tr:eq(0) th:eq('+idx+')', api.table().footer()).html(total);
})
}
});
I have also found the DataTables editor (https://editor.datatables.net/examples/inline-editing/simple), which would be perfect for this situation - but it is not open source. Any ideas on how to mimic this inline editing functionality is welcome. I would like to avoid doing this with modals. Any help is appreciated!
Here is an answer that allows you to edit in place with contenteditable.
Note that this requires the dataTables KeyTable plugin
Working Fiddle here
/* Note - requires datatable.keys plugin */
var table = $("#table1").DataTable({
"keys": true,
"paging": false,
"searching": false,
"info": false,
"footerCallback": function ( row, data, start, end, display ) {
var columns = [1, 2];
var api = this.api();
_.each(columns, function(idx) {
var total = api
.column(idx)
.data()
.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0)
$('tr:eq(0) th:eq('+idx+')', api.table().footer()).html(total);
})
}
});
// keys introduces the key-blur event where we can detect moving off a cell
table
.on( 'key-blur', function ( e, datatable, cell ) {
// The magic part - using the cell object, get the HTML node value,
// put it into the dt cell cache and redraw the table to invoke the
// footer function.
cell.data( $(cell.node()).html() ).draw()
} );
Note - I can foresee that you may get non-numeric data entered. You will have to police that in the key-blur event where you can test the dom node value and act accordingly.
using php to echo json array inline i want js/jquery to populate table according to these data.
HTML table
<table>
<thead>
<tr>
<th>Time</th>
<th data-day='2013-03-15'>15-3</th>
<th data-day='2013-03-16'>16-3</th>
<th data-day='2013-03-17'>17-3</th>
</tr>
</thead>
<tbody>
<tr data-time='09'>
<td>9am</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<script>
var arr=[
{"date":"2013-03-15","id":"4","time_booked":"09:00:00"},
{"date":"2013-03-15","id":"1","time_booked":"09:10:00"},
{"date":"2013-03-17","id":"5","time_booked":"09:30:00"}
];
$.each(arr,function(){
console.log('id:'+this.id+'inside:'+this.date+'|'+this.time_booked);
});
</script>
i want to loop thro arr and according to its date and time_booked write id inside td.
for example first row will go to td with date-day='2013-03-15' and data-time='09'
so how can i do this using javascript ?
im thinking should i include data-day,data-time inside each td in tbody ? or is there a better way to do it ?
current approach:
include data-day inside each tr so html of tbody is
<tr data-time='09'>
<td data-day='2013-03-15'></td>
<td data-day='2013-03-16'></td>
etc..
</tr>
then use js
$.each(arr,function(){
var rday=this.date;
var rtime=this.time_booked;
var sel='tr[data-hr="'+rtime.substr(0,2)+'"]';
var dom=$(sel).find('td[data-day="'+rday+'"]').first();
if(dom.length)dom.append(this.id);
});
but i have a feeling its stupid ! there must be a way to map table using x,y (table head,row head) or there is none ?
I think the jQuery index function is what you're looking for. In the code sample below, I've used it to fetch the colIndex for the date. In this case, it fetches all of the th cells within the table, and uses .index(..) with a selector seeking the required date. This gives the column index of the date you're seeking, and from there it's all pretty straight-forward.
var arr=[
{"date":"2013-03-15","id":"4","time_booked":"0900"},
{"date":"2013-03-15","id":"1","time_booked":"0910"},
{"date":"2013-03-17","id":"5","time_booked":"0930"}
];
$.each(arr,function(){
var cell = GetCellByDateAndTime(this.date, this.time_booked);
$(cell).text(this.id);
});
function GetCellByDateAndTime(date, time) {
var colIndex = $("#BookingsTable th").index($("[data-day='" + date + "']"));
var row = $("#BookingsTable tr[data-time='" + time + "']")
var cell = $(row).children($("td"))[colIndex];
return cell;
}
And a Fiddle.
I spent quite a good time twicking arround tablesorter to get it to work with values such as :"R$ 3.400,95"
Needless to say, I failed miserably. I did try to add a headers: {2: {sorter:"currency"}} property , but it just stopped working at all.
Any one has any idea how to solve this?
The Javascript:
$.tablesorter.addParser({
// set a unique id
id: 'thousands',
is: function(s) {
// return false so this parser is not auto detected
return false;
},
format: function(s) {
// format your data for normalization
return s.replace('$','').replace(/,/g,'');
},
// set type, either numeric or text
type: 'numeric'
});
$(function() {
// call the tablesorter plugin
$("#ver_saida").tablesorter({
decimal: ",",
dateFormat: 'uk',
headers:{2:{sorter:'thousands'}}
});
});
The other headers work fine, but that last property makes that particular header stop working.
Here is the HTML table:
<table id="ver_saida" class="tablesorter">
<thead>
<tr>
<th class="sorter-shortDate dateFormat-ddmmyyyy tablesorter-header">Data<span>n</span></th>
<th>Descrição<span>n</span></th>
<th>Valor<span>n</span></th>
<th>Situação<span style="margin-left:2em;">n</span></th>
</tr>
</thead>
<tr class="pago">
<td class="datout">17/05/2012</td>
<td class="desout">atraso teste</td>
<td class="valout"> R$45,46</td>
<td class="situacao">pago</td>
<td class="delCel"><button class="deletar" href="financeiro_deletar.php?id=36">Deletar</button></td>
</tr>
<tr class="npago late">
<td class="datout">13/06/2012</td>
<td class="desout">IPVA macerati</td>
<td class="valout"> R$5.565,62</td>
<td class="situacao">não pago</td>
<td class="delCel"><button class="deletar" href="financeiro_deletar.php?id=38">Deletar</button></td>
</tr>
<table>
I made an experiment: if I take out the "R$" from the cell html it reads with no problem , but the thing is , I don1t know how to make it ignore the "R$" and still leave it in the table ( for readability porposes).
Modify the 'format' method with:
format: function(s) {
// format your data for normalization
return parseFloat(s.replace(/[^0-9,]/g, '').replace(',', '.'), 10);
},