We've updated the ServiceNow Community Code of Conduct, adding guidelines around AI usage, professionalism, and content violations. Read more

How to restrict past date selection in due date field in problem task

Gopal14
Tera Contributor

Hi Team,

 

I want to restrict past date selection in due date field in problem task and Change task tables.

 

I have tried directly in UI Policy, it is working but in form it is showing error, if selected date has passed past date.

 

Apart from that how can i do this

16 REPLIES 16

Itallo Brandão
Tera Guru

Hi Gopal,

Using a UI Policy for date validation logic can be tricky because UI Policies are primarily designed for field behavior (Visible/Mandatory/Read-only), not for complex date math or validation feedback.

The Best Practice: You should use an onChange Client Script. This allows you to catch the date immediately after the user picks it, compare it against the current time using ServiceNow's helper functions (which handle date formats automatically), and clear the field if it is invalid.

Here is the script you can apply to both the Problem Task and Change Task tables.

Solution: onChange Client Script

  • Table: Problem Task [problem_task] (Repeat for Change Task)

  • Type: onChange

  • Field Name: Due date [due_date]

  • UI Type: All

Script:

 
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '') {
        return;
    }

    // 1. Get the user's date format (e.g., dd-MM-yyyy HH:mm:ss)
    // We use the helper function 'getDateFromFormat' provided by ServiceNow
    var format = g_user_date_time_format;
    var dateMs = getDateFromFormat(newValue, format);
    
    // 2. Get the current time in milliseconds
    var now = new Date().getTime();

    // 3. Compare: If Selected Date is less than Now
    if (dateMs < now && dateMs != 0) {
        
        // Clear the invalid value
        g_form.clearValue('due_date');
        
        // Show an error message specifically under the field
        g_form.showFieldMsg('due_date', 'The Due Date cannot be in the past. Please select a future date.', 'error');
    } else {
        // If valid, clear any previous error messages
        g_form.hideFieldMsg('due_date');
    }
}


Optional: Backend Protection (Business Rule)

Client Scripts only work on the Form view. If you want to prevent users from setting past dates via List Edit or API, you should also add an onBefore Business Rule.

  • When: Before Insert/Update

  • Condition: Due date changes

  • Script:

     
    if (current.due_date < gs.nowDateTime()) {
        gs.addErrorMessage('Due date cannot be in the past.');
        current.setAbortAction(true);
    }


Summary:
The Client Script provided above will give you the smooth user experience you are looking for (clearing the field and showing a clean error message) without the limitations of a UI Policy.

If this script solves your validation issue, please mark it as Accepted Solution.

Best regards,
Brandão.

Hi @Itallo Brandão 

 

I have used the above same script,

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
   if (isLoading || newValue === '') {
      return;
   }
    var format = g_user_date_time_format;
    var dateMs = getDateFromFormat(newValue, format);
    var now = new Date().getTime();
    if (dateMs < now && dateMs != 0) {
       // g_form.clearValue('due_date');
        g_form.showFieldMsg('due_date', 'The Due Date cannot be in the past. Please select a future date', 'error');
    } else {
        g_form.hideFieldMsg('due_date');
    }
   
}

Now what 's happening is If I select today, then also it is showing fieldmessage.

 

Gopal14_0-1770185328753.png

 

If I select yesterday, then it is showing field message and error message also, but If I try to save that form, it is saving

Gopal14_1-1770185373107.png

 

 

Gopal14_2-1770185411933.png

 

 

Any changes required here

Hi @Gopal14 ,

You absolutely nailed it in your observation!

The Root Cause:

  1. Why it saves: You are using g_form.clearValue(). Since the field is not mandatory, the system treats "Empty" as a valid state and allows the save.

  2. Why it clears old records: Your logic (especially if using UI Policy) runs when the form loads. A date that was valid yesterday is "past" today, so the script/policy blindly wipes it out when you open the record.

  3. Why "Today" fails: The script compares timestamps (Time). 12:00 PM (Now) is greater than 00:00 AM (Today selected), so it blocks today.

The Solution: You need a script that ignores time, ignores existing database values (only checks changes), and handles the mandatory state.

Use this onChange Client Script:

  • Type: onChange

  • Field: Due date

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    // 1. Safety check: Stop if loading OR if value is empty
    if (isLoading || newValue === '') {
        return;
    }

    // 2. CRITICAL: Only validate if the user actually CHANGED the value.
    // This prevents the script from clearing historical dates when you open the form tomorrow.
    if (newValue == oldValue) {
        return;
    }

    // 3. Get User Format and Setup Dates
    var format = g_user_date_time_format; // or g_user_date_format depending on field type
    var dateMs = getDateFromFormat(newValue, format);
    
    // Create Date Objects to compare "Day vs Day" (ignoring time)
    var selectedDate = new Date(dateMs);
    selectedDate.setHours(0,0,0,0);
    
    var today = new Date();
    today.setHours(0,0,0,0); // Strip time from "Now"

    // 4. Compare
    if (selectedDate < today) {
        g_form.showFieldMsg('due_date', 'Past dates are not allowed. Please select Today or Future.', 'error');
        g_form.clearValue('due_date');
        
        // 5. THE FIX FOR SAVING: Make it mandatory if they try to cheat
        // This forces them to pick a valid date before saving
        g_form.setMandatory('due_date', true); 
    } else {
        g_form.hideFieldMsg('due_date');
    }
}


Why this works:

  1. selectedDate.setHours(0,0,0,0): Fixes the "Today" bug.

  2. if (newValue == oldValue): Fixes the "Old records getting cleared" bug.

  3. setMandatory(true): Fixes the "User can save empty" bug.

If this script solves the logic logic loop, please mark it as Accepted Solution.

Best regards,
Brandão.
=D

@Itallo Brandão   This code working fine in Native view, But when we are testing in SOW(service operations workspace) it is not working