Incident client script access DOM for getElementById
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Needed a client script to a "g_form.showFieldMsg()" on the subcategory field. Easy enough, right? Only issue is the message I needed displayed had line breaks, and well... you can't add line breaks in a showFieldMsg. I tried the \r\n and <br/> methods, but all failed. I realized I needed to wrap that message in a <pre> tag for the line breaks "\r\n" to work.
The other issue was that if I did this, I also had to set the parent div of the showFieldMsg to "fit-content".
Here's the rub... the showFieldMsg div's id is "incident.subcategory_fieldmsg", but har har if you think you can use top.document.getElementById(). Oh no no no, it's all buried in the infamous gsft_main iFrame, but then to make matters worse, THAT's all buried in a shadowRoot element. What a joke.
I digress... here is what I needed to have happen:
And here's the client script code I used to make it happen:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading) {
return;
}
function consoleWarn(msg) {
/* eslint-disable-next-line no-console */
console.warn(msg);
}
function consoleDir(msg) {
/* eslint-disable-next-line no-console */
console.dir(msg);
}
g_form.hideFieldMsg("subcategory");
var msg = false;
var lineBreak = "\r\n";
var category = g_form.getValue("category");
if (category == "NEW Truck Service System (Dynamics 365)") {
switch (newValue) {
case "":
break;
case "Access & Configuration":
msg = '- Access denied errors and principal user errors' + lineBreak;
msg += '- TSA role misconfigured (e.g., able to edit Work Orders or create accounts)' + lineBreak;
msg += '- Site Manager (lacks access to functional location tab)' + lineBreak;
msg += '- Site Manager (Incorrect account/contact creation)' + lineBreak;
msg += '-Shop employee plays a temporary TSA role and will need TSA permissions';
break;
case "Resource Management - Site Manager":
msg = '- Site Manager Unable to edit newly created skills and characteristics' + lineBreak;
msg += '- Site Manager Error adding skill to technician' + lineBreak;
msg += '- Site Manager unable to create new resource from skills page' + lineBreak;
break;
case "Resource Management/Booking - TSA":
msg = '- TSA Resource category table not visible' + lineBreak;
msg += '- TSA Not able to see Technical Resources in the Schedule Dashboard' + lineBreak;
msg += '- Time zone discrepancies during booking' + lineBreak;
msg += '- Incorrect estimated time updates';
break;
case "Reporting":
msg = '- Work Order Summary or Resource Utilization report not available' + lineBreak;
msg += '- Dashboards not rendering properly' + lineBreak;
msg += '- KPI dashboards missing or incomplete';
break;
case "Feedback Survey Issues":
msg = '- Survey invitations not sent after work order completion';
break;
case "Customer Notifications":
msg = '- SMS notifications not triggered properly';
break;
case "Shopcore to D365 Misalignment":
msg = '- Work orders not flowing from ShopCore' + lineBreak;
msg += '- Status changes not reflected in D365' + lineBreak;
msg += '- Time zone discrepancies during booking' + lineBreak;
msg += '- Incorrect estimated time updates';
break;
case "Operations & Scheduling":
msg = '- Site Manager unable to create or delete bookings from Schedule Board' + lineBreak;
msg += '- Empty entries in Bookable Resources view' + lineBreak;
msg += '- Booking suggestions not available for G13/multi-resource work orders' + lineBreak;
msg += '- Wait time estimates not visible';
break;
case "XXX": /* template */
msg = 'XXX' + lineBreak;
msg += 'XXX' + lineBreak;
break;
}
}
if (msg) {
g_form.showFieldMsg("subcategory", msg);
try {
setTimeout(function() {
var mc = top.document.getElementsByTagName("MACROPONENT-F51912F4C700201072B211D4D8C26010")[0];
if (mc) {
var shadowRoot_ = mc.shadowRoot;
if (shadowRoot_) {
var iFrame = shadowRoot_.querySelector("#gsft_main");
if (iFrame) {
var iframeDoc = iFrame.contentWindow.document;
var iframeWin = iFrame.contentWindow;
if (iframeDoc) {
var div = iframeDoc.getElementById("incident.subcategory_fieldmsg");
if (div) {
div.style.setProperty("width", "fit-content");
var pre = iframeDoc.createElement("pre");
pre.appendChild(div.children[0]);
div.appendChild(pre);
} else {
consoleWarn("NO DIV FOUND");
}
} else {
consoleWarn("no iframeDoc");
}
} else {
consoleWarn("no iFrame");
}
} else {
consoleWarn("no shadowRoot_");
}
} else {
consoleWarn("no mc");
}
}, 300);
} catch (e) {
consoleWarn("try/catch err: " + e.message);
}
}
}
Pay very close attention to the code here:
var mc = top.document.getElementsByTagName("MACROPONENT-F51912F4C700201072B211D4D8C26010")[0];
if (mc) {
var shadowRoot_ = mc.shadowRoot;
if (shadowRoot_) {
var iFrame = shadowRoot_.querySelector("#gsft_main");
if (iFrame) {
var iframeDoc = iFrame.contentWindow.document;
that's the magic-sauce to access elements buried in a shadowRoot that's buried in the gsft_main iFrame.
Lovely we are forced to do such things, isn't it?
