logo

NJP

Widget Fun in ServiceNow | Share the Wealth

Import · Feb 03, 2022 · video

all right let's begin so yeah let's let's just kind of start from the top i've got a little list of things that i'm going to share there's really no particular order so let's just kind of jump into them one at a time so hopefully you've had a chance to attend our previous ones and if you've been attending all four of them now you'll see they've all been kind of building on each other so now we're just going to kind of go backwards and i'm just going to kind of jump into some of these fun features all right so the first one i want to show you is is called sp record picker so anybody remember when we were talking about directives and stuff angular providers anybody want to chime in and tell us what a a directive is no i can do it if you like so a directive is a repeatable component or reusable component within angularjs that we can use across widgets and there are a lot of out-of-the-box directives a lot if you've done any kind of portal dev at all you've probably used directives and didn't even know it maybe all right so i've started a new widget here let's turn the preview on okay so remember probably one of the most simple directives is right here ng if either true or false right you just do a an expression that results in a true or false value and that's that's a directive right now well it's an example of a directive now let's take a look at as promised sp record picker what does that do now that one you call it a little bit differently this is not a native angularjs one of course this is a on the service now built so here let me let me pull up my reference code here from another widget that i had built previously real quick okay so how the how these work is think of it like this this is a little mini widget itself right but it's not really stored as a widget in service now it's stored as what's called an angular provider but as an out of the box native one this one isn't really even in your angular providers list if you go to that module this is just behind the scenes but you know there is some decent documentation out there for it you know new rocket actually has a pretty good article out there that explains a lot of the different options but i'll just i'll show you some of the basic usage of it right now all right so what i like to do is always first of all okay i guess let me tell you what this does first we're getting ahead of ourselves this is going to put a basically a reference field i guess that's the the easiest way to put it this is going to put a reference field on your page and allow a user to pick a record from a table so one of the first things i'm going to do is i'm going to set up a an object for this field so let's let's just we'll use users as an example so i'm going to like define a field called user and it's not going to start off with any values right it's going to start off empty so i'm going to define these and then yeah let's also give it a a name and so there are a few different ways of of doing this right i'm just kind of showing you one all right so now there's a few things that i need to define here in at the directive level in my html one of those things is well first of all i'm going to tie it to this this object like this right now i've bound this this directive to to this object all right okay so let's we we know first of all we need a table now i would recommend it against defining all of this you know like i i'm i i don't like putting in table names and stuff in the in our template so what i would probably do is just add these over here actually and you can even do that client or uh server side it might even make the most sense so let's actually do that here table will be incident or maybe you can get that from your options your widget options or something right you can make that uh dynamic okay we also are going to need a default query we're going to need a display field all right so let's just here let's make our our default query active oh you don't want to do an incident we're doing assist user sorry so our default query is active equals true we want our display fields to be name and email and we want our search fields we'll also do the same okay so now over here we can just use well we can make this just data.usernow we don't even have to do this um right okay so let's oh yeah so in here let's finish filling these out now so that's gonna be dot user oh here let's keep it consistent there's a dot user dot table and default is it dash query right default dash query here let's close some of this stuff down there's query equals data dot user dot default three i think that's how i named it and you know also so you know organization wise when you start to get a lot of attributes on an html tag go ahead and create a new line here and just start you know it you can do that and it's a lot it gets a lot easier to read all right so we're going to display fields value field let's go ahead and add these in here so display fields value field search fields oh yeah we need to i need to add the value field in here real quick and also i have a typo so we'll use this id as the value field okay all right that's good so let's go ahead and finish filling this out whoops search fields okay all right so let's just see what we got so far we'll save that all right and let's always open up your console make sure you're watching any errors that come through i looks like i have an error i did something wrong no that's not related to me all right so let's troubleshoot this why don't we have it anything in here well this could be because i should probably include my angular notation i believe um actually do i need to do that i believe i do actually yeah so let me just put all those in real quick and i could probably confirm that that's the case if i were to look in here and try to find that where is it but you know what let's do this first of all that way we'll be able to see it and then we can kind of see what's going wrong oh did we get it there is it sn record picker not sp you know i could be making a really dumb mistake and even though i was just using it yesterday is it i appreciate it listen that's right it is oh my god thank you yeah i wouldn't get very far there would we all right but this is here maybe all right let's take these back out then i've been going all day good time i think it's a lack of a fancy old fashion probably probably oh look at that look at that there we go i'm my own worst enemy sometimes all right okay awesome thank you for chiming in there your lifesaver okay so yeah so you can see what i've done so far you know you define this object server side or client side it doesn't matter right but i like to try to get everything as clean as i can server side and then i i built my my directive here and now i can pick a user and now what happens like you want to be able to respond to that right so the best way to do that is well there's a couple ways you can do it one is you can see as i i i can either use the angularjs watch method to just watch this client side or i can also just paste this in let me take this out for now there's this out of the box event that fires when you pick a new value here it's the field change event you can watch for that and um here so like my name is user right now i specified there and then so then i'm going to be let's just because i don't want to respond to every single field change right because i may have multiple fields on the page or around the site whatever i only want to respond to the user field so let's say user selected and then we're gonna log this okay so let's watch the console look at that these are selected and it gave me the society of that user i want you to give me the sys id because that's what i i specified as the value field i wanted the sys id field to be the value if i wanted to get the user's email then over here the value field can become email and now watch when i select a user see that boom ain't that handy any questions on that you know i think there's here let me show you i think there's also an attribute for allow multiple if i'm not mistaken equals true let's see what happens now i thought it was just multiple but that you may be right i'm not sure i think it's just multiple it is okay so let's do multiple yeah and we called no did it like that oh yeah it is okay yeah so there's yeah multiple i guess why we call this best kept secrets because good luck on finding all the documentation for this in one place it ain't gonna happen but you can find little bits and pieces of it all over so yeah and so you can see what's happening over here now i'm getting both the values pretty nice huh or you can even go through widgets that already exist that servicenow's created and search for like sn dash and just see what they're pulling in of their own directives in all of their scripts excellent point so if we were to go to our widgets module and let's look for everything i already got it over here yeah so there's 12 out of well 11 because this one's mine 11 auto box widgets that use that directive so let's see let's take a look at one and see how they're using it pretty similar you can also specify a page size so that's your limit right how many records you want to bring back at any given time so yeah they're using it pretty much very very similarly is how we're doing it here how are they watching for it over here i wonder you can see they set that up kind of like we did yeah they're also watching for the field change object so that's the pretty standard way of doing it but like i said you can also do scope.watch and then watch c dot user but i think this is probably the better way of doing it plus let's say there's even an on change event too or something that you could bind to on the actual s record picker i want to say i have to look that up but okay there's another change let's try this ng change equals and then let's write a function real quick scope dot changed equals function i don't know if ngc change works because it's something interior to the directive that they've do what you're doing because i'm going to look it up and if it's wrong we can just change that no yeah it doesn't work here i wanted to say it was on dash change yeah it is it is on change oh okay on that change there it is yep all right cool any any questions about that anybody no all right what's the what was the next one we wanted to look at all right dynamic page titles now maybe you already know about this maybe you don't okay let's just let's open up the portal and we'll show you how this works all right let's go to how about a catalog item i wonder if they'd if it's so c up here in my browser tab apple ipad 3 that's a dynamic page title and these are these are really easy to do let's see if it all is this also doing it on the knowledge article side let's see you know usually it just gives you the static page like knowledgebase service portal yeah so this tells you even like the first it's the knowledge base that it comes from and then the page or the article you're looking at so how does that work let's take a look at that real quick let's go to the sc cat item okay so you've got on the page record a field dynamic page title now this is going to be a user-defined name you you could make this whatever you want but it's going to have to correspond to your your your items down your variables down in your dynamic page title variables list right so we can see the one that they've got set up here see here here's the name that's where it has to correspond so you choose this name in this case they just give it name let's open that up so the query parameter is what is the parameter up in the url of the page that you're going to use to look up a record in the database right so if we're sitting let's go back to a catalog item so if we're sitting on this page it's going to look up in the url and we want to use this this is our value that we're going to want to go look up in the catalog item table to [Music] to get values right so it's the sysid parameter so that's that's what you do there enter that relevant table column this is i'm not totally sure what the cr corey's url parameter value against provided column name in the table i don't really know what the difference is between oh you know okay sorry it's it's i know i'm getting ahead of myself here it's it's what what field on your table does does this parameter correspond to right because this isn't always going to necessarily be the name of a field so by default if you if you don't choose anything here it's none but say say my parameter was actually the the name of the item and i had to look at the name and then i would i would connect this then to the name field on the catalog item and that's how i would look it up so that's what that is but this is going to be none because we're just using society i guess you know you could pick society out of the list but that'd be redundant and then then you're going to choose finally what field holds the value that you want to return for the page title and in this case name so if we wanted to change it to just be like the category let's go ahead and do that and we'll see how that affects this so right now it's apple ipad 3. we expect this to change to tablets or hardware or something yeah tablets so that's how that works pretty easy so if we wanted to create another one in here say or that was the name so let's just change that back to name all right save all right we're going to create another one now for category we're still going to use the society to look it up but now just like we did before we're going to think it's a category let's insert that all right so now back at our page instead of name just name we could do this category dash name and let's check it out now see tablets apple ipad 3. pretty easy huh and so this is this is good too because if you're doing any kind of like google analytics or stuff where you're logging the the names or the page names of of all of the you know everything viewed in your knowledge base or or catalog if you don't do this you're just going to get the same page name and it it's not going to be very helpful to you to you so this this helps give more human readable logs also all right any questions there on dynamic page titles no all right next okay same vein page route maps so whenever i'm building a custom portal or doing anything where i'm going to change anything on a page right even if most of the portal is out of the box and just say say for example on this page i want to add another widget right or i want to do anything i just i want to do something to make this page my own and i don't want that to affect any other portal that might be using this page right because this is a pretty fundamental page in the portal sc cat item there are things that link to this page all over the place and if i'm going to create my own like call it my sc cat item and even if it's going to be exactly the same i got to go hunting down every single place in my portal where it's linking to a cad item and update the url and that's going to be a nightmare to maintain you don't want to do that you always want to be no matter how custom you make your portal you want to you want this to be the url to your catalog items right or whatever the page is so how do you do that you know you can still here so here we are on the catalog item i'm going to clone it this is now my catalog item [Music] my sc cat item let's save it and let's just say the only thing i i i didn't want any of this stuff right i wanted to take all the related stuff off just because it wasn't just showing what i want i'm gonna delete that this is all being deleted from my page right all right so now how do i get users to my page my version of the catalog item page from my portal i'm going to create a new page route map which says so just say new catalog item page or [Music] i choose my portals i want to apply this to and i'm going to route from that out of the box cat item page to my sc cat item page active of course you can maintain multiple page route maps and order them i've never done that i don't know why this really needs an order but maybe there is a use case anyway let's submit it and actually we aren't going to really be able to see that change here let's make another change to our our catalog page let's see where was that my which one is going on there let's here you know let's just add another widget to it you know we just like that breakout game so much we want to make sure our users can play it before they get a chance to submit a catalog item all right so now here i am at the catalog home page i'm going to click on this and if you look if you notice my url down at the bottom is still sc cat item right if i copy my link address and paste it up here look it's still sc cad item i didn't have to change that but now it links to my new page and it doesn't even show my my url up in here right it's totally masked so you can still keep in a very out of the box url structure throughout your whole your whole portal and and never have to go updating uh page urls and stuff like that right use the page route maps to to route to any any page that you re you know any kind of modification you need to make to an out of the box page you can use those and then you never have to update any urls ever any questions about that how that works oh look at this this is broken what's going on up there oh you know what happened when i cloned my page it didn't copy the uh page title variables over so let's let's do that real quick because anybody have any questions while i do that any conditions on those uh redirects to different pages like only do it for certain groups good question let's go take a quick look at that okay let's just insert those real quick there we go okay so yeah let's take a look at that page route map now um where was that so let's see no that's it there's like an idea to serve to service now yeah i think that's kind of where they were going with like with orders because i don't know what the what the purpose of an order is you know if you can't make them conditional it's like i guess oh you know because if it's applying to multiple portals then you could create i guess kind of like a hierarchy of page route yeah but now apparently yeah we don't have any options to make them conditional but that yeah that's an excellent idea i guess you gotta write your own widget for that oh geez sounds like widget fun five yeah oh really i really have to drink for that it could only really be like user based or session based right because you're not on a record right the conditions you might be on a record but you don't know that here you know what i mean right yeah yeah yeah interesting though it'd be fun to build yep all right let's take a look at the next one we got a few more we're gonna look at let's go back to our widget our new widget where was that okay there is an object available to us in our server scripts yeah let's just focus on our server script here we don't need anything else called called sp now you can browse all of the available functions just by typing dollar sign sp and checking them all out i think i mentioned this in one of our our previous year the wealth but i didn't really get it into any of them but these are really worth taking the time and checking out so let's do a quick example of how you can use these let's say i want to oh let's do this let's we'll do our user first there but then we're going to do a list of incidents all right so we're just going to do an incident gr make this super easy add query active is true or i could have done active query and then yeah let's just do that for now we'll we'll set a limit so we don't get a million back let's just say like 20. incident gr dot query okay so now we're gonna loop through each incident and here let's get an items array ready for this actually let's just open up our template real quick and get a place for our incidents and we know we're going to repeat an li for every item in data.items and for now let's just we're going to print out the whole item all right let's get an item object ready for each one we're going to initialize it blank and then we want to let's let's just to make sure we got a good list first we're going to do item dot display value equals incident gr dot get display value and then data.items push item let's see what we got okay we got a list of 20 incidents 20 active incident numbers exactly what we wanted but now we want to to display a lot more about this let's say we want to do this we want to get like three fields back and we want to get all our id sys created on and state all right so now what we can do is check this out we have let's see what we have available here we have a get fields service here or function like a field but returns an array of field objects for each comma separated field name hmm let's check this out let's try it come on so we're going to pass to it first our glide record object and then our fields and [Music] actually actually we want to put this up here all right so we're going to populate the item let's see what we get nice look at that i mean it ain't looking like much yet but now look at what we can do over here what did we ask for we asked for caller id oh here you know let's let's add number in there just for the sake of it so let's do the number first actually we can't just do that we'll do um [Music] actually here yeah let's do that and we'll we'll see what happens here we'll just do the state for now now look what this looks like hold on yeah i didn't think that was gonna work let's do that we want here so we'll we'll see exactly what we need to print out yeah we're looking for the display oh yeah wait so that gives us that gives us an array it sure did didn't it okay so what you can alright so let's do this here actually because it gave us to it gave this to us in a rather funny way right and and i would rather i mean one thing that we can do here is like we could do you know do another repeat inside here like this and she repeat equals field and item see what we get with that yep so see then now it printed out an actual object for each one and what we could do is like field name field.value there we go now that's starting to look like something all right so as you're working with these you're gonna have to really just pay close attention to the format of how these things come back to you they're not always consistent right now so so this is one way of doing it right now maybe i wanted to you know i'll just show you another quick way of doing it using get field so let's say instead of doing that let's say we're going to call our own function get fields and we're going to pass to it our glide record and now down here we have a function fields i guess the glide record so for now so here we're going to say well here let's let's go and just make this data that fields make sure we can get it down here easily or var f in data dot fields whoops i guess first data.field.split right you got to convert that to an array first okay so then for each one field equals fields and a trim that we're just gonna i would just do that just because like here you wanna maybe you wanna keep some spaces in there right that's gonna take out those spaces all right and now in here oops we wanna do this up there never define your variables in the loop to find them outside okay so here we get the fill and now we're going to say i kind of lost my train of thought here get fields oh yeah oh yeah this is where we're going to get field then how did we call this item so we're going to create a field object property in our item object and so the fields you know i just i'm getting too complicated in this i don't want to get too far into the weeds and i just realized that the way i was doing it before is probably just going to be your best way right let me even do that there sorry about that it was everybody's time so i guess what i was trying to get at was if you want if you really want more control you could loop through each of these field names right and call get field and get it back singularly right but what i did is i'm using get fields to to just call them in all at once and so then you can structure your your template however you want to get those out or i guess here this is where i was ultimately wanted trying to get to you could also then re-loop through these nevermind i'm getting too advanced let's go to the next one sorry yeah we want to keep this our favorite out of the box methods and i'm starting to to get to advance more like object formatting and stuff and so forgive me all right we want to spend a few minutes time wait like let's take a look at some other ones in here real quick before we move on anybody have any questions about these i mean that you you've seen before in widgets that you're not really sure what it does one of my favorite other ones is is to be able to embed widgets so you can use get widget from an instance that's like an instance that already exists or you can go even define that instance server side or client side and like create one on the fly those are fun but look you got some pretty use useful ones get user initials you don't have to write your own user functions to to get those you can just call that with user initials so a lot of really great stuff get related list you can call that on a form object a glide sorry a glide record and specify a view and it returns all the related lists for that view so there's really awesome stuff in here definitely worth looking at it all right let's let's get out of the widgets for a second now let's get out and take a look at just basic page structure how does a portal page put together it's pretty simple but it can be a little you know there's a lot that goes into it once you you know start really cracking it open so let's open this up in page designer we'll cover a couple real basics first just in case some of you are really new to portal your header and footer are not going to be visible in here right your header and footer are maintained as far as part of the theme of your portal and so those are maintained separately this is the page view it's strictly just the page that's you know the view between the the header and the footer and it's a basic bootstrap model built on the the container rows and columns concept all right so if you look over here in this top section of the layouts this is basic kind of basic bootstrap layout stuff you've got a container which can contain rows those are your horizontal objects and then your rows can contain columns those are your vertical objects so the vertical objects are what's going to create your your column spacing on the page these columns so now at each one of these levels you can maintain a lot of different properties so let's just hop into let's go to the top one here this top level container click the pencil so we can see we have the ability to upload a background image that's going to display for that container so now whatever we whatever widgets we throw into this container are all going to be you know have this background image so that's you can you can also choose a color if you don't want it to be an image you can choose color you you know there's some different options for it here you can even move move this container to the header which means that the page is going to consider it part of the header and if you use a sticky header then it'll move with the the page and so a lot of cool options here then you can also apply classes at these levels right so there's a lot of bootstrap classes that you can apply you know to create spacing or to make elements like for example this one we're saying hidden excess it means on extra small screens this container isn't going to show at all which that's usually one of the first things i change in portals because even on a mobile i still want them to have search on the home page you know so i i just maybe make it give a different kind of search but yeah i don't want it to disappear but you can see if you did want a whole container to appear or disappear in certain screen sizes you could do that yeah so a lot of different spacing and and layout options here once you get into the the row you have some similar options but less right i i can give it a css class that i can target with some css but that's about all at the row level the column level is really where we get into responsiveness and stuff so you can see here in this row we have three columns three different columns and actually if i open up that row object actually not here let's do it in the i can do it from the page view if we look at that home page so there are multiple ways of looking at objects on a page or like how a page is constructed right here's another way of looking what we were at what we were just looking at you see here's that first container with just the home page search in it um then there's another container oh you know here's another container that you can i forgot they have it's just the banner that disappears on the smaller ones they they're including just the type of head search on the smaller screens i still like the banner even on smaller screens though anyway so you can see in the third container we have three columns one for each link that's so this is a great way of creating static page structure right but if i was in the portal and say one of these links was conditional or maybe i had a fourth one or you wanted to be able to just you know freely add you know more links here without having to go and update the page structure i would use a widget that actually you know just lines my items up itself i would use three different widgets here but remember this page that we're looking at this is just a sample demo site this is not considered the out of the box portal and this is not what servicenow suggests you implement so you know or they have three widgets here for for three links it's a terrible setup don't don't implement that but the basic page structure is is great they're like you can see below that they're also using three columns and in that sense it makes more sense because you actually have different lists that you want to lay out on the page right like these lists down here and so those are super easy to do you know you you just select that column make sure you have the column selected and then you can go in and you can choose at the different sizes of screens how many columns you want that column to take up and it's always going to go it's going to cascade uh from smallest to largest so and really it's best to just get in and kind of play with these to see how it works me trying to explain it at all here is is going to be lost i'm going to become all tongue-tied it's just best to go in and and experiment with those but so as you're going through this you might encounter that there's also a lot of different places to write css right you can write css at the page level so i can go now into the page settings and provide some page specific css that gets only applied on this page just like out of the box they have some here so here's one so this is one place you can write css another place is of course in the widgets themselves they all have css files i can write css in a style sheet and attach it to my theme right and depending on what you need for like what you're trying to target and and how globally you want that css to take effect that's all gonna depend on where you write it you know where you store it and you'll just have to you know think of that on a case-by-case basis let's see what else about the layouts here anybody have any anything interesting you want to point out about layouts that you can think of or any questions about what you can do with these hey jeff this is albert i just posted a question i think you were editing one of those containers um i'm just curious what the bootstrap alternative checkbox was doing oh bootstrap alternative let me jog my memory on that uh i think it was on the container i believe or the yeah okay boost trap alternative what is that doing that's new that's new is there not a hover or maybe on the container in the in the actual platform you can hover and see what it is because i've never seen that one bootstrap alt yeah google let's google together everyone yeah what's up says oh come on we'll disable the boost trap css grid system in the container okay all right use what instead though i guess nothing well let's experiment here let's let's do that on this one right here bootstrap alternative there you go so okay so i guess all your container row all your call classes i guess just get ignored i guess you would just write your own in that one little container i suppose so cool sorry i was talking to mute i i've got the doc site open it says if if that's selected the the width the standard bootstrap class and the now record with the container and the size columns are all ignored only select this field if you plan to provide custom css classes and css for the container row and column records well there you go all right i bet this is an answer to using flexbox because everyone wants to use flexbox instead of grid i bet yeah there is there are times where i have yeah been not that one i want this one it's kind of stymied by out of the box bootstrap classes that are there that like really bugged me from being able to do what i wanted to do and so yeah that's a great uh use case for that all right well hey we're at the top i got a meeting right after this yeah hopefully we kind of exposed you to some more out-of-the-box features of service now you know i'm gonna show you the light that there is a lot there under the hood that you can make use of sorry i took you on a wild goose chase with object formatting i should have tried having a drink before that but if you got any questions always feel free to reach out come out to the ceo the uix coe slack channel ask us questions there if you want every other friday yeah thanks everybody thank you yeah bye thank you thank you [Music] you

View original source

https://www.youtube.com/watch?v=MRWrhW3qCs8