Free Service Portal Widget: Related Lists

nathanfirth
Tera Guru

To help contribute back to the community, we're going to try to develop and give away one new widget per month.

For January we have developed the "Related List" widget, which allows you to display related lists on the form page in Service Portal.

Example below from a service catalog request:

Screen Shot 2017-01-12 at 10.20.55 AM.png

To download the widget, it's available on ServicePortal.io: Free Widget of the Month - ServicePortal.io - Service Portal, CMS, and Custom Apps

65 REPLIES 65

Hello Nathan,



thanks for your reply. I tried to use a custom api parameter for view:



var params = {
table: list.table,
filter: list.field+"="+data.sys_id,
view: 'sp', -> view: 'itil',
title: list.label
};



but this seems not to work ... it always takes 'sp' view. Also the caption of related list is slightly diffrent to default portal (maybe caused by some UI_Messages)



Grüße


Vesp


vespertinus



you should pass the view name like below


data.view = $sp.getParameter("view");


var f = $sp.getForm(data.table, data.sys_id, data.query, data.view);


data.related_lists = f._related_lists;


arthurcheung
Kilo Expert

Thank you! This widget has been very useful for us. Although the filters don't work properly when the related list is from a defined relationship. In these cases, the filter passed into the data table widget is "undefined=<sys_id>", which ends up bringing everything back from the table.



I ended up modifying the widget to do the following check in the server script before passing the data onto the widgets.



  1. From getForms from SP, when type is REL, then we look up the defined relationship.
  2. We extract the query.
  3. We then create a GlideScopeEvaluator to use on the query. (http://wiki.servicenow.com/index.php?title=Scoped_GlideScopedEvaluator_API_Reference#evaluateScript....)
  4. Grab encoded query from evaluated query.
  5. Use encoded query for the filter parameter when creating the data tables.

Hi Arthur



Can you explain it alittle more detailed ?


Maybe with an example ?



Regards


Simon


Sure. I'll go through each of my steps in more detail. Everything I talk about here is in the server script of the widget. Note that you will require underscore (this article explains how to get it, if you don't have it already). Hope this explains it. I can't give you an export of the widget as there are some client specific modifications in it, but if you're having trouble, let me know. I'll see if I can explain further, or give you a cut down version.


  1. From getForms from SP, when type is REL, then we look up the defined relationship.
    The widget pulls the related lists using the $sp.getForm function. This is existing code:
    var f = $sp.getForm(data.table, data.sys_id, data.query);
    data.f = f;
    data.related_lists = f._related_lists;  
    From here, if you inspect data.related_lists you'll discover on the "type" property some will be "REL", which will indicate it's a defined relationship.

    To do this, I added the following snippet of code directly under the snippet I showed above (note that I use underscore - you'll need to have that added in a script include)
    if (_(data.related_lists).where({"type": "REL"}).length > 0) {
          data.related_lists = _(data.related_lists).map(function (item) {

                  if (item.type === 'REL') {
                          item.definedRelationshipFilter = extractDefinedRelationshipsQuery(item.apply_to, item.apply_to_sys_id, item.table, item.relationship_id)
                  }

                  return item;
          });
    }  
    This snippet basically loops through the related lists, and if the type is "REL" it will extract the query into a new property named "definedRelationshipFIlter", which we'll use later on. Steps 2, 3 and 4 describe what we do within the function call extractDefinedRelationshipQuery

  2. We extract the query.
  3. We then create a GlideScopeEvaluator to use on the query. (http://wiki.servicenow.com/index.php?title=Scoped_GlideScopedEvaluator_API_Reference#evaluateScript....)
  4. Grab encoded query from evaluated query.

    extractDefinedRelationshipQuery is a function I defined to do as the name suggests - you can just dump it at the very bottom of the server script. The code is below:

    function extractDefinedRelationshipsQuery(applyTo, applyToSysId, table, relationshipId){
          var parent = new GlideRecord(applyTo);
          parent.get(applyToSysId);
          var current = new GlideRecord(table);

          //Evaluate the script from the field
          var evaluator = new GlideScopedEvaluator();

          relationshipId = relationshipId.replace(/REL:/, '');
          var relationship = new GlideRecord('sys_relationship');
          if(relationship.get(relationshipId)){
                  // setup variables to be used by the script
                  var vars = {"current": current, "parent": parent};
                  var queryObject = evaluator.evaluateScript(relationship, 'query_with', vars);
                  extractedQuery = current.getEncodedQuery();
          }

          return extractedQuery;
    }  


  5. Use encoded query for the filter parameter when creating the data tables.
    This last part is to actually use the filter query we have now defined for "REL" related lists. To do this, look for the following param definition:

    var params = {
          table: list.table,
          filter: (list.field+"="+data.sys_id),
          view: 'sp',
          title: list.label,
          show_new: true
    };  
    and add our query filter to the filter as below. This basically uses "definedRelationshipFilter" if it exists.
    var params = {
          table: list.table,
          filter: list.definedRelationshipFilter || (list.field+"="+data.sys_id),
          view: 'sp',
          title: list.label,
          show_new: true
    };