34 Replies · Latest reply on Oct 6, 2017 5:04 AM by kiran pedduri

    How to get a watch list in widget in Service Portal ?

      Hi Team,

       

      How to get watch list for a particular ticket opened in service portal.

      How to create a widget for this?

      Any suggestions or ideas will help me a lot.

       

       

      Thanks.

      NOW PlatformDeveloper Community

        • Re: How to get a watch list in widget in Service Portal ?
          Laurent Chicoine

          Hi,

           

          You can simply use a List collector variable referencing the user table. In the Service Portal that field will allow to enter an existing user or an email address. You probably should add a help text to indicate to your users that they can input an email address as it is not obvious otherwise.

            • Re: How to get a watch list in widget in Service Portal ?
              Nithin g

              Hi Laurent,

               

              Thanks for your suggestion.

              I want to get the watch list for a particular ticket who are already added to the that record .

              I want to see this watch list in service portal with the help of a widget.

              any idea or suggestion ?

              Thanks

                • Re: How to get a watch list in widget in Service Portal ?
                  Laurent Chicoine

                  Hi Nithin,

                   

                  Here is a quick widget I made, however it does not have any save functionality so you would have to add that. Also the sn-record-picker does not allow to add an email address as the usual watch list field does. If your goal is only to display a read of what was set on creation than this would do the job by simply setting sn-disabled="true".

                   

                  HTML:

                  <div ng-if="data.canRead" class="panel panel-primary b">
                    <div class="panel-heading">
                      <h4 class="panel-title pull-left">
                        ${Watch list}
                      </h4>
                      <div class="clearfix"></div>
                    </div>
                    <div class="panel-body">
                        <div class="text-center text-italic text-muted">
                          <sn-record-picker field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'name'" search-fields="'name'" value-field="'sys_id'" default-query="'active=true'" multiple="true"></sn-record-picker>
                        </div>
                    </div>
                  </div>
                  

                   

                  Client script:

                  function($scope, spUtil) {
                      var c = this;
                      
                      $scope.watch_list = {  
                          displayValue: c.data.displayValue,  
                          value: c.data.value,
                          name: 'watch_list'  
                    }; 
                  }
                  

                   

                  Server script:

                  (function() {
                      
                      var table = $sp.getParameter('table')
                      var sys_id = $sp.getParameter('sys_id')
                      var gr = new GlideRecord(table);
                      if(gr.get(sys_id)){
                          data.canRead = gr.watch_list.canRead();
                          data.canWrite = gr.watch_list.canWrite();
                          if(data.canRead){
                              data.displayValue = gr.getDisplayValue('watch_list');
                              data.value = gr.getValue('watch_list');
                          }
                      }
                  })();
                  

                   

                  I know this is incomplete but I hope it helps.

                  4 of 4 people found this helpful
              • Re: How to get a watch list in widget in Service Portal ?
                Sean Doone

                Laurent,

                 

                I'm trying to add the aforementioned watch list functionality (multiple user selection on the record picker) in the Service Portal. Any idea why I'm getting an uncaught type error with the scoped attribute multiple="true"? When I remove that attribute and revert to single selection, it works. Is there something I'm missing when declaring displayValue and value in the scoped watch_list object?

                 

                Error reads: Cannot ready property of 'split' of null

                 

                Further debugging shows that it's coming from the onSelecting() function with the following line:

                var values = scope.field.value == ' ' ? [] : scope.field.value.split(',');

                 

                Any help would be greatly appreciated. I'd really like to avoid a workaround for this.

                  • Re: How to get a watch list in widget in Service Portal ?
                    Warren Shekyls

                    Hi Sean,

                     

                    This is being caused by one line of code in the server side portion of the widget:

                     

                    data.value = gr.getValue('watch_list')

                     

                    When you use getValue and there is nothing in that field, getValue returns 'null', this means the clinet side see's the javascript value null and cant deal with it.

                     

                    I suggest replacing the 2 lines:

                     

                    data.displayValue = gr.getDisplayValue('watch_list');  
                    data.value = gr.getValue('watch_list');

                     

                    with these lines:

                     

                    var dV = gr.getDisplayValue('watch_list');
                    var sV = gr.getValue('watch_list');
                    data.displayValue = dV == '' ? [] : dV;
                    data.value = sV == null ? [] : sV;

                     

                    This will ensure at least a blank array is sent, which can be split.

                     

                    Edit: I don't know how to do the fancy code blocks sorry if it's tough to read

                  • Re: How to get a watch list in widget in Service Portal ?
                    Siladitya Mishra

                    Hi Guys,

                    Does any one figured out how to add save functionality, so that it will update added watch list user to the incident record?

                    I am struggling to get it done from last few days.

                     

                    Any suggestions or ideas will help me a lot.

                     

                      • Re: How to get a watch list in widget in Service Portal ?
                        Laurent Chicoine

                        Hi Siladitya,

                         

                        How do you which to update the watch list? On save (another button on your page, that is probably in another widget), as soon as a user is added/removed or a dedicated button in the watch list widget?

                         

                        Having an idea of which widgets you want to combine this with would help (especially if they are default widgets).

                          • Re: How to get a watch list in widget in Service Portal ?
                            Siladitya Mishra

                            Hi Laurent,

                             

                            I have just used your above code to get watch list on the service portal page. As of now when a user is added to the watch list in the back end in ServiceNow the user is visible in the portal page while opening the incident.

                            However now I want the user should be able to add a person in the watch list from the Service portal page, and the same should reflect in the back end of ServiceNow now.

                             

                            I have added a button on the page, so that the user should be able to save the watch list after adding user(s) to it.

                             

                            HTML:-

                            -----------------

                            <div ng-if="data.canRead" class="panel panel-primary b">
                              <div class="panel-heading">
                                <h4 class="panel-title pull-left">
                                  ${Watch list}
                                </h4>
                                <div class="clearfix"></div>
                              </div>
                              <div class="panel-body">
                                  <div class="text-center text-italic text-muted">
                                  <sn-record-picker on-change="getWatchlists(watch_list)" field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'name'" search-fields="'name'" value-field="'sys_id'" default-query="'active=true^web_service_access_only=false^user_nameISNOTEMPTY'" multiple="true"></sn-record-picker>
                                    <input type="button" value = "Apply"/>
                                 
                                </div>
                              </div>
                            </div>
                            

                             

                            Client script:-

                            ---------------------------

                            function($scope, spUtil, $http) { 
                                var c = this; 
                                 
                                $scope.watch_list = {   
                                    displayValue: c.data.displayValue,   
                                    value: c.data.value, 
                                    name: 'watch_list'   
                              };
                            $scope.getWatchlists = function (cObj) { 
                              var value = document.getElementById(cObj).value;
                              console.log("Value: "+value);
                            
                              }
                            }
                            

                             

                            Server side script:-

                            ---------------------------------

                            (function() {  
                                  
                                var table = $sp.getParameter('table'); 
                                var sys_id = $sp.getParameter('sys_id');
                              var gr = new GlideRecord('task');
                              if(gr.get(sys_id)){  
                                    data.canRead = gr.watch_list.canRead();  
                                    data.canWrite = gr.watch_list.canWrite();  
                                    if(data.canRead){  
                                        var dV = gr.getDisplayValue('watch_list'); 
                              var sV = gr.getValue('watch_list'); 
                              data.displayValue = dV == '' ? [] : dV;
                              data.value = sV == null ? [] : sV;
                                    }
                              } 
                            
                            })(); 
                            

                             

                            Please let me know if you need any more details.

                          • Re: How to get a watch list in widget in Service Portal ?
                            Laurent Chicoine

                            Hi,

                             

                            I did assume that your onchange function was just for testing so I removed it in my code, here you go (I also added a record watcher to allow the watch list to be updated in real time to avoid potential conflicts).

                             

                            I haven't played much with the service portal, so my code might not be optimal, feel free to improve it.

                             

                            HTML

                            <div ng-if="data.canRead" class="panel panel-primary b">  
                              <div class="panel-heading">  
                                <h4 class="panel-title pull-left">  
                                  ${Watch list}  
                                </h4>  
                                <div class="clearfix"></div>  
                              </div>  
                              <div class="panel-body">
                                <form ng-submit="save()">
                                    <div class="text-center text-italic text-muted">
                                      <div>
                                          <sn-record-picker field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'name'" search-fields="'name'" value-field="'sys_id'" default-query="'active=true^web_service_access_only=false^user_nameISNOTEMPTY'" multiple="true"></sn-record-picker>  
                                      </div>
                                      <div style="float:right; margin-top:15px;">
                                        <button type="submit" class="btn btn-primary">
                                          ${Apply}
                                          </button>
                                      </div>
                                    </div>
                                </form>  
                              </div>  
                            </div> 
                            

                             

                            Client controller

                            function($scope, spUtil, $http) {
                                var c = this;
                                
                                $scope.watch_list = {
                                    displayValue: c.data.displayValue,
                                    value: c.data.value,
                                    name: 'watch_list'
                                };
                                $scope.save = function(){
                                    c.data.watchList = $scope.watch_list.value;
                                    c.server.update().then(function(){
                                    });
                                };
                                spUtil.recordWatch($scope, c.data.table, "sys_id=" + c.data.sys_id, function(name, data) {
                                    if(name.name == 'record.updated' && data.operation == 'update'){
                                        $scope.watch_list.value = data.record.watch_list.value;
                                        $scope.watch_list.displayValue = data.record.watch_list.display_value;
                                        $scope.$apply();
                                    }
                                });
                            }
                            

                             

                            Server script

                            (function() {
                                var gr;
                                if(input && input.watchList){
                                    gr = new GlideRecord(input.table);
                                    if(gr.get(input.sys_id)){
                                        if(gr.watch_list.canWrite()){
                                            gr.watch_list = input.watchList;
                                            gr.update();
                                            gs.addInfoMessage('Updated');
                                        }
                                        else{
                                            gs.addErrorMessage("Update failed, you don't have the required access");
                                        }
                                    }
                                }
                                else{
                                    var table = $sp.getParameter('table');
                                    var sys_id = $sp.getParameter('sys_id');
                                    gr = new GlideRecord(table);
                                    if(gr.get(sys_id)){
                                        data.table = table;
                                        data.sys_id = sys_id;
                                        data.canRead = gr.watch_list.canRead();
                                        data.canWrite = gr.watch_list.canWrite();
                                        if(data.canRead){
                                            var dV = gr.getDisplayValue('watch_list');
                                            var sV = gr.getValue('watch_list');
                                            data.displayValue = dV == '' ? [] : dV;
                                            data.value = sV == null ? [] : sV;
                                        }
                                    }
                                }
                                
                            })();
                            
                            2 of 2 people found this helpful
                              • Re: How to get a watch list in widget in Service Portal ?
                                Siladitya Mishra

                                Hi Laurent,

                                 

                                Thanks for the help!

                                 

                                I have just remove one of the condition from the Server side script, so that the user can make the watch list value EMPTY/NULL.

                                 

                                From

                                if(input && input.watchList)
                                

                                 

                                To

                                if(input)
                                

                                 

                                Thanks again

                                • Re: How to get a watch list in widget in Service Portal ?
                                  jued0001

                                  I've added the widget and though it seems to be working, it's throwing a bunch of errors.  Has anyone else seen that, and did you resolve them?

                                  • Re: How to get a watch list in widget in Service Portal ?
                                    Pranav Parmar

                                    Hi Laurent,

                                     

                                    I am getting bunch of errors while loading this widget. Did you came across any issues for this?

                                     

                                    Also is there a way we can add email address to watchlist using this widget?

                                    • Re: How to get a watch list in widget in Service Portal ?
                                      jimboy

                                      Hi Laurent,

                                       

                                      Is it possible to not show any results when user has not typed any value yet? And how would we change the displayed value to email instead of showing the name because some of our Exchange users does not have name defined (select DL list for example).

                                        • Re: How to get a watch list in widget in Service Portal ?
                                          Laurent Chicoine

                                          To show the email instead of the name you can change the server script to this:

                                           

                                          (function() {
                                          
                                          var table = $sp.getParameter('table');
                                          var sys_id = $sp.getParameter('sys_id');
                                          var gr = new GlideRecord(table);
                                          if(gr.get(sys_id)){
                                          data.canRead = gr.watch_list.canRead();
                                          data.canWrite = gr.watch_list.canWrite();
                                          if(data.canRead){
                                          var emails = [];
                                          if(!gr.watch_list.nil()){
                                          var usersId = gr.getValue('watch_list').split(',');
                                          var userDisplay = gr.watch_list.getDisplayValue().split(',');
                                          usersId.forEach(function(userId, index){
                                          var userGr = new GlideRecord('sys_user');
                                          if(userGr.get(userId) && !userGr.email.nil()){
                                          emails.push(userGr.getValue('email'));
                                          }
                                          else{
                                          //Keep display value
                                          emails.push(userDisplay[index]);
                                          }
                                          });
                                          data.displayValue = emails.join(',');
                                          }
                                          else{
                                          data.displayValue = '';
                                          }
                                          data.value = gr.getValue('watch_list'); 
                                          }
                                          data.formModel = $sp.getForm(table, sys_id, '', 'default_view');
                                          }
                                          })();
                                          

                                           

                                          And change the sn-record-picker to this:

                                          <sn-record-picker field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'email'" search-fields="'email'" value-field="'sys_id'" default-query="'active=true^emailISNOTEMPTY'" multiple="true"></sn-record-picker>
                                          

                                           

                                          The server script allows existing member of the watch list that would not have an email address (or email addresses that would not be a reference to a user). However the field won't accept these inputs for new value.

                                           

                                          For your question about not showing any result before the user gives an input, I don't see any good way to do it, and there is no option for that.

                                            • Re: How to get a watch list in widget in Service Portal ?
                                              jimboy

                                              Tried this new server script and updated the sn-record-picker but the widget disappeared, seems like there's an error somewhere in the server script?

                                                • Re: How to get a watch list in widget in Service Portal ?
                                                  Laurent Chicoine

                                                  Could you post your previous server script?

                                                   

                                                  Dix you call the widget with the table and sys_id parameter?

                                                   

                                                  Are you able to get the errors in the log?

                                                    • Re: How to get a watch list in widget in Service Portal ?
                                                      jimboy

                                                      Here's the widget code:

                                                       

                                                      HTML

                                                      <div class="panel panel-default" ng-if="data.canRead">    
                                                        <div class="panel-heading">    
                                                          <h4 class="panel-title pull-left">    
                                                            ${Watch list}    
                                                          </h4>    
                                                          <div class="clearfix"></div>    
                                                        </div>          
                                                        <div class="panel-body">
                                                          <form ng-submit="save()">
                                                            <div class="text-center text-italic text-muted">
                                                              <div>
                                                                <sn-record-picker field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'email'" display-fields="'name'" search-fields="'email'" value-field="'sys_id'" default-query="'active=true^web_service_access_only=false^user_nameISNOTEMPTY^emailISNOTEMPTY'" page-size="10" multiple="true"></sn-record-picker>
                                                              </div>
                                                              <div style="margin-top:15px; float: right;">
                                                                <button type="submit" class="btn btn-default btn-sm">${Update}</button>
                                                              </div>
                                                            </div>
                                                          </form>
                                                        </div>
                                                      </div>
                                                      

                                                       

                                                      Client script

                                                      function($scope, spUtil, $http) {  
                                                          var c = this;  
                                                            
                                                          $scope.watch_list = {  
                                                              displayValue: c.data.displayValue,  
                                                              value: c.data.value,  
                                                              name: 'watch_list'
                                                          };  
                                                          $scope.save = function(){  
                                                              c.data.watchList = $scope.watch_list.value;  
                                                              c.server.update().then(function(){  
                                                              });  
                                                          };  
                                                          spUtil.recordWatch($scope, c.data.table, "sys_id=" + c.data.sys_id, function(name, data) {  
                                                              if(name.name == 'record.updated' && data.operation == 'update'){  
                                                                  $scope.watch_list.value = data.record.watch_list.value;  
                                                                  $scope.watch_list.displayValue = data.record.watch_list.display_value;  
                                                                  $scope.$apply();  
                                                              } 
                                                          });  
                                                      $scope.$on("field.change", function(evt, parms) {
                                                      if (parms.field.name == 'watch_list'){
                                                      }
                                                      });
                                                      }  
                                                      

                                                       

                                                      Server script

                                                      (function() {  
                                                          var gr;  
                                                          if(input){  
                                                              gr = new GlideRecord(input.table);  
                                                              if(gr.get(input.sys_id)){  
                                                                  if(gr.watch_list.canWrite()){  
                                                                      gr.watch_list = input.watchList;  
                                                                      gr.update();  
                                                                      gs.addInfoMessage('Updated');  
                                                                  }  
                                                                  else{  
                                                                      gs.addErrorMessage("Update failed, you don't have the required access");  
                                                                  }  
                                                              }  
                                                          }  
                                                          else{  
                                                              var table = $sp.getParameter('table');  
                                                              var sys_id = $sp.getParameter('sys_id');  
                                                              gr = new GlideRecord(table);  
                                                              if(gr.get(sys_id)){  
                                                                  data.table = table;  
                                                                  data.sys_id = sys_id;  
                                                                  data.canRead = gr.watch_list.canRead();  
                                                                  data.canWrite = gr.watch_list.canWrite();  
                                                                  if(data.canRead){  
                                                       var dV = gr.getDisplayValue('watch_list');  
                                                                      var sV = gr.getValue('watch_list');  
                                                                      data.displayValue = dV == '' ? [] : dV;  
                                                                      data.value = sV == null ? [] : sV;  
                                                                  }  
                                                              }  
                                                          }  
                                                      })();
                                                      
                                                      
                                                        • Re: How to get a watch list in widget in Service Portal ?
                                                          Laurent Chicoine

                                                          Sorry, I did it quick and forgot to test with an empty watch list. I updated the code I posted with the following change: I replaced if(gr.getValue('watch_list') != '') with: if(!gr.watch_list.nil())

                                                           

                                                          On my side it is working with this. If it's not working, please provide the logs that are given in your browser console.

                                                           

                                                           

                                                            • Re: How to get a watch list in widget in Service Portal ?
                                                              jimboy

                                                              I replaced the server code and still the widget did not appear. Here's the error from browser console:

                                                              TypeError: Cannot read property 'startsWith' of undefined

                                                                  at isBlockedTable (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:56122)

                                                                  at Object.initChannel (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:56098)

                                                                  at Object.recordWatch (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:66766)

                                                                  at new api.controller (ticket_watchlist_jgs.js:16)

                                                                  at Object.invoke (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:8230)

                                                                  at $controllerInit (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:10657)

                                                                  at nodeLinkFn (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:9945)

                                                                  at compositeLinkFn (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:9521)

                                                                  at publicLinkFn (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:9444)

                                                                  at Object.render (js_includes_sp.jsx?v=07-20-2017_1155&lp=Tue_Mar_28_20_39_49_PDT_2017&c=2_42:69355)

                                                                • Re: How to get a watch list in widget in Service Portal ?
                                                                  Laurent Chicoine

                                                                  Ok, I took your script to update it to make sure I have the same thing as you have.

                                                                   

                                                                  First thing, taking it as is it is not working for me a I get the following error: Uncaught TypeError: scope.field.value.split is not a function

                                                                   

                                                                  This seems to be caused by the use of an array instead of using a string because usually the split function is called on a string and is not available for an array.

                                                                   

                                                                  Here is the updated server function:

                                                                   

                                                                  (function() {    
                                                                      var gr;    
                                                                      if(input){    
                                                                          gr = new GlideRecord(input.table);    
                                                                          if(gr.get(input.sys_id)){    
                                                                              if(gr.watch_list.canWrite()){    
                                                                                  gr.watch_list = input.watchList;    
                                                                                  gr.update();    
                                                                                  gs.addInfoMessage('Updated');    
                                                                              }    
                                                                              else{    
                                                                                  gs.addErrorMessage("Update failed, you don't have the required access");    
                                                                              }    
                                                                          }    
                                                                      }    
                                                                      else{    
                                                                          var table = $sp.getParameter('table');    
                                                                          var sys_id = $sp.getParameter('sys_id');    
                                                                          gr = new GlideRecord(table);    
                                                                          if(gr.get(sys_id)){    
                                                                              data.table = table;    
                                                                              data.sys_id = sys_id;    
                                                                              data.canRead = gr.watch_list.canRead();    
                                                                              data.canWrite = gr.watch_list.canWrite();    
                                                                              if(data.canRead){ 
                                                                  var emails = [];
                                                                  if(!gr.watch_list.nil()){
                                                                  var usersId = gr.getValue('watch_list').split(',');
                                                                  var userDisplay = gr.watch_list.getDisplayValue().split(',');
                                                                  usersId.forEach(function(userId, index){
                                                                  var userGr = new GlideRecord('sys_user');
                                                                  if(userGr.get(userId) && !userGr.email.nil()){
                                                                  emails.push(userGr.getValue('email'));
                                                                  }
                                                                  else{
                                                                  //Keep display value
                                                                  emails.push(userDisplay[index]);
                                                                  }
                                                                  });
                                                                  }
                                                                  var dV = emails.join(',');
                                                                  var sV = gr.getValue('watch_list');    
                                                                  data.displayValue = dV;    
                                                                  data.value = sV == null ? "" : sV;    
                                                                              }    
                                                                          }    
                                                                      }    
                                                                  })();  
                                                                  

                                                                   

                                                                   

                                                                  It is working in my developer instance on Jakarta release on a test page having this single widget. If you still have an error maybe you should try with a test page to see if your issue is not related to a library being loaded or another widget.

                                                                  1 of 1 people found this helpful
                                                                    • Re: How to get a watch list in widget in Service Portal ?
                                                                      jimboy

                                                                      Hi Laurent, the new server script is now working on my side as well - it now shows the email address instead of display name. Thank you very much for your swift response.

                                                                      • Re: How to get a watch list in widget in Service Portal ?
                                                                        jimboy

                                                                        Just noticed now that this does not check whether the incident ticket is active still active or not, which leads us to unexpected behavior that when user is viewing the ticket and the incident was closed then user can still edit the watch list.

                                                                         

                                                                        I was trying to play around with the record watcher you incorporated on client script but can't make it work so that when ticket is not active anymore the watch list will be disabled. I know that I can add an OR statement on the sn-disabled property and check on server script if ticket is active or not but this only applied when user reloads the page, when user does not reload and ticket is updated it is not captured.

                                                                          • Re: How to get a watch list in widget in Service Portal ?
                                                                            Laurent Chicoine

                                                                            Ok so first I update the HTML so it checks for the canWrite for the Update button:

                                                                             

                                                                            <div class="panel panel-default" ng-if="data.canRead">      
                                                                              <div class="panel-heading">      
                                                                                <h4 class="panel-title pull-left">      
                                                                                  ${Watch list}      
                                                                                </h4>      
                                                                                <div class="clearfix"></div>      
                                                                              </div>            
                                                                              <div class="panel-body">  
                                                                                <form ng-submit="save()">  
                                                                                  <div class="text-center text-italic text-muted">  
                                                                                    <div>  
                                                                                      <sn-record-picker field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'email'" display-fields="'name'" search-fields="'email'" value-field="'sys_id'" default-query="'active=true^web_service_access_only=false^user_nameISNOTEMPTY^emailISNOTEMPTY'" page-size="10" multiple="true"></sn-record-picker>  
                                                                                    </div>  
                                                                                    <div style="margin-top:15px; float: right;">  
                                                                                      <button ng-disabled="!data.canWrite" type="submit" class="btn btn-default btn-sm">${Update}</button>  
                                                                                    </div>  
                                                                                  </div>  
                                                                                </form>  
                                                                              </div>  
                                                                            </div>  
                                                                            

                                                                             

                                                                            Then for the recordWatch I was able to use it however the way I use it does not match the documentaiton, the function callback of the recordWatch was returning me a single parameter which was the data object, I was not receiving any name... So if it does not work this way, you can try to change the callback function to function(name, data)

                                                                             

                                                                            function($scope, spUtil, $http) {    
                                                                                var c = this;    
                                                                                    
                                                                                $scope.watch_list = {    
                                                                                    displayValue: c.data.displayValue,    
                                                                                    value: c.data.value,    
                                                                                    name: 'watch_list'  
                                                                                };    
                                                                                $scope.save = function(){    
                                                                                    c.data.watchList = $scope.watch_list.value;    
                                                                                    c.server.update().then(function(){    
                                                                                    });    
                                                                                };    
                                                                                spUtil.recordWatch($scope, c.data.table, "sys_id=" + c.data.sys_id, function(data) {
                                                                            if(data.data.operation == 'update'){
                                                                            var activeUpdate = data.data.changes.indexOf('active') > -1;
                                                                            var watchListUpdate = data.data.changes.indexOf('watch_list') > -1;
                                                                            if(activeUpdate || watchListUpdate){
                                                                            c.data.recordRefresh = true;
                                                                            c.data.watchList = false; //Do not pass the watch list in the update
                                                                            c.server.update().then(function(){ 
                                                                            $scope.watch_list.displayValue = c.data.displayValue;
                                                                            $scope.watch_list.value = c.data.value;
                                                                            });
                                                                            }
                                                                            }   
                                                                                });    
                                                                            } 
                                                                            

                                                                             

                                                                            We need to go back to server script because we cannot simply use the display value provided as we need to get the email addresses. So we simply server update and run the initialization script again, it is a light script so I'm not really worried about it's performance. I changed the condition for if(input.watchList) so that the other script is runned for other outputs.

                                                                             

                                                                            (function() {    
                                                                                var gr;    
                                                                                if(input.watchList){  
                                                                            gr = new GlideRecordSecure(input.table);    
                                                                            if(gr.get(input.sys_id)){    
                                                                            if(gr.watch_list.canWrite()){    
                                                                            gr.watch_list = input.watchList;    
                                                                            gr.update();    
                                                                            gs.addInfoMessage('Updated');    
                                                                            }    
                                                                            else{    
                                                                            gs.addErrorMessage("Update failed, you don't have the required access");    
                                                                            }    
                                                                            }
                                                                                }    
                                                                                else{    
                                                                                    var table = $sp.getParameter('table');    
                                                                                    var sys_id = $sp.getParameter('sys_id');    
                                                                                    gr = new GlideRecord(table);    
                                                                                    if(gr.get(sys_id)){    
                                                                                        data.table = table;    
                                                                                        data.sys_id = sys_id;    
                                                                                        data.canRead = gr.watch_list.canRead();    
                                                                                        data.canWrite = gr.watch_list.canWrite();    
                                                                                        if(data.canRead){ 
                                                                            var emails = [];
                                                                            if(!gr.watch_list.nil()){
                                                                            var usersId = gr.getValue('watch_list').split(',');
                                                                            var userDisplay = gr.watch_list.getDisplayValue().split(',');
                                                                            usersId.forEach(function(userId, index){
                                                                            var userGr = new GlideRecord('sys_user');
                                                                            if(userGr.get(userId) && !userGr.email.nil()){
                                                                            emails.push(userGr.getValue('email'));
                                                                            }
                                                                            else{
                                                                            //Keep display value
                                                                            emails.push(userDisplay[index]);
                                                                            }
                                                                            });
                                                                            }
                                                                            var dV = emails.join(',');
                                                                            var sV = gr.getValue('watch_list');    
                                                                            data.displayValue = dV;    
                                                                            data.value = sV == null ? "" : sV;    
                                                                                        }    
                                                                                    }    
                                                                                }    
                                                                            })();  
                                                                            

                                                                             

                                                                            Hope it works without bugs for you this time .

                                                                            1 of 1 people found this helpful
                                                                              • Re: How to get a watch list in widget in Service Portal ?
                                                                                jimboy

                                                                                I think hiding the "Update" button is not enough for the behavior we want to achieve.

                                                                                 

                                                                                So here's what's my working code's behavior right now - when the incident's state is changed to Resolved or Closed, the snRecordPicker is disabled.This behavior is much better since users will only see a read-only view of the watch list. The problem with my current code is that it only works when you reload the page (whatever the state is during that reload), if ever the state changes to Resolved/Closed while use is viewing the page, the snRecordPicker does not update - that is where we need help, to make it update in real-time as state changes.

                                                                                 

                                                                                And by the way, on your server script, it will not allow a blank value (if user removes everything on watch list) to save since you used if(input.watchList){, we used if(input){ instead so it will accept blank value.

                                                                                 

                                                                                HTML

                                                                                <div class="panel panel-default" ng-if="data.canRead">   
                                                                                  <div class="panel-heading">   
                                                                                    <h4 class="panel-title pull-left">   
                                                                                      ${Watch list}   
                                                                                    </h4>   
                                                                                    <div class="clearfix"></div>   
                                                                                  </div>         
                                                                                  <div class="panel-body">
                                                                                    <form ng-submit="save()">
                                                                                      <div class="text-center text-italic text-muted">
                                                                                        <div>
                                                                                          <sn-record-picker field="watch_list" sn-disabled="!data.canWrite||!data.editWatchlist" table="'sys_user'" display-field="'email'" display-fields="'name'" search-fields="'email'" value-field="'sys_id'" default-query="'active=true^web_service_access_only=false^user_nameISNOTEMPTY^emailISNOTEMPTY^emailNOT LIKEcorp.jgsummit^emailNOT LIKEonmicrosoft.com^emailNOT LIKElocal.com^emailNOT LIKE.local'" page-size="10" multiple="true"></sn-record-picker>
                                                                                        </div>
                                                                                        <div style="margin-top:15px; float: right;">
                                                                                          <button type="submit" class="btn btn-default btn-sm" ng-disabled="!data.canWrite">${Update}</button>
                                                                                        </div>
                                                                                      </div>
                                                                                    </form>
                                                                                  </div>
                                                                                </div>
                                                                                

                                                                                 

                                                                                Client Script

                                                                                function($scope, spUtil, $http) {
                                                                                var c = this;
                                                                                
                                                                                
                                                                                $scope.watch_list = {
                                                                                displayValue: c.data.displayValue,
                                                                                value: c.data.value,
                                                                                name: 'watch_list'
                                                                                };
                                                                                $scope.save = function(){
                                                                                c.data.watchList = $scope.watch_list.value;
                                                                                c.server.update().then(function(){
                                                                                });
                                                                                };
                                                                                spUtil.recordWatch($scope, c.data.table, "sys_id=" + c.data.sys_id, function(name, data) {
                                                                                if(name.name == 'record.updated' && data.operation == 'update'){
                                                                                $scope.watch_list.value = data.record.watch_list.value;
                                                                                $scope.watch_list.displayValue = data.record.watch_list.display_value;
                                                                                $scope.$apply();
                                                                                }
                                                                                });
                                                                                $scope.$on("field.change", function(evt, parms) {
                                                                                if (parms.field.name == 'watch_list'){
                                                                                }
                                                                                });
                                                                                }
                                                                                

                                                                                 

                                                                                Server Script

                                                                                (function() {
                                                                                var gr;
                                                                                if(input){
                                                                                gr = new GlideRecord(input.table);
                                                                                if(gr.get(input.sys_id)){
                                                                                if(gr.watch_list.canWrite()){
                                                                                gr.watch_list = input.watchList;
                                                                                gr.update();
                                                                                gs.addInfoMessage('Updated');
                                                                                }
                                                                                else{
                                                                                gs.addErrorMessage("Update failed, you don't have the required access");
                                                                                }
                                                                                }
                                                                                }
                                                                                else{
                                                                                var table = $sp.getParameter('table');
                                                                                var sys_id = $sp.getParameter('sys_id');
                                                                                gr = new GlideRecord(table);
                                                                                if(gr.get(sys_id)){
                                                                                data.table = table;
                                                                                data.sys_id = sys_id;
                                                                                data.canRead = gr.watch_list.canRead();
                                                                                data.canWrite = gr.watch_list.canWrite();
                                                                                if(data.canRead){
                                                                                var emails = [];
                                                                                if(!gr.watch_list.nil()){
                                                                                var usersId = gr.getValue('watch_list').split(',');
                                                                                var userDisplay = gr.watch_list.getDisplayValue().split(',');
                                                                                usersId.forEach(function(userId, index){
                                                                                var userGr = new GlideRecord('sys_user');
                                                                                if(userGr.get(userId) && !userGr.email.nil()){
                                                                                emails.push(userGr.getValue('email'));
                                                                                }
                                                                                else{
                                                                                //Keep display value
                                                                                emails.push(userDisplay[index]);
                                                                                }
                                                                                });
                                                                                }
                                                                                var dV = emails.join(',');
                                                                                var sV = gr.getValue('watch_list');
                                                                                data.displayValue = dV;
                                                                                data.value = sV == null ? "" : sV;
                                                                                }
                                                                                }
                                                                                }
                                                                                
                                                                                // Check if current ticket is in Closed/Resolved State (make watch list read only)
                                                                                if(data.table == 'incident' && gr.caller_id == gs.getUserID() && gr.state == 6||gr.state == 7){
                                                                                data.editWatchlist = false;
                                                                                } else {
                                                                                data.editWatchlist = true;
                                                                                }
                                                                                // End
                                                                                
                                                                                })();
                                                                                
                                                                                1 of 1 people found this helpful
                                                                                  • Re: How to get a watch list in widget in Service Portal ?
                                                                                    Laurent Chicoine

                                                                                    You are right about the blank value.

                                                                                     

                                                                                    However, maybe I was not explicit enough but the code I proposed does not simply grey out the update button, it updates the data.canWrite and data.canRead when the active field is updated. Also I changed the script so it uses the GlideRecordSecure API so that ACL are checked when the user update the watch list. For the part about the data.canRead and data.canWrite being evaluated on change of the active field, you could change that to the state field, you could also completely remove this condition to refresh the widget on each update if you want to make sure the ACL take into account any dynamic security rule you have:

                                                                                     

                                                                                    var stateUpdate = data.data.changes.indexOf('state') > -1;

                                                                                    instead of

                                                                                    var activeUpdate = data.data.changes.indexOf('active') > -1;

                                                                                     

                                                                                    and the condition would become if(stateUpdate || watchListUpdate)

                                                                                     

                                                                                    As for the input being potentially blank, you can change condition to check for an explicit false boolean as we are passing false when simply refreshing the widget: if(input && input.watchList !== false)