logo

NJP

Differentiate Old Work notes and New Work notes on a String field (5000 characters)

New article articles in ServiceNow Community · Jun 27, 2025 · article

Before BR, Update - true

Condition: current.description.changes();

Choose the table name (Incident or Story, etc.) and field name (description) on the condition - as per your requirement.

(function executeRule(current, previous) { if (!current.description.changes()) return; var oldDesc = (previous.description || '').trim(); var newDesc = (current.description || '').trim(); function tokenize(text) { return text .replace(/\r\n/g, '\n') .split(/(\n+)/) .map(function(chunk) { return chunk.match(/\n+$/) ? chunk : chunk.trim().split(/\s+/); }) .reduce(function(a, b) { return a.concat(b); }, []) .filter(function(w) { return w !== ''; }); } var oldWords = tokenize(oldDesc), newWords = tokenize(newDesc), m = oldWords.length, n = newWords.length; // LCS matrix var L = []; for (var i = 0; i <= m; i++) L[i] = Array(n + 1).fill(0); for (i = m - 1; i >= 0; i--) { for (var j = n - 1; j >= 0; j--) { L[i][j] = oldWords[i] === newWords[j] ? L[i + 1][j + 1] + 1 : Math.max(L[i + 1][j], L[i][j + 1]); } } // Backtrack into diff var ops = [], i = 0, j = 0; while (i < m || j < n) { if (i < m && j < n && oldWords[i] === newWords[j]) { ops.push({ op: 'equal', word: oldWords[i] }); i++; j++; } else if (j < n && (i === m || L[i][j + 1] >= L[i + 1][j])) { ops.push({ op: 'insert', word: newWords[j] }); j++; } else { ops.push({ op: 'delete', word: oldWords[i] }); i++; } } // Format spans var newHtml = '', oldHtml = ''; ops.forEach(function(o) { if (o.op === 'equal') { newHtml += o.word + ' '; oldHtml += o.word + ' '; } else if (o.op === 'insert') { newHtml += '' + o.word + ' '; } else if (o.op === 'delete') { oldHtml += '' + o.word + ' '; } }); // Timestamps var newTimestamp = new GlideDateTime().getDisplayValue(); // now var oldTimestamp = previous.sys_updated_on.getDisplayValue(); // when previous was saved // Build output with labeled timestamps var journalHtml = '[code]' + '

New text as of: ' + newTimestamp + '
' + '
' + newHtml.trim() + '
' + '
' + '
was
' + '
' + '
Old text as of: ' + oldTimestamp + '
' + '
' + oldHtml.trim() + '
' + '[/code]'; // Write to work notes (respects journal + HTML rendering) current.work_notes = journalHtml; })(current, previous);

OUTPUT:

AnishReghu_0-1751014686732.png

AnishReghu_1-1751014751643.png

AnishReghu_2-1751014813412.png

AnishReghu_3-1751014887003.png

OUTPUT AFTER IMPROVISATION:

AnishReghu_0-1751023840260.png

Fig: Differentiate Work notes with timestamp

Note - The reason why we didn't fetch the input from Work notes rather choose a string field (Description) as input and performed the required HTML operation on it, and then output it into a journal entry field like 'Work notes' is because we don't want to alter the very basic structure of the journal entry field 'Work notes' here. I have rather chose 'Work notes' just as a medium to display the formatted string, which ultimately serves the purpose.

Regards,

Anish Reghu

(Hit Like, if the solution helps you)

Don't forget to Bookmark, for easy access in future.

View original source

https://www.servicenow.com/community/developer-articles/differentiate-old-work-notes-and-new-work-notes-on-a-string/ta-p/3302429