Font Size:

How to Show Time Remaining of the Assignment as Separate Column in Datalist Inbox

Introduction

This article discusses how to display the time remaining for an assignment as a separate column in the List Inbox, using 3 different methods: JavaScript, BeanShell scripting, and Time Ago Formatter Plugin.

Note
This JavaScript code is only compatible with Joget DX8 and above.

How does it work?

This tutorial includes three sample applications that demonstrate the implementation using JavaScript, BeanShell scripting, and the Time Ago Formatter Plugin. Step-by-step guide for the sample application:

  1. Open the App Center and log in as Administrator.
  2. Download one of the sample applications.
  3. Click Import AppChoose File.
  4. Select the downloaded sample application.
  5. Click UploadPublish.
  6. Under UI Builder, click Launch next to the UI to launch the app.
  7. From the sidebar, click Sample Feedback Form Assignment Process > New Sample Feedback Form.
  8. Type in the Name and select a date in Due Date, and click Submit.
  9. The List Inbox displays the latest record, with a separate column showing the time remaining based on its due date.
  10. Similarly, the Manage Sample Feedback Form list also includes a column that displays the remaining time using the same logic.


Creating a Sample App

The steps outlined below are applicable to all three implementation methods—JavaScript, BeanShell scripting, and the Time Ago Formatter Plugin.

  1. Open the App Center and log in as Administrator.
  2. Click Design New App > Create New App.
  3. Type in the App ID and App Name, and click Save.
  4. Under Form Builder, Click Add New.
  5. Type in the Form ID, Form Name, and Table Name, and click Save.
  6. Drag a Text Field into the Form Builder, and use "name" as its ID.
  7. Drag a Date Picker into the Form Builder and label it as Due Date.
  8. Under Properties for Due Date, select Date and Time stored in UTC for Field Type.
  9. Click Apply Change > Save > Generate App.
  10. Click the boxes next to GENERATE CRUD and GENERATE PROCESS - ASSIGNMENT PROCESS > Generate.
  11. Click Close.
  12. Under List Builder, click the List - Sample Feedback Form from the Quick Navigator.
  13. Drag a new Name column from the palette into the List Builder and position it to the right of the Due Date column.
  14. Label the newly added Name column as Due In.
  15. Click the Due Date column.
  16. Under Properties, select JavaScript Condition from Formatter, and click Add.
  17. Under Conditions, Type 1==1 inside Rule, and click the PROPERTY ASSISTANT icon at Formatting.
  18. Select the #date.dd-MM-yyyy HH:mm:ss# hash variable under Hash Variable and click Insert.
  19. Click Apply Change > Save.
  20. Under UI Builder, click the KB DX9 Show Time Remaining Sample App from the Quick Navigator.
  21. Drag a List Inbox into the sidebar under My Audit Trail.
  22. Use sampleFeedbackForm_inbox as the Menu ID for the List Inbox and select the List - Sample Feedback Form for List
  23. Under Redirection for New Sample Feedback Form, use sampleFeedbackForm_inbox (the Menu ID of the List Inbox) for Url Redirect After Process Started.

JavaScript Implementation

The following steps outline the implementation using JavaScript.

  1. Inside UI Builder, copy the following JavaScript code and paste it into the List View Custom Header inside the UI of List Inbox.
    <script>
    
    $(document).ready(function () {
        // Add custom class to the Due Date column
        $("table tbody tr").each(function () {
            // Find the right column: adjust the index (e.g., td:eq(1)) to match Due Date column
            const td = $(this).find("td:eq(1)"); // Change index as needed
            const text = td.text().trim();
    
            if (text.match(/^\d{4}-\d{2}-\d{2}/)) {
                td.addClass("due-date-column");
                td.attr("data-due-date", text);
            }
        });
    
        // Function to calculate the difference between current date and target date
        function getDateDifference(targetDateString) {
            const parts = targetDateString.split(/[- :]/);
            const targetDate = new Date(parts[0], parts[1] - 1, parts[2], parts[3] || 0, parts[4] || 0, 0);
            const currentDate = new Date();
            let differenceMs = targetDate - currentDate;
            let isPast = false;
    
            if (differenceMs < 0) {
                differenceMs = Math.abs(differenceMs);
                isPast = true;
            }
    
            let differenceSeconds = Math.floor(differenceMs / 1000);
            let differenceMinutes = Math.floor(differenceSeconds / 60);
            let differenceHours = Math.floor(differenceMinutes / 60);
            const differenceDays = Math.floor(differenceHours / 24);
    
            differenceHours %= 24;
            differenceMinutes %= 60;
            differenceSeconds %= 60;
    
            return {
                days: differenceDays,
                hours: differenceHours,
                minutes: differenceMinutes,
                seconds: differenceSeconds,
                isPast: isPast
            };
        }
    
        function getBackgroundColor(difference) {
            if (difference.isPast) {
                return 'red';
            } else if (difference.days > 1 || (difference.days === 1 && (difference.hours > 0 || difference.minutes > 0))) {
                return 'green';
            } else if (difference.hours >= 12) {
                return 'orange';
            } else {
                return 'red';
            }
        }
    
        // For each row with a due date, calculate and show "Due In"
        $('.due-date-column').each(function () {
            const span = $(this);
            const dueDateValue = span.text().trim();
    
            if (dueDateValue) {
                const difference = getDateDifference(dueDateValue);
                const trElement = span.closest('tr')[0];
    
                if (trElement) {
                    const divElement = document.createElement('div');
                    divElement.textContent = `${difference.days} days, ${difference.hours} hours, ${difference.minutes} minutes, ${difference.seconds} seconds`;
                    divElement.style.backgroundColor = getBackgroundColor(difference);
                    divElement.style.padding = '5px';
                    divElement.style.borderRadius = '5px';
                    divElement.style.color = 'white';
                    divElement.style.display = 'inline-block';
    
                    // Insert into a specific column, adjust selector as needed
                    const targetTd = trElement.querySelector('.column_body.column_name.body_column_2');
                    if (targetTd) {
                        targetTd.innerHTML = ''; // Clear existing
                        targetTd.appendChild(divElement);
                    }
                }
            }
        });
    });
    
    
    
    </script>

  2. Similarly, paste the CSS code into the Custom Header inside the UI(List) of Manage Sample Feedback Form.
  3. In the Custom Header, change td:eq(1) to td:eq(2) on line 3, so the code points to the correct Due Date column.
  4. Click Apply Change > Save.

BeanShell Scripting Implementation

The following steps outline the implementation using BeanShell scripting.

Info
While BeanShell is useful for quick scripting, it is resource-intensive. If the same BeanShell script is used in multiple places, it is recommended to use the Time Ago Formatter plugin or JavaScript as a more efficient alternative.
  1. Click List - Sample Feedback Form from the List Builder.
  2. Click the Due In column.
  3. Select BeanShell under Formatter.
  4. Copy the following BeanShell script and paste it inside Script.
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    // Get the due date string from the current row (adjust "due_date")
    String dueDateStr = row.get("due_date");
    
    if (dueDateStr != null && !dueDateStr.isEmpty()) {
        try {
            // Parse the due date with time — adjust format if needed
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            Date dueDate = sdf.parse(dueDateStr);
            Date currentDate = new Date();
    
            long differenceMs = dueDate.getTime() - currentDate.getTime();
            boolean isPast = false;
    
            if (differenceMs < 0) {
                differenceMs = Math.abs(differenceMs);
                isPast = true;
            }
    
            long differenceSeconds = TimeUnit.MILLISECONDS.toSeconds(differenceMs);
            long differenceMinutes = TimeUnit.MILLISECONDS.toMinutes(differenceMs);
            long differenceHours = TimeUnit.MILLISECONDS.toHours(differenceMs);
            long differenceDays = TimeUnit.MILLISECONDS.toDays(differenceMs);
    
            differenceHours = differenceHours % 24;
            differenceMinutes = differenceMinutes % 60;
            differenceSeconds = differenceSeconds % 60;
    
            String backgroundColor = "";
            if (isPast) {
                backgroundColor = "red";
            } else if (differenceDays > 1 || (differenceDays == 1 && (differenceHours > 0 || differenceMinutes > 0))) {
                backgroundColor = "green";
            } else if (differenceHours >= 12) {
                backgroundColor = "orange";
            } else {
                backgroundColor = "red";
            }
    
            String result = "<div style=\"background-color:" + backgroundColor + "; color:white; padding:5px; border-radius:5px; display:inline-block;\">";
            result += differenceDays + " days, " + differenceHours + " hours, " + differenceMinutes + " minutes, " + differenceSeconds + " seconds";
            result += "</div>";
    
            return result;
    
        } catch (Exception e) {
            return "<div style='color:red;'>Invalid date</div>";
        }
    }
    
    return "";
    
  5. Click Apply Change > Save.

Time Ago Formatter Plugin Implementation

The Time Ago Formatter Plugin can be downloaded from the Joget Marketplace. Additional information about the plugin can be found here.

  1. Download the Time Ago Formatter Plugin.
  2. Click the Quick Edit button > Settings > Manage Plugins > Upload Plugin.
  3. Click Choose File > Plugin > Upload.
  4. Click List - Sample Feedback Form from the List Builder.
  5. Delete the existing Due In column.
  6. Copy the existing Due Date column and paste it inside the List Builder.
  7. Label the new column as Due In.
  8. Under Formatter, click Time Ago Datalist Formatter.
  9. Under Date Output Format, select all the formats and check the Include Format in Output checkbox.
  10. Click Apply Change > Save.

The Logic of Showing the Remaining Time of an Assignment

JavaScript Implementation

The following code shows the remaining time of an assignment in a separate column using JavaScript.

<script>

$(document).ready(function () {
    // Add custom class to the Due Date column
    $("table tbody tr").each(function () {
        // Find the right column: adjust the index (e.g., td:eq(1)) to match Due Date column
        const td = $(this).find("td:eq(1)"); // Change index as needed
        const text = td.text().trim();

        if (text.match(/^\d{4}-\d{2}-\d{2}/)) {
            td.addClass("due-date-column");
            td.attr("data-due-date", text);
        }
    });

    // Function to calculate the difference between current date and target date
    function getDateDifference(targetDateString) {
        const parts = targetDateString.split(/[- :]/);
        const targetDate = new Date(parts[0], parts[1] - 1, parts[2], parts[3] || 0, parts[4] || 0, 0);
        const currentDate = new Date();
        let differenceMs = targetDate - currentDate;
        let isPast = false;

        if (differenceMs < 0) {
            differenceMs = Math.abs(differenceMs);
            isPast = true;
        }

        let differenceSeconds = Math.floor(differenceMs / 1000);
        let differenceMinutes = Math.floor(differenceSeconds / 60);
        let differenceHours = Math.floor(differenceMinutes / 60);
        const differenceDays = Math.floor(differenceHours / 24);

        differenceHours %= 24;
        differenceMinutes %= 60;
        differenceSeconds %= 60;

        return {
            days: differenceDays,
            hours: differenceHours,
            minutes: differenceMinutes,
            seconds: differenceSeconds,
            isPast: isPast
        };
    }

    function getBackgroundColor(difference) {
        if (difference.isPast) {
            return 'red';
        } else if (difference.days > 1 || (difference.days === 1 && (difference.hours > 0 || difference.minutes > 0))) {
            return 'green';
        } else if (difference.hours >= 12) {
            return 'orange';
        } else {
            return 'red';
        }
    }

    // For each row with a due date, calculate and show "Due In"
    $('.due-date-column').each(function () {
        const span = $(this);
        const dueDateValue = span.text().trim();

        if (dueDateValue) {
            const difference = getDateDifference(dueDateValue);
            const trElement = span.closest('tr')[0];

            if (trElement) {
                const divElement = document.createElement('div');
                divElement.textContent = `${difference.days} days, ${difference.hours} hours, ${difference.minutes} minutes, ${difference.seconds} seconds`;
                divElement.style.backgroundColor = getBackgroundColor(difference);
                divElement.style.padding = '5px';
                divElement.style.borderRadius = '5px';
                divElement.style.color = 'white';
                divElement.style.display = 'inline-block';

                // Insert into a specific column, adjust selector as needed
                const targetTd = trElement.querySelector('.column_body.column_name.body_column_2');
                if (targetTd) {
                    targetTd.innerHTML = ''; // Clear existing
                    targetTd.appendChild(divElement);
                }
            }
        }
    });
});



</script>
Code Configuration and Customization

The following snippet finds the index number ("td:eq(1)") for the Due Date column in the List Inbox. Adjusts the index number if necessary.

        // Find the right column: adjust the index (e.g., td:eq(1)) to match Due Date column
        const td = $(this).find("td:eq(1)"); // Change index as needed

In this tutorial, the index number for the Due Date column in the List Inbox is 1.

However, the index number for the Due Date column in the Manage Sample Feedback Form is 2.

The following snippet changes the background color for the time remaining based on the thresholds. Adjusts the thresholds if necessary.

    function getBackgroundColor(difference) {
        if (difference.isPast) {
            return 'red';
        } else if (difference.days > 1 || (difference.days === 1 && (difference.hours > 0 || difference.minutes > 0))) {
            return 'green';
        } else if (difference.hours >= 12) {
            return 'orange';
        } else {
            return 'red';
        }
    }

The following snippet replaces the Name column with the time remaining information in the List Inbox. Adjust the column name and body column number if necessary.

                // Insert into a specific column, adjust selector as needed
                const targetTd = trElement.querySelector('.column_body.column_name.body_column_2');

.column_name represents the column name of the time remaining column (Due In column). In this tutorial, the column Name is "name".

.body_column_2 represents the body column number of the Due In column. In this tutorial, the body column number is 2. The body column number for the Due In column can be retrieved by using the element inspector tool in the browser.

BeanShell Scripting Implementation

The following code shows the remaining time of an assignment in a separate column using JavaScript.

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

// Get the due date string from the current row (adjust "due_date")
String dueDateStr = row.get("due_date");

if (dueDateStr != null && !dueDateStr.isEmpty()) {
    try {
        // Parse the due date with time — adjust format if needed
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date dueDate = sdf.parse(dueDateStr);
        Date currentDate = new Date();

        long differenceMs = dueDate.getTime() - currentDate.getTime();
        boolean isPast = false;

        if (differenceMs < 0) {
            differenceMs = Math.abs(differenceMs);
            isPast = true;
        }

        long differenceSeconds = TimeUnit.MILLISECONDS.toSeconds(differenceMs);
        long differenceMinutes = TimeUnit.MILLISECONDS.toMinutes(differenceMs);
        long differenceHours = TimeUnit.MILLISECONDS.toHours(differenceMs);
        long differenceDays = TimeUnit.MILLISECONDS.toDays(differenceMs);

        differenceHours = differenceHours % 24;
        differenceMinutes = differenceMinutes % 60;
        differenceSeconds = differenceSeconds % 60;

        String backgroundColor = "";
        if (isPast) {
            backgroundColor = "red";
        } else if (differenceDays > 1 || (differenceDays == 1 && (differenceHours > 0 || differenceMinutes > 0))) {
            backgroundColor = "green";
        } else if (differenceHours >= 12) {
            backgroundColor = "orange";
        } else {
            backgroundColor = "red";
        }

        String result = "<div style=\"background-color:" + backgroundColor + "; color:white; padding:5px; border-radius:5px; display:inline-block;\">";
        result += differenceDays + " days, " + differenceHours + " hours, " + differenceMinutes + " minutes, " + differenceSeconds + " seconds";
        result += "</div>";

        return result;

    } catch (Exception e) {
        return "<div style='color:red;'>Invalid date</div>";
    }
}

return "";
Code Configuration and Customization

The following snippet gets the values of a column with the name of due_date. Adjust the column name if necessary.

String dueDateStr = row.get("due_date");

The following snippet changes the background color for the time remaining based on the thresholds. Adjusts the thresholds if necessary.

        String backgroundColor = "";
        if (isPast) {
            backgroundColor = "red";
        } else if (differenceDays > 1 || (differenceDays == 1 && (differenceHours > 0 || differenceMinutes > 0))) {
            backgroundColor = "green";
        } else if (differenceHours >= 12) {
            backgroundColor = "orange";
        } else {
            backgroundColor = "red";
        }

Expected outcome

After submitting a new form with a due date, a new record will appear showing the time remaining until the due date. The background color of the time remaining is dynamically updated based on the urgency of the deadline.

JavaScript and BeanShell Scripting Implementations

Records showing the time remaining until the due date will appear in the List Inbox.

Similarly, a similar result will also appear in the Manage Sample Feedback Form.

Time Ago Formatter Plugin Implementation

The Time Ago Formatter Plugin displays the time difference without applying any background color styling.


Download sample app

Download the demo app for How to Show Time Remaining of the Assignment as Separate Column in Datalist Inbox:

 

Created by Aadrian Last modified by Gabriel on Jun 25, 2025