How to write the validation for multirow variable set start date through catalog client script ???

Manikantahere
Tera Contributor

I am writing a script for field validation in multirow variable set where current record start date should be always greater than previous record end date and this also should include the logic where this should check if I change row in between after inserting multiple rows.

The below script is working when I am creating a new row.

function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }
g_form.clearValue('end_date');
   var mrvs = g_service_catalog.parent.getValue('itinerary');
    if (mrvs.length>2) {
        //alert(mrvs.length);
        var obj = JSON.parse(mrvs);
        if (newValue < obj[obj.length-1].end_date) {
            alert('The start date in this itinerary must be after the end date of the previous itinerary.');
            g_form.clearValue('start_date');
        }
    }
}

 

Lets Consider the scenario 

 

2nd row start date I given as  22/06/25 which is greater than first row end date i.e. 20/06/25

now  I have added rows 5 and now want to edit second row where I want to change the date to 21/06. 

but I am getting the alert which should not right?


 

 

4 REPLIES 4

Ankur Bawiskar
Tera Patron
Tera Patron

@Manikantahere 

User can delete the 1st row and add 3rd, 4th row so this logic won't work as user can play with MRVS multiple times.

you can use onSubmit and get the complete JSON and then compare all the dates.

If you still want to use onChange then update script as this

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

    // Get all rows in the MRVS
    var mrvs = g_service_catalog.parent.getValue('itinerary');
    if (!mrvs) return;

    var rows = JSON.parse(mrvs);

    // Find the index of the current row
    var currentSysId = g_form.getUniqueValue(); // Unique sys_id for the current MRVS row
    var currentIndex = -1;

    for (var i = 0; i < rows.length; i++) {
        if (rows[i].sys_id == currentSysId) {
            currentIndex = i;
            break;
        }
    }

    // Only validate if not the first row
    if (currentIndex > 0) {
        var previousEndDate = rows[currentIndex - 1].end_date;
        var currentStartDate = newValue;

        // Optional: Convert to Date objects for safe comparison
        var prevEnd = new Date(previousEndDate);
        var currStart = new Date(currentStartDate);

        if (currStart <= prevEnd) {
            alert('The start date in this itinerary must be after the end date of the previous itinerary.');
            g_form.clearValue('start_date');
        }
    }
}

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }
g_form.clearValue('end_date');
   var mrvs = g_service_catalog.parent.getValue('itinerary');
     var obj = JSON.parse(mrvs);
   var index = -1 ;
   var currentSysId = g_form.getUniqueValue();
   alert("cuurent sys id is :" +currentSysId);
     
	for(var i =0;i<obj.length;i++){
		if(obj[i].sys_id == currentSysId){
			index = i;
			alert("index value is "+i);
			break;
		}
	}
    if (index > 0) {
        //alert(mrvs.length);
      var previousEndDate = obj[index-1].end_date;
		alert(JSON.stringify(mrvs));
        alert(newValue+obj[obj.length-1].end_date);
       
        if (newValue < previousEndDate) {
            alert('The start date in this itinerary must be after the end date of the previous itinerary.');
            g_form.clearValue('start_date');
        }
    }
}

 

I am only getting alert current sys Id is.... and  its not going into for loop and executing remaining logic 

@Manikantahere 

I will suggest to use onSubmit instead.

There should be something unique for each of your row so that you determine the row number

Like sequence number

But try this script once

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

    // Get all rows in the MRVS
    var mrvs = g_service_catalog.parent.getValue('itinerary');
    if (!mrvs) return;

    var rows = JSON.parse(mrvs);

    // Get current row's start_date and end_date values
    var currStart = g_form.getValue('start_date');
    var currEnd = g_form.getValue('end_date');

    // Find the index of the current row by matching all field values
    var index = -1;
    for (var i = 0; i < rows.length; i++) {
        // Compare all relevant fields to identify the row
        if (rows[i].start_date == currStart && rows[i].end_date == currEnd) {
            index = i;
            break;
        }
    }

    if (index > 0) {
        var previousEndDate = rows[index - 1].end_date;

        // Convert to Date objects for safe comparison
        var prevEnd = new Date(previousEndDate);
        var currStartDate = new Date(newValue);

        if (currStartDate <= prevEnd) {
            alert('The start date in this itinerary must be after the end date of the previous itinerary.');
            g_form.clearValue('start_date');
        }
    }
}

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

@Manikantahere 

Hope you are doing good.

Did my reply answer your question?

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader