
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-04-2021 07:42 AM
Hi Everyone,
I've been working with creating my own custom components for Agent Workspace using the UI Framework.
I've gotten my application to do almost everything I want, I have a <now-card> with a <now-button> inside, like this:
<div><now-card id="myCard" style={{width:"250px"}}><now-card-header tagline={{"label":"Incident","icon":"tree-view-short-outline"}} heading={{label: number}} /><br/>{short_description}<br/><br/><now-button on-click={buttonClicked}>Assign to Me</now-button></now-card>
Solved! Go to Solution.
- Labels:
-
Now Experience UI Framework

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-04-2021 08:04 AM
You need to read up on the shadowdom. It basically keeps everything separate so that jquery and the like will never be able to return anything. You can access it like this though, snagged it from something I did in Home Assistant.
const home_assistant_main = document
.querySelector("body > home-assistant").shadowRoot
.querySelector("home-assistant-main");
var header = home_assistant_main.shadowRoot
.querySelector("app-drawer-layout > partial-panel-resolver > ha-panel-lovelace").shadowRoot
.querySelector("hui-root").shadowRoot
.querySelector("#layout > app-header > app-toolbar")
.style.display = "none";
Ultimately what you need to do is when the button click event is triggered have the container that the card is in set a style for the DIV its in to hide it or set a var and use an IF statement to have it excluded from the HTML. Something like the below
//If attachments length is greater than 0 then render one thing and if it is 0 render something else.
attachments.length > 0 ? attachments.map(attachment => (
<li className="sn-card">
<div className="sn-attachments"
data={attachment.sys_id}
on-click={attachmentsClicked}
>
<div className="sn-attachments-content -static has-media">
<now-icon icon="document-fill" size="xl"></now-icon>
</div>
<div className="sn-attachments-content">
<span className="sn-attachments-content-title">
<span>{attachment.file_name}</span>
</span>
<span>{(attachment.size_bytes / 1024 / 1024).toFixed(2)} MB</span>
</div>
</div>
</li>
)) :
<li className="sn-card">
<div className="sn-attachments">
<div className="sn-attachments-content">
<span className="sn-attachments-content-title">
<span>No PDF's found.</span>
</span>
</div>
</div>
</li>

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-04-2021 08:04 AM
You need to read up on the shadowdom. It basically keeps everything separate so that jquery and the like will never be able to return anything. You can access it like this though, snagged it from something I did in Home Assistant.
const home_assistant_main = document
.querySelector("body > home-assistant").shadowRoot
.querySelector("home-assistant-main");
var header = home_assistant_main.shadowRoot
.querySelector("app-drawer-layout > partial-panel-resolver > ha-panel-lovelace").shadowRoot
.querySelector("hui-root").shadowRoot
.querySelector("#layout > app-header > app-toolbar")
.style.display = "none";
Ultimately what you need to do is when the button click event is triggered have the container that the card is in set a style for the DIV its in to hide it or set a var and use an IF statement to have it excluded from the HTML. Something like the below
//If attachments length is greater than 0 then render one thing and if it is 0 render something else.
attachments.length > 0 ? attachments.map(attachment => (
<li className="sn-card">
<div className="sn-attachments"
data={attachment.sys_id}
on-click={attachmentsClicked}
>
<div className="sn-attachments-content -static has-media">
<now-icon icon="document-fill" size="xl"></now-icon>
</div>
<div className="sn-attachments-content">
<span className="sn-attachments-content-title">
<span>{attachment.file_name}</span>
</span>
<span>{(attachment.size_bytes / 1024 / 1024).toFixed(2)} MB</span>
</div>
</div>
</li>
)) :
<li className="sn-card">
<div className="sn-attachments">
<div className="sn-attachments-content">
<span className="sn-attachments-content-title">
<span>No PDF's found.</span>
</span>
</div>
</div>
</li>

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-04-2021 08:29 AM
Hi Drew,
a few questions.
For the first solution, will this allow me to select these elements with jQuery? If so, that is the way I want to go for this as I want to hide the element slowly, like a fade out effect.
I'm having issues getting it to work. It would appear to me the first statement:
document
.querySelector("body > home-assistant").shadowRoot
it seems as though home-assistant should be replaced with my app name, which I have done. However when I do this I get.
TypeError: Cannot read property 'shadowRoot' of null
this happens when I try to console.log it.
I also get that if I attempt to return the shadowRoot of just "body".
Is there something I should be importing to make this work?
I have tried doing this both inside and outside the view declaration.
Is there any way to dig into the structure using the inspector?
Also, I am confident the second option would work for simply hiding it, but I'd like to apply jQuery's fade effect.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-04-2021 09:59 AM
Actually home-assistant is a tag so you would replace it with the tag name. The issue with doing this is you have to crawl down the tree of tags to get to the one you want. Which can get messy and will break if ServiceNow changes the structure of the page.
If you want it to fade then you may want to consider assigning a class to the DIV that will do this.
So something like
//In the event script set the fadeClass var to the class name that will kickoff the fading
//HTML
<div class="{fadeClass}">
<now-card id="myCard" style={{width:"250px"}}><now-card-header tagline={{"label":"Incident","icon":"tree-view-short-outline"}} heading={{label: number}} />
<br/>
{short_description}
<br/>
<br/>
<now-button on-click={buttonClicked}>Assign to Me</now-button>
</now-card>
</div>
There maybe a better way to trigger it using the parms passed into the button event but I would have to mess with it again.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-04-2021 10:44 AM
Thanks Drew,
I think for now I'm going to go with your original second solution and leave the fading for later.
It sounds like jQuery isn't the way to go for this type of thing anymore. I need to study up on this more before I try the more advanced stuff.