How to change mandatory fields on the Propose Major Incident UI Action?

Jonathan Demeul
Tera Expert

Hi everyone,

I've recently been requested to change the OOTB Propose Major Incident UI Action to change which fields are mandatory when proposing a major incident. Right now, the only mandatory field in the dialog box is Work Notes, we want to make Business Impact required as well. How can I change this?

find_real_file.png

How can I achieve the mandatory state Work Notes has and apply it to Business Impact as well?

Kind regards

1 ACCEPTED SOLUTION

Hey,

The client script is directly below the HTML of the UI Page. You should end up with something like the 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">
<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;
		}
	.form-horizontal {
		margin-top: 5px;
		margin-bottom: 20px;
	}
	.propose-modal-textarea {
		resize: vertical;
		min-height: 120px
	}
	#dialog_buttons .btn{
		margin-left: 10px;
		padding-left: 15px;
		padding-right: 15px;
	}
	#work-notes-wrapper .required-marker{
		display: inline-block;
	}
	
	#business-impact-wrapper .required-marker{
		display: inline-block;
	}
		
	#page_timing_div {
		display:none !important;
	}
</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 class="form-horizontal no_next">
	<div class="form-group" id="work-notes-wrapper">
		<label class="col-sm-2 control-label" for="mim-propose-work-notes">
			<span mandatory="true" class="required-marker"></span>
			${gs.getMessage('Work notes')}
		</label>
		<div class="col-sm-10">
			<textarea required="true" class="form-control propose-modal-textarea" id="mim-propose-work-notes" type="text" oninput="proposeModal.workNotesOnChange()" onchange="proposeModal.workNotesOnChange()"></textarea>
		</div>
	</div>
	<div class="form-group" id="business-impact-wrapper">
		<label class="col-sm-2 control-label" for="mim-propose-business-impact">
			<span mandatory="true" class="required-marker"></span>
			${gs.getMessage('Business Impact')}
		</label>
		<div class="col-sm-10">
			<textarea required="true" class="form-control propose-modal-textarea" name="mim-propose-business-impact" id="mim-propose-business-impact" oninput="proposeModal.businessImpactOnChange()" onchange="proposeModal.businessImpactOnChange()"></textarea>
		</div>
	</div>
</div>
<div id="dialog_buttons" class="clearfix pull-right no_next">
		<button type="button" class="btn btn-default" onclick="proposeModal.close()" title="${gs.getMessage('Close the dialog')}">${gs.getMessage('Cancel')}</button>
		<button type="button" class="btn btn-primary disabled" aria-disabled="true" id="mim-propose-button" title="${gs.getMessage('Propose Major Incident')}" onclick="proposeModal.propose()">${gs.getMessage('Propose')}</button>
</div>
</j:jelly>

 

And in the Client Script:

addLoadEvent(function() {
	(function(global) {
		var workNotes = $("mim-propose-work-notes");
		var businessImpact = $("mim-propose-business-impact");
		var workNotesWrapper = $('work-notes-wrapper');
		var bussImpWrapper = $("business-impact-wrapper");
		var proposeBtn = $('mim-propose-button');
		workNotes.focus();
		var dialog;
		if(!config.workspace) {
			dialog = GlideModal.prototype.get("sn_major_inc_mgmt_mim_propose");

			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()) {
				workNotesWrapper.removeClassName('is-filled');
				proposeBtn.addClassName('disabled');
				proposeBtn.writeAttribute('aria-disabled', true);
			} else {
// 				workNotesWrapper.addClassName('is-filled');
// 				proposeBtn.removeClassName('disabled');
// 				proposeBtn.writeAttribute('aria-disabled', false);
				checkMandatoryFields();
			}
		}

		function businessImpactOnChange() {
			if (!businessImpact.value.trim()) {
				bussImpWrapper.removeClassName('is-filled');
				proposeBtn.addClassName('disabled');
				proposeBtn.writeAttribute('aria-disabled', true);
			} else {
// 				bussImpWrapper.addClassName('is-filled');
// 				proposeBtn.removeClassName('disabled');
// 				proposeBtn.writeAttribute('aria-disabled', false);
				checkMandatoryFields();
			}
		}

		function checkMandatoryFields(){
			if(workNotes.value.trim() && businessImpact.value.trim()){
				bussImpWrapper.addClassName('is-filled');
				proposeBtn.removeClassName('disabled');
				proposeBtn.writeAttribute('aria-disabled', false);
				workNotesWrapper.addClassName('is-filled');
				proposeBtn.removeClassName('disabled');
				proposeBtn.writeAttribute('aria-disabled', false);
			}
		}

		function propose() {
			if (!proposeBtn.hasClassName('disabled')) {
				var msg = getMessage("Proposed as major incident candidate");
				var notes = workNotes.value.trim();
				var bi = businessImpact.value.trim();
				if(!config.workspace) {
					g_form.getControl('work_notes').value = msg + "\n" + notes;
					if (businessImpact.value)
						g_form.setValue('business_impact', bi);
					close();
					gsftSubmit(null, g_form.getFormElement(), 'sysverb_mim_propose');
				}else {
					iframeMsgHelper.confirm({
						msg: msg,
						workNotes: notes,
						businessImpact: bi
					});
				}
			}
		}

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

 

find_real_file.png

 

View solution in original post

8 REPLIES 8

4 years after and SN has not made this something configurable on properties. Your insight was really helpful here.

Guys, have you managed to get it working in Workspace as well?
Thanks!

Same question here! I digged everywhere within the components of the Store Application, but failed to find it so far.

work space is not working 
i want to make madatory the business impact field  in SOW also