0

I've a table with this columns: name, age, birthday I also have a input field with date.

birthday is populated with a date. I want to create 2 buttons like "select users with age > 30" and "select user with age > 60".

var table= $('#users').DataTable({
        "drawCallback": updateDays(moment()),
        paging: false,
        columnDefs: [ {
            orderable: false,
            className: 'select-checkbox',
            targets:   0
        } ],
        select: {
            style:    'multi'
        },
        order: [[ 1, 'asc' ]],
        buttons: [{'selectAll',
            'selectNone',
        ],

[...]

$('input[id="dateOfBirthday"]').daterangepicker({
            "autoApply": true,
            "singleDatePicker": true,
            "showDropdowns": true,
            locale: {
                format: 'DD-MM-YYYY'
            }
        }, function(start, end, label) {
        updateDays(start);
        $('input[id="dateOfBirthday"]').val(start.format("DD-MM-YY"));
    });

And when you change the date, it update the years inside the table

function updateDays(startDate) {
    $('.age').each(
        function () {
            var diff;
            var start;
            start = $(this).closest('tr').children('.birthday').text();
            start= moment(start, "DD/MM/YY");
            diff = startDate.diff(start, 'days');
            $(this).text(diff);
        });

[...]

The code is adapted from the real project because it's too long so please understand if there are some coding errors; what it's important here is the logic behind the code, not the code itself.

Thanks

2
  • May you explain a bit business logic behind? As I understood, your input field specifies some data and your buttons filter the table to match the users who are older than 30 (or older than 60) by the time this date comes? Also, I couldn't grasp the logic of updating the years (of birthdays?), since provided context is insufficient. Could you share some more details? Commented Mar 7, 2019 at 10:01
  • Hello @ygorbunkov , thanks for the reply. I've this input field where I select a date (for example 2020/03/07). In the table I've user John Doe, born in 1988. So the age field will be updated to 32. If I change the date to 2021/07/20 the age will be 33. If I choose 2005/01/10 the age will be 17 so when I click "users with age > 30" in the first 2 cases the user will be selected, but not on the last case (year 2005). Commented Mar 7, 2019 at 10:37

1 Answer 1

1

I believe, this code does the job just fine:

//define source data
const srcData = [
  {name: 'Christopher Evans', birthday: '13/06/1981'},
  {name: 'Samuel L Jackson', birthday: '21/12/1948'},
  {name: 'Tom Holland', birthday: '01/06/1996'},
  {name: 'Robert Downey Jr', birthday: '04/04/1965'}
];
//define get age function
const getAgeAtDate = (currentDate, birthDate) => {
  const thisYearBirthday = new Date(currentDate.getFullYear(), birthDate.getMonth(), birthDate.getDate());
  const yearDiff = currentDate.getFullYear()-birthDate.getFullYear();
  return thisYearBirthday>currentDate ? yearDiff - 1 : yearDiff;
};
//define reference date (today by default)
var referenceDate = new Date();
//define filter margin 30, 60, 0
var filterMargin = 0;
//define dataTable object
const dataTable = $('#mytable').DataTable({
  sDom: 't',
  data: srcData,
  columns: [
    {title:'name', data:'name'},
    {title:'birthday', data:'birthday'},
    {title:'age as of today', data: null, render: (data, type, row)=> {
      const today = new Date();
      const birthday = new Date(...row.birthday.split('/').reverse());
      return getAgeAtDate(today, birthday);
    }}
  ]
});
//define external search function to compare with referenceDate
$.fn.DataTable.ext.search.push((settings, row, index, rowObj)=>{
  const birthday = new Date(...rowObj.birthday.split('/').reverse());
  return getAgeAtDate(referenceDate, birthday)>filterMargin;
});
//set reference date callback
$('#referenceDate').on('change', function(){
  if(!$(this).val()){
    referenceDate = new Date();
    return;
  };
  referenceDate = new Date(...$(this).val().split('-'));
  dataTable.column(2).header().innerText = 'age as of '+referenceDate.toLocaleDateString();
  dataTable.rows().every(function(){
    const birthday = new Date(...this.data().birthday.split('/').reverse());
    const rowNum = this.index();
    dataTable.cell(rowNum,2).node().innerText = getAgeAtDate(referenceDate, birthday)
  })
});
//apply filter
$('.filter').on('click', function(){
  filterMargin = $(this).attr('margin');
  dataTable.draw();
});
<!doctype html>
<html>
<head>
  <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
  <input id="referenceDate" type="date"></input>
  <button class="filter" margin="30">older than 30</button>
  <button class="filter" margin="60">older than 60</button>
  <button class="filter" margin="0">clear filter</button>
  <table id="mytable"></table>
</body>
</html>

Sign up to request clarification or add additional context in comments.

2 Comments

Hello @ygorbunkov, what if I want to select the rows? I mean, i want to keep all rows visible, just select the user with age > 30 for example
You're going to need select extension (datatables.net/extensions/select) and slight changes to the above code: codepen.io/ygorbunkov/pen/PLjoRw?editors=1010

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.