- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-11-2021 04:16 PM
Hi,
you'll need to modify the mim_propose UI Page to add the following line at line 88 onto line 96
<span mandatory="true" class="required-marker"></span>
You'll also need to duplicate the workNotesOnChange client script to mimic the behaviour for your business impact field.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-11-2021 11:45 PM
Hi Kieran,
I've edited the UI Page by adding your line of code here:
<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">
<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 class="form-control propose-modal-textarea" name="mim-propose-business-impact" id="mim-propose-business-impact"></textarea>
</div>
</div>
</div>
What am I missing? The field is not mandatory as per this change. What do you mean with "You'll also need to duplicate the workNotesOnChange client script to mimic the behaviour for your business impact field."
I can't find a client script with that name.
Kind regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-12-2021 03:18 PM
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);
});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-31-2021 04:41 AM
Thank you, works flawlessly
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-12-2025 05:23 PM
4 years after and SN has not made this something configurable on properties. Your insight was really helpful here.