logo

NJP

Handshake between Client Controller and Client script

Import · Mar 27, 2018 · article

Hello Everyone.

Lately, I came across various use cases, where I felt the need of having g_form apis to work on service portal widgets.

So, what if we can control a piece of code on client controller which can be executed on change/ onload event of client script.

I wanted to have something like what we call broadcast in angularJS but in native JS. I found something interesting BroadcastChannel

However, it doesn't work on IE image . Luckily, I found an IE complaint solution UI script

Use case1 : Hide section on service portal

Create separate client script with replica logic of the client script which is working fine for native view.

UI Type : Service Portal/Mobile

function onChange(control, oldValue,
  newValue, isLoading, isTemplate)
{
  var section = 'Section Name';
  var recordID = g_form.getUniqueValue(); // an extra layer to ensure we are doing on correct data 
  var flag = (g_form.getValue(
      'u_section_control') == 'false') ?
    'block' : 'none'; // logic can be written here
  broadCastChangeSection(section, flag,
    recordID);
}
/*static function in client script */
function broadCastChangeSection(section,
  flag, recordID)
{
  var intiateEvent = new BroadcastChannel(
    'hideSection');
  var data = {
    'section': section,
    'flag': flag,
    'recordID': recordID
  };
  intiateEvent.postMessage(data);
}

Widget manipulation (form widget)

HTML (add src="name of your UI script.jsbx", community trims the src attribute -_-)

Client Controller

var intiateEventSection = new BroadcastChannel('hideSection');
intiateEventSection.onmessage = function(ev)
{
  var dataParser = angular.fromJson(ev.data); // parsing JSON
  if ($location.search().sys_id == dataParser.recordID.toString())
  { // evaluate the correct record
    for (var i = 0; i < document.querySelectorAll("legend").length; i++)
    {
      if (document.querySelectorAll("legend")[i].innerHTML == dataParser.section.toString())
      { // evaluate the section name sent in client script
        document.querySelectorAll("legend")[i].parentNode.style.display = dataParser.flag.toString(); // hide the element based on flag passed in client script
        break;
      }
    }
  }
}

Use case2: Make attachments mandatory on portal (sc_cat item widget)

Widget Manipulation

HTML (add src="name of your UI script.jsbx", community trims the src attribute -_-)

Client Controller

$scope.triggerOnSubmit = function(){

                                $scope.data.sc_cat_item.item_action = "order";

                                if (g_form)

                                                g_form.submit();

                }


Replaced by

       $scope.triggerOnSubmit = function(){

                        $scope.data.sc_cat_item.item_action = "order";

                        if (g_form && checkAttachment()) // checkAttachment() added to check if attachment check is needed

                                    g_form.submit();

                        else if(!checkAttachment() && alertType == 'confirm')

                                    confirm(alertMessage);

                        else if(!checkAttachment() && alertType == 'infoMessage')

                        spUtil.addErrorMessage(alertMessage);  // Attachment not found

            }

Additional code

/* Attachment Mandatory  Code Start*/

            var checkNeeded = false;

            var alertMessage = '';

            var alertType = '';

  var checkAttachmentEvent = new BroadcastChannel('CheckAttchment');

            checkAttachmentEvent.onmessage = function(ev) {

                        var dataParser = angular.fromJson(ev.data);

                        alertMessage = dataParser.Message;

                        alertType = dataParser.type;

                        checkNeeded = true;

            }


            function checkAttachment(){

                        console.log('Attachment Count'+$scope.attachments.length);

            return (checkNeeded && $scope.attachments.length == 0)? false: true;   

            }

Client script

UI Type : Service Portal/Mobile

function onLoad() {

// you can write your logic here

            setTimeout(function(){

                        var checkAttachment = new BroadcastChannel('CheckAttchment');

                        var data = {'type': 'confirm', 'Message':'Do you want to submit without attaching?'};               

            checkAttachment.postMessage(data);

            }, 30);

}

This of course opened a Pandora box of possibilities image

View original source

https://www.servicenow.com/community/now-platform-articles/handshake-between-client-controller-and-client-script/ta-p/2327916