Can a Service Portal Widget "Retrieve" data from another widget

Steven Young
Tera Guru

Hey Wonderful Community.

I have a rather complex situation i'm hoping can be solved fairly simply.

Within the Service Portal, i'm creating a new page.  I have 5 widgets on the page.

Widget 

A. a "location" (reference) widget,  a reference to the location table.  using the <sn-record-picker>
B. a "status" (reference widget. a reference to the sys_choice table.  using the <sn-record-picker>
C. A checkbox widget
D. an free text input box
E. a "reference field"

Now,  hear me out.  What i would like to do, using widgets A, B, C, D.   I would like to:
Set a value in widget A. (do not want to broadcast anything)
Set a value in widget B. (do not want to broadcast anything)
Widget C is optional
When i set a value in Widget D,  I want to get the value from Widget A,  Get the value from Widget B,  Get the value from Widget C,   Do some server side scripting, then broadcast the results to Widget E.


Is there a way to have 1 widget gather data from the other widgets?
Or if i want to do this, will i need to combine all 4 of these widgets into a single widget?  That way when i do the ng-onclick i can just gather all the values from the same widget?

1 ACCEPTED SOLUTION

Not sure why you cannot give us a general jist of what you are doing but here is a place to start. Use the below in the appropriate widget client controller

//There are two ways to go about this, I'm showing both just as an example.

$scope.$on("field.change.location", function(evt, parms) {
	$rootScope.$broadcast("new.selected.value.location", parms.newValue)
});

$scope.$on("field.change", function(evt, parms) {
	if (parms.field.name == 'status'){
		$rootScope.$broadcast("new.selected.value.status", parms.newValue)
	}
});

 

For widget D do something like

$scope.$on("new.selected.value.location", function(event, data){

	c.data.location = data;

);

 

then when they hit the button check to see if you have all of the values that you need and if so update the record.

View solution in original post

8 REPLIES 8

Hey Drew, thanks for the reply.

 

to be honest, i'm still new when it comes to Angular and Service Portal.  i just started learning how angular works.

Would love some help if you are good at it.

I have edited the widgets to to be generic.  i cant put what this is for on the net. 
But if this will work for updating a record on a table, i'll adapt it for what i really need it for.


Widget A:  Here is the HTML.  I dont have client or server script yet.
HTML: 
For the location reference, i just need the sys_id from this.
I need the whole value from the location notes

<!--##################################################################################-->
<!--#################################LOCATION PANEL###################################-->
<!--##################################################################################-->
<div class="panel panel-default">
  <div class="panel-heading" style="background-color:lightblue">
    <h4 class="panel-title">Location</h4>
  </div>
  <div class="panel-body">
    <sn-record-picker 
                      field="location" 
                      table="'cmn_location'" 
                      display-field="'name'" 
                      value-field="'sys_id'" 
                      search-fields="'name'" 
                      page-size="100">
    </sn-record-picker>


    <form class="m-t form-horizontal" role="form">
      <div class="form-group">
        <label class="col-sm-2 control-label">Location Notes</label>
        <div class="col-sm-10">
          <textarea type="text" rows="3" placeholder="{{data.loc.street}}" class="form-control" ng-model="locNotes"></textarea>
        </div>
      </div>
    </form>
  </div>
</div>
<!--##################################################################################-->
<!--##################################################################################-->

 

Widget B. i dont have client or server yet  This will be modified to point to a different query for the sys_choice table. and the panel title will be updated.
HTML:  

I need to get the "Value"  number value from this field.

<!--##################################################################################-->
<!--###############################STATUS PANEL#######################################-->
<!--##################################################################################-->
<div class="panel panel-default">
  <div class="panel-heading" style="background-color:lightblue">
    <h4 class="panel-title">Status</h4>
  </div>
  <div class="panel-body">
    <sn-record-picker 
                      field="status" 
                      table="'sys_choice'" 
                      display-field="'label'" 
                      default-query="'element=install_status^name=cmdb_ci^inactive=false'" 
                      value-field="'sys_id'" 
                      search-fields="'label'" 
                      page-size="100"></sn-record-picker>

  </div>
</div>
<!--##################################################################################-->
<!--##################################################################################-->

 

Widget C.  This one i need to get even if it's false.  I've thought about making this a yes/no field.
HTML:  i dont have client or server yet.

I need to get the true/false value, or if needed can be converted to a Yes/No mandatory field and script can be adapted.

<!--##################################################################################-->
<!--####################################SHARED########################################-->
<!--##################################################################################-->
<div class="panel panel-default">
  <div class="panel-heading" style="background-color:lightblue">
    <h4 class="panel-title">Share</h4>
  </div>
  <div class="panel-body">
    <input type="checkbox" ng-model="c.data.shared"> Share
  </div>
</div>
<!--##################################################################################-->
<!--##################################################################################-->

 

Widget 😧  When this button is clicked it will take the string that is entered and query a table for the value.  lets just say it'll search for sys_id.

For this, this value could be read by a barcode reader, manually inserted, or copy/pasted.  This will all be free text entries.  When we click the button it will search for a record on lets say the "sys_user" table.
IF it finds it (which it should find this value)  i need to take the 4 values from the 3 other widgets and update the record.  and stay on the page, and if possible put the cursor back in widget d to be ready for the next value.

IF it does not find a value, i need Widget E to then become visible.  Widget E, i cannot share.  

<!--##################################################################################-->
<!--#############################THING TO LOOK FOR####################################-->
<!--##################################################################################-->
<div class="panel panel-default">
  <div class="panel-heading">
    <h4 class="panel-title">Thing to Look For</h4>
  </div>
  <div class="panel-body">
    <div class="form-group">
      <label class="col-sm-2 control-label">LOOK FOR</label>
      <div class="col-sm-10">
        <input ng-model="c.data.thing" placeholder="STRING TO LOOK FOR" class="form-control">
      </div>
    </div>
    <br/>
    <br/>
    <div align="right"><button type="button" ng-click="c.findThing()" class="findThing btn btn-primary">Go Find It</button></div>
  </div>
</div>
<!--##################################################################################-->
<!--##################################################################################-->

 

BOGUS Widget E:

<!--##################################################################################-->
<!--#################################BOGUS PANEL######################################-->
<!--##################################################################################-->
<div class="panel panel-default">
  <div class="panel-heading"  style="background-color:green">
    <h4 class="panel-title">BOGUS</h4>
  </div>
  <div class="panel-body">
    BOGUS BOGUS BOGUS BOGUS
    <sn-record-picker 
                      field="user_name" 
                      table="'sys_user'" 
                      display-field="'name'" 
                      value-field="'sys_id'" 
                      search-fields="'name'" 
                      page-size="100"></sn-record-picker>
    <form class="m-t form-horizontal" role="form">
      <div class="form-group">
        <label class="col-sm-2 control-label">BOGUS</label>
        <div class="col-sm-4">
          <input type="text" placeholder="{{BOGUS}}" class="form-control" ng-model="BOGUS">
        </div>
        <label class="col-sm-2 control-label">BOGUS</label>
        <div class="col-sm-4">
          <input type="text" placeholder="{{BOGUS}}" class="form-control" ng-model="BOGUS">
        </div>
      </div>
      <div class="form-group">
        <label class="col-sm-2 control-label">BOGUS</label>
        <div class="col-sm-4">
          <input type="text" placeholder="{{BOGUS}}" class="form-control" ng-model="BOGUS">
        </div>
        <label class="col-sm-2 control-label">BOGUS</label>
        <div class="col-sm-4">
          <input type="checkbox" placeholder="{{BOGUS}}" ng-model="BOGUS"> BOGUS
        </div>
      </div>
      <div class="form-group">
        <label class="col-sm-2 control-label">BOGUS</label>
        <div class="col-sm-10">
          <input type="text" placeholder="{{BOGUS}}" class="form-control" ng-model="BOGUS">
        </div>
      </div>
      <div class="form-group">
        <label class="col-sm-2 control-label">BOGUS BOGUS</label>
        <div class="col-sm-10">
          <textarea rows="3" type="text" placeholder="{{BOGUS}}" class="form-control" ng-model="BOGUS"></textarea>
        </div>
      </div>
      <div class="form-group">
        <label class="col-sm-2 control-label">BOGUS</label>
        <div class="col-sm-10">
          <input type="text" placeholder="{{BOGUS}}" class="form-control" readonly>
        </div>
      </div>
    </form>
  </div>
  <button type="button" class="btn btn-outline-secondary btn-lg" ng-click="c.addItem()" value="Add">Create BOGUS Record</button>
</div>
<!--##################################################################################-->
<!--##################################################################################-->

 

and i may need to add more fields later when they see how this works.

 

Not sure why you cannot give us a general jist of what you are doing but here is a place to start. Use the below in the appropriate widget client controller

//There are two ways to go about this, I'm showing both just as an example.

$scope.$on("field.change.location", function(evt, parms) {
	$rootScope.$broadcast("new.selected.value.location", parms.newValue)
});

$scope.$on("field.change", function(evt, parms) {
	if (parms.field.name == 'status'){
		$rootScope.$broadcast("new.selected.value.status", parms.newValue)
	}
});

 

For widget D do something like

$scope.$on("new.selected.value.location", function(event, data){

	c.data.location = data;

);

 

then when they hit the button check to see if you have all of the values that you need and if so update the record.

Hey Drew,

 

Thanks for the insight.  Unfortunately, if you've ever worked in Government or Healthcare, sometimes you just cannot say what you're doing.  In my time working on ServiceNow, i've worked in both Government and in Healthcare.  

So, with that said, i've gotten my form working.  without completely understanding the entirety of the broadcast, i didn't want to use it.  

now i understand it a little bit more.

i took my first 3 widgets and did a broadcast to widget D.  on widget d, i set a value based on the broadcast. 

Now, when i do the action in Widget D, i do get the action i'm looking for.

 

I had an issue with the recordWatch not updating for some reason.  so within widget d, i added:
$rootScope.$broadcast('update');

and in my record Watch widget:
$rootScope.$on('update', function(event, args) {
c.server.update($scope);
});

and that resolved my issue with the recordwatch widget not updating.  now it updates each time.

i greatly appreciate the help, and sorry for the cloak and daggers game of not being able to exactly say what i'm doing.

ChrisBurks
Giga Sage

I think another possibility is to create a Service and add as a provider in each widget in the Angular Provider related list and pass into the client controller.