Business Impact mandatory

Rajendar3
Tera Contributor

Make business impact mandatory in order to promote an incident to a Major Incident and Propose major incident  for both UI actions ,I'm not able to modify the "mim_propose" UI page , Could you help me with this code.

any help would be much appreciated .

 

Rajendar3_1-1674494961346.png

For both UI actions (Propose & Promote) Business Impact field should be mandatory

Rajendar3_2-1674495047843.png

 

@Pradeep Sharma @Community Alums @Basheer @jaheerhattiwale @Ankur Bawiskar 

 

 

1 ACCEPTED SOLUTION

jaheerhattiwale
Mega Sage
Mega Sage

@Rajendar3 Tried and Tested solution.

 

I have updated the code of "mim_workbench_promote" ui page. like below

 

HTML:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<!-- To use <g:ui_reference/> in this UI page, below are the required JS.
<g:requires name="scripts/functions.js" includes="true" />
<g:requires name="scripts/functions_reference.js" includes="true" />
<g:requires name="scripts/utils.js" includes="true" />
<g:requires name="scripts/accessibility_tabindex.js" includes="true" />
<g:requires name="scripts/slushbucket.js" includes="true" />
<g:requires name="scripts/ac.js" includes="true" />
<g:requires name="scripts/ac_derived_field_support.js" includes="true" />
<g:requires name="scripts/popups.js" includes="true" />
<g:requires name="scripts/classes/AutoComplete.js" includes="true" />
<g:requires name="scripts/classes/SlushBucket.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXReferenceControls.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXOtherCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXReferenceCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXReferenceCompleterMulti.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXTableCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXEmailClientCompleter.js" includes="true" />
<j2:set var="jvar_theme" value="$[gs.getProperty('glide.css.theme.ui16')]"/>
<g2:requires name="styles/css_includes_doctype.css" includes="true" params="c=$[gs.getCssCacheVersionString()]$[jvar_theme]" />
-->
<g:evaluate var="jvar_isNextPg" expression="RP.getParameterValue('sysparm_next_pg')"/>
<j:if test="${jvar_isNextPg == 'true'}">
<style>
.no_next {
display: none !important;
}
</style>
</j:if>
<style>
body {
overflow-x: hidden;
}
#mim-promote-form {
overflow: hidden;
}
.form-horizontal {
margin-top: 5px;
margin-bottom: 20px;
}
.promote-modal-textarea {
resize: vertical;
min-height: 120px
}
#dialog_buttons .btn{
margin-left: 10px;
padding-left: 15px;
padding-right: 15px;
text-align: right;
}
#work-notes-wrapper .required-marker {
display: inline-block;
}

#business-impact-wrapper .required-marker {
display: inline-block;
}
</style>
<script>
var config = {
workspace: '${JS_STRING:RP.getParameterValue('sysparm_workspace')}' == 'true'
};
var iframeMsgHelper = (function () {
function createPayload(action, modalId, data) {
return {
messageType: 'IFRAME_MODAL_MESSAGE_TYPE',
modalAction: action,
modalId: modalId,
data: (data ? data : {})
};
}
function pm(window, payload) {
if (window.parent === window) {
console.warn('Parent is missing. Is this called inside an iFrame?');
return;
}
window.parent.postMessage(payload, location.origin);
}
function IFrameMessagingHelper(window) {
this.window = window;
this.src=location.href;
this.messageHandler = this.messageHandler.bind(this);
this.window.addEventListener('message', this.messageHandler);
}
IFrameMessagingHelper.prototype.messageHandler = function (e) {
if (e.data.messageType !== 'IFRAME_MODAL_MESSAGE_TYPE' || e.data.modalAction !== 'IFRAME_MODAL_ACTION_INIT') {
return;
}
this.modalId = e.data.modalId;
};
IFrameMessagingHelper.prototype.confirm = function (data) {
var payload = createPayload('IFRAME_MODAL_ACTION_CONFIRMED', this.modalId, data);
pm(this.window, payload);
};
IFrameMessagingHelper.prototype.cancel = function (data) {
var payload = createPayload('IFRAME_MODAL_ACTION_CANCELED', this.modalId, data);
pm(this.window, payload);
};
return new IFrameMessagingHelper(window);
}());
</script>
<div id="mim-promote-form">
<div class="form-horizontal no_next">
<div class="form-group" id="work-notes-wrapper">
<label class="col-sm-2 control-label" for="mim-promote-work-notes">
<span mandatory="true" class="required-marker label_description"></span>
${gs.getMessage('Work notes')}
</label>
<div class="col-sm-10">
<textarea required="true" class="form-control promote-modal-textarea" id="mim-promote-work-notes" type="text" oninput="promoteModal.workNotesOnChange()" onchange="promoteModal.workNotesOnChange()"></textarea>
</div>
</div>
<div class="form-group" id="business-impact-wrapper">
<label class="col-sm-2 control-label" for="mim-promote-business-impact">
<span mandatory="true" class="required-marker label_description"></span>
${gs.getMessage('Business Impact')}
</label>
<div class="col-sm-10">
<textarea required="true" class="form-control promote-modal-textarea" name="mim-promote-business-impact" id="mim-promote-business-impact" oninput="promoteModal.workNotesOnChange()"></textarea>
</div>
</div>
</div>
<div id="dialog_buttons" class="clearfix pull-right no_next">
<button type="button" class="btn btn-default" onclick="promoteModal.close()" title="${gs.getMessage('Close the dialog')}">${gs.getMessage('Cancel')}</button>
<button type="button" class="btn btn-primary disabled" aria-disabled="true" id="mim-promote-button" title="${gs.getMessage('Promote to Major Incident')}" onclick="promoteModal.promote()">${gs.getMessage('Promote')}</button>
</div>
</div>
</j:jelly>

 

 

Client Script:

(function(global) {
var workNotes = $("mim-promote-work-notes");
var businessImpact = $("mim-promote-business-impact");
var workNotesWrapper = $('work-notes-wrapper');
var businessImpactWrapper = $('business-impact-wrapper');
var promoteBtn = $('mim-promote-button');
workNotes.focus();
var dialog, resizeObserver;
if(config.workspace) {
var modalTextAreas = document.querySelectorAll(".promote-modal-textarea");
var iframeStyle = window.frameElement.style;
var formContainer = $("mim-promote-form");
resizeObserver = new ResizeObserver(function(entries) {
iframeStyle.height = formContainer.offsetHeight + 5 + "px";
});
for(var i=0; i < modalTextAreas.length; i++) {
resizeObserver.observe(modalTextAreas[i]);
}
} else {
dialog = GlideModal.prototype.get("sn_major_inc_mgmt_mim_workbench_promote");
var currentWorkNotes = dialog.getPreference('WORK_NOTES');
if(currentWorkNotes) {
workNotes.value = currentWorkNotes;
workNotesOnChange();
}
var currentBusinessImpact = dialog.getPreference('BUSINESS_IMPACT');
if(currentBusinessImpact)
businessImpact.value = currentBusinessImpact;
}
function _debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}

function workNotesOnChange() {
if ((!workNotes.value.trim()) || (!businessImpact.value.trim())) {
workNotesWrapper.removeClassName('is-filled');
businessImpactWrapper.removeClassName('is-filled');
promoteBtn.addClassName('disabled');
promoteBtn.writeAttribute('aria-disabled', true);
} else {
workNotesWrapper.addClassName('is-filled');
businessImpactWrapper.addClassName('is-filled');
promoteBtn.removeClassName('disabled');
promoteBtn.writeAttribute('aria-disabled', false);
}
}

function _promoteRestCall(record) {
var dfd = $j.Deferred();
var api = '/api/sn_major_inc_mgmt/mim/actions/' + window.NOW.MAJOR_INCIDENT_WORKBENCH.sys_id;
var data = {
action: 'PROMOTE',
record: record
};
$j.ajax({
type: 'POST',
url: api,
data: JSON.stringify(data),
success: function(data) {
dfd.resolve(data);
},
error: function() {
dfd.reject();
},
contentType: "application/json",
dataType: 'json'
});
return dfd.promise();
}

function promote() {
getMessage("Promoted to a major incident", function(msg) {
var updateWorkNotes = msg + "\n" + workNotes.value.trim();
if (!promoteBtn.hasClassName('disabled')) {
if (window.NOW.MAJOR_INCIDENT_WORKBENCH) {
var record = {};
record.work_notes = updateWorkNotes;
record.business_impact = businessImpact.value;
_promoteRestCall(record).then(function() {
dialog.setPreference('reload', true);
close();
});
} else {
//When UI Page is rendered from Form UI Action
if(config.workspace) {
iframeMsgHelper.confirm({
msg: msg,
workNotes: workNotes.value.trim(),
businessImpact: businessImpact.value.trim()
});
} else {
g_form.getControl('work_notes').value = updateWorkNotes;
g_form.setValue('business_impact', businessImpact.value);
GlideModal.prototype.get('sn_major_inc_mgmt_mim_workbench_promote').destroy();
gsftSubmit(null, g_form.getFormElement(), 'sysverb_mim_accept');
}
}
}
});
}

function close() {
if(config.workspace) {
resizeObserver.disconnect();
window.location.href = window.location.href + '&sysparm_next_pg=true';
} else {
dialog.destroy();
}
}
global.promoteModal = {
promote: promote,
close: close,
workNotesOnChange: _debounce(workNotesOnChange, 200) // Only execute when left idle for 200 ms
};
})(window);

 

 

Note:

Follow the same for "mim_propose" ui page as well.

 

Please mark as correct answer if this solves your issue.

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

View solution in original post

7 REPLIES 7

jaheerhattiwale
Mega Sage
Mega Sage

@Rajendar3 Tried and Tested solution.

 

I have updated the code of "mim_workbench_promote" ui page. like below

 

HTML:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<!-- To use <g:ui_reference/> in this UI page, below are the required JS.
<g:requires name="scripts/functions.js" includes="true" />
<g:requires name="scripts/functions_reference.js" includes="true" />
<g:requires name="scripts/utils.js" includes="true" />
<g:requires name="scripts/accessibility_tabindex.js" includes="true" />
<g:requires name="scripts/slushbucket.js" includes="true" />
<g:requires name="scripts/ac.js" includes="true" />
<g:requires name="scripts/ac_derived_field_support.js" includes="true" />
<g:requires name="scripts/popups.js" includes="true" />
<g:requires name="scripts/classes/AutoComplete.js" includes="true" />
<g:requires name="scripts/classes/SlushBucket.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXReferenceControls.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXOtherCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXReferenceCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXReferenceCompleterMulti.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXTableCompleter.js" includes="true" />
<g:requires name="scripts/classes/ajax/AJAXEmailClientCompleter.js" includes="true" />
<j2:set var="jvar_theme" value="$[gs.getProperty('glide.css.theme.ui16')]"/>
<g2:requires name="styles/css_includes_doctype.css" includes="true" params="c=$[gs.getCssCacheVersionString()]$[jvar_theme]" />
-->
<g:evaluate var="jvar_isNextPg" expression="RP.getParameterValue('sysparm_next_pg')"/>
<j:if test="${jvar_isNextPg == 'true'}">
<style>
.no_next {
display: none !important;
}
</style>
</j:if>
<style>
body {
overflow-x: hidden;
}
#mim-promote-form {
overflow: hidden;
}
.form-horizontal {
margin-top: 5px;
margin-bottom: 20px;
}
.promote-modal-textarea {
resize: vertical;
min-height: 120px
}
#dialog_buttons .btn{
margin-left: 10px;
padding-left: 15px;
padding-right: 15px;
text-align: right;
}
#work-notes-wrapper .required-marker {
display: inline-block;
}

#business-impact-wrapper .required-marker {
display: inline-block;
}
</style>
<script>
var config = {
workspace: '${JS_STRING:RP.getParameterValue('sysparm_workspace')}' == 'true'
};
var iframeMsgHelper = (function () {
function createPayload(action, modalId, data) {
return {
messageType: 'IFRAME_MODAL_MESSAGE_TYPE',
modalAction: action,
modalId: modalId,
data: (data ? data : {})
};
}
function pm(window, payload) {
if (window.parent === window) {
console.warn('Parent is missing. Is this called inside an iFrame?');
return;
}
window.parent.postMessage(payload, location.origin);
}
function IFrameMessagingHelper(window) {
this.window = window;
this.src=location.href;
this.messageHandler = this.messageHandler.bind(this);
this.window.addEventListener('message', this.messageHandler);
}
IFrameMessagingHelper.prototype.messageHandler = function (e) {
if (e.data.messageType !== 'IFRAME_MODAL_MESSAGE_TYPE' || e.data.modalAction !== 'IFRAME_MODAL_ACTION_INIT') {
return;
}
this.modalId = e.data.modalId;
};
IFrameMessagingHelper.prototype.confirm = function (data) {
var payload = createPayload('IFRAME_MODAL_ACTION_CONFIRMED', this.modalId, data);
pm(this.window, payload);
};
IFrameMessagingHelper.prototype.cancel = function (data) {
var payload = createPayload('IFRAME_MODAL_ACTION_CANCELED', this.modalId, data);
pm(this.window, payload);
};
return new IFrameMessagingHelper(window);
}());
</script>
<div id="mim-promote-form">
<div class="form-horizontal no_next">
<div class="form-group" id="work-notes-wrapper">
<label class="col-sm-2 control-label" for="mim-promote-work-notes">
<span mandatory="true" class="required-marker label_description"></span>
${gs.getMessage('Work notes')}
</label>
<div class="col-sm-10">
<textarea required="true" class="form-control promote-modal-textarea" id="mim-promote-work-notes" type="text" oninput="promoteModal.workNotesOnChange()" onchange="promoteModal.workNotesOnChange()"></textarea>
</div>
</div>
<div class="form-group" id="business-impact-wrapper">
<label class="col-sm-2 control-label" for="mim-promote-business-impact">
<span mandatory="true" class="required-marker label_description"></span>
${gs.getMessage('Business Impact')}
</label>
<div class="col-sm-10">
<textarea required="true" class="form-control promote-modal-textarea" name="mim-promote-business-impact" id="mim-promote-business-impact" oninput="promoteModal.workNotesOnChange()"></textarea>
</div>
</div>
</div>
<div id="dialog_buttons" class="clearfix pull-right no_next">
<button type="button" class="btn btn-default" onclick="promoteModal.close()" title="${gs.getMessage('Close the dialog')}">${gs.getMessage('Cancel')}</button>
<button type="button" class="btn btn-primary disabled" aria-disabled="true" id="mim-promote-button" title="${gs.getMessage('Promote to Major Incident')}" onclick="promoteModal.promote()">${gs.getMessage('Promote')}</button>
</div>
</div>
</j:jelly>

 

 

Client Script:

(function(global) {
var workNotes = $("mim-promote-work-notes");
var businessImpact = $("mim-promote-business-impact");
var workNotesWrapper = $('work-notes-wrapper');
var businessImpactWrapper = $('business-impact-wrapper');
var promoteBtn = $('mim-promote-button');
workNotes.focus();
var dialog, resizeObserver;
if(config.workspace) {
var modalTextAreas = document.querySelectorAll(".promote-modal-textarea");
var iframeStyle = window.frameElement.style;
var formContainer = $("mim-promote-form");
resizeObserver = new ResizeObserver(function(entries) {
iframeStyle.height = formContainer.offsetHeight + 5 + "px";
});
for(var i=0; i < modalTextAreas.length; i++) {
resizeObserver.observe(modalTextAreas[i]);
}
} else {
dialog = GlideModal.prototype.get("sn_major_inc_mgmt_mim_workbench_promote");
var currentWorkNotes = dialog.getPreference('WORK_NOTES');
if(currentWorkNotes) {
workNotes.value = currentWorkNotes;
workNotesOnChange();
}
var currentBusinessImpact = dialog.getPreference('BUSINESS_IMPACT');
if(currentBusinessImpact)
businessImpact.value = currentBusinessImpact;
}
function _debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}

function workNotesOnChange() {
if ((!workNotes.value.trim()) || (!businessImpact.value.trim())) {
workNotesWrapper.removeClassName('is-filled');
businessImpactWrapper.removeClassName('is-filled');
promoteBtn.addClassName('disabled');
promoteBtn.writeAttribute('aria-disabled', true);
} else {
workNotesWrapper.addClassName('is-filled');
businessImpactWrapper.addClassName('is-filled');
promoteBtn.removeClassName('disabled');
promoteBtn.writeAttribute('aria-disabled', false);
}
}

function _promoteRestCall(record) {
var dfd = $j.Deferred();
var api = '/api/sn_major_inc_mgmt/mim/actions/' + window.NOW.MAJOR_INCIDENT_WORKBENCH.sys_id;
var data = {
action: 'PROMOTE',
record: record
};
$j.ajax({
type: 'POST',
url: api,
data: JSON.stringify(data),
success: function(data) {
dfd.resolve(data);
},
error: function() {
dfd.reject();
},
contentType: "application/json",
dataType: 'json'
});
return dfd.promise();
}

function promote() {
getMessage("Promoted to a major incident", function(msg) {
var updateWorkNotes = msg + "\n" + workNotes.value.trim();
if (!promoteBtn.hasClassName('disabled')) {
if (window.NOW.MAJOR_INCIDENT_WORKBENCH) {
var record = {};
record.work_notes = updateWorkNotes;
record.business_impact = businessImpact.value;
_promoteRestCall(record).then(function() {
dialog.setPreference('reload', true);
close();
});
} else {
//When UI Page is rendered from Form UI Action
if(config.workspace) {
iframeMsgHelper.confirm({
msg: msg,
workNotes: workNotes.value.trim(),
businessImpact: businessImpact.value.trim()
});
} else {
g_form.getControl('work_notes').value = updateWorkNotes;
g_form.setValue('business_impact', businessImpact.value);
GlideModal.prototype.get('sn_major_inc_mgmt_mim_workbench_promote').destroy();
gsftSubmit(null, g_form.getFormElement(), 'sysverb_mim_accept');
}
}
}
});
}

function close() {
if(config.workspace) {
resizeObserver.disconnect();
window.location.href = window.location.href + '&sysparm_next_pg=true';
} else {
dialog.destroy();
}
}
global.promoteModal = {
promote: promote,
close: close,
workNotesOnChange: _debounce(workNotesOnChange, 200) // Only execute when left idle for 200 ms
};
})(window);

 

 

Note:

Follow the same for "mim_propose" ui page as well.

 

Please mark as correct answer if this solves your issue.

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

@Rajendar3 

Result:

jaheerhattiwale_0-1674541534900.png

 

 

Promote button will be available only when both fields are filled.

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

this is not working for me.. The Propose or Promote button does not show active even you enter the comments. It is disabled

Could you also provide the code to make the work notes field not mandatory?