Home > Net >  DataTable: the date is sorted only by the first number (based on dd)
DataTable: the date is sorted only by the first number (based on dd)

Time:02-15

I'm having a problem with sorting the date; what I notice is that the date is sorted only according to the first number (therefore only to dd), as you can verify.

The date format must be dd/MM/yyyy. So the date 11/02/2022 should come before the date 04/12/2021 but this does not happen.

Can you kindly help me?

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link rel="stylesheet" href="//cdn.datatables.net/1.11.4/css/jquery.dataTables.min.css" />
</head>
<body>

<table id="my-table"  width="90%">
        <thead>
            <tr>
                <th >Id</th>
                <th >Title</th>
                <th >Brand</th>
                <th >Section</th>
                <th >Date</th>
                
            </tr>
        </thead>
    </table>
    
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <script src="//cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
    <script>
        $(document).ready(function() {
            $("#my-table").DataTable();
        });
        
        var allart = [{
    title: '2019 Indian FTR 1200 Motorcycle Review', 
    date: '27/11/2021 ', 
    brand:' Guzzi ', 
    section:' In evidence ', 
    id:' 123456 '}, {
    title: "2022 Honda Ruckus Buying Guide", 
    date: '04/12/2021 ', 
    brand:' Honda ', 
    section:' In archive ', 
    id:' 135623 '}, {
    title: "Chaleco López inaugurates' his' museum", 
    date: '22/01/2022 ', 
    brand:' Chaleco ', 
    section:' On the front page ', 
    id:' 256346 '
    }, {
    title: "5 Motorcycles You Don't Have to Shift", 
    date: '11/02/2022 ', 
    brand:' Various ', 
    section:' On the front page', 
    id:' 752372 '
    },{
    title: "2020 Harley-Davidson LiveWire New Electric Motorcycle Review", 
    date: '20/01/2022 ', 
    brand:' Harley-Davidson  ', 
    section:' In archive ', 
    id:' 745672 '
    }, {
    title: "2019 Kawasaki Z400 Review", 
    date: '02/02/2022 ', 
    brand:' Kawasaki  ', 
    section:' In evidence ', 
    id:' 763452 '
    }];

let table = document.getElementById("my-table");
var tbdy = document.createElement('tbody');
                allart.forEach(function (item) {               
                    let child = document.createElement("tr");
                    child.innerHTML = `
                    <td>${item.id}</td>
                    <td>${item.title}</a></td>
                    <td>${item.brand}</td>
                    <td>${item.section}</td>
                    <td>${item.date}</td>
                    `;
                    tbdy.appendChild(child);
                })
                table.appendChild(tbdy);
    </script>
</body>
</html>

CodePudding user response:

Your dates are not in a valid format so DataTable treats them as strings. For DataTable to sort them as dates, you need to convert them to date object. Try this

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link rel="stylesheet" href="//cdn.datatables.net/1.11.4/css/jquery.dataTables.min.css" />
</head>
<body>
    <table id="my-table"  width="90%">
        <thead>
            <tr>
                <th >Id</th>
                <th >Title</th>
                <th >Brand</th>
                <th >Section</th>
                <th >Date</th>
            </tr>
        </thead>
    </table>
    
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <script src="//cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
    <script>
        var allart = [
            {
                title: '2019 Indian FTR 1200 Motorcycle Review', 
                date: '27/11/2021 ', 
                brand:' Guzzi ', 
                section:' In evidence ', 
                id:' 123456 '
            },
            {
                title: "2022 Honda Ruckus Buying Guide", 
                date: '04/12/2021 ', 
                brand:' Honda ', 
                section:' In archive ', 
                id:' 135623 '
            },
            {
                title: "Chaleco López inaugurates' his' museum", 
                date: '22/01/2022 ', 
                brand:' Chaleco ', 
                section:' On the front page ', 
                id:' 256346 '
            },
            {
                title: "5 Motorcycles You Don't Have to Shift", 
                date: '11/02/2022 ', 
                brand:' Various ', 
                section:' On the front page', 
                id:' 752372 '
            },{
                title: "2020 Harley-Davidson LiveWire New Electric Motorcycle Review", 
                date: '20/01/2022 ', 
                brand:' Harley-Davidson  ', 
                section:' In archive ', 
                id:' 745672 '
            },
            {
                title: "2019 Kawasaki Z400 Review", 
                date: '02/02/2022 ', 
                brand:' Kawasaki  ', 
                section:' In evidence ', 
                id:' 763452 '
            }
        ];

        $(document).ready(function() {
            let table = document.getElementById("my-table");
            var tbdy = document.createElement('tbody');
            allart.forEach(function (item) {               
                let child = document.createElement("tr");
                child.innerHTML = `
                <td>${item.id}</td>
                <td>${item.title}</a></td>
                <td>${item.brand}</td>
                <td>${item.section}</td>
                <td>${item.date}</td>
                `;
                tbdy.appendChild(child);
            })
            table.appendChild(tbdy);

            $("#my-table").DataTable({
                columnDefs: [{
                    targets: 3,
                    "render": function ( data, type, row, meta ) {
                        if( type == 'sort' || type == 'type' ){
                            switch(data.trim().toLowerCase()){
                                case 'in evidence': return 0;
                                case 'on the front page': return 1;
                                case 'in archive': return 2;
                                default: return data;
                            }
                        }

                        return data;
                    }
                },{
                    targets: 4,
                    "render": function ( data, type, row, meta ) {
                        if( type == 'sort' || type == 'type' ){
                            let date = data.trim().split('/');

                            if( data.length > 0 ){
                                return new Date(date[1] '/' date[0] '/' date[2]).getTime();
                            }
                        }

                        return data;
                    }
                }],
                order: [[3, 'asc']]
            });
        });
    </script>
</body>
</html>

CodePudding user response:

If you don't mind modifying the data in place (instead of creating a new array), and you are okay with ES6 (which you using let implies that you are), this is quite easy with Array.sort. You'll have to do some finagling with the date, but that doesn't have to show up on your page. You can try it like this

allart.sort((firstObj, secondObj) => {
  // this gives you an array with [year, month, day]
  const firstArr = firstObj.date.split('/').reverse()
  const secondArr = secondObj.date.split('/').reverse()
  // the date object month is 0-indexed, so we're subtracting 1 from the month
  firstArr[1] -= 1
  secondArr[1] -= 1
  firstDate = new Date(firstArr[0], firstArr[1], firstArr[2])
  secondDate = new Date(secondArr[0], secondArr[1], secondArr[2])
  // now to the actual sort logic! Since you indicated newest to oldest, we'll do 
  return secondDate - firstDate
})
  //then you can do your forEach function, etcetera
  • Related