We've updated the ServiceNow Community Code of Conduct, adding guidelines around AI usage, professionalism, and content violations. Read more

snChoiceList Directive snOnChange issue

Thomas Wright
Giga Expert

Hi All,

Need some Service Portal widget expertise please. I'm having trouble getting the value out of a sn-choice-list field with an onchange. Here's my HTML:

<sn-choice-list

        sn-on-change="c.valueSelected(attribute)"

        sn-model="attribute.value"

        sn-items="attribute.choices"

        sn-value-field="value"

        sn-text-field="display">

</sn-choice-list>

And my client script:

c.valueSelected = function(attribute) {

        alert(attribute.value);

};

alert(attribute.value) is giving me the oldValue rather than newValue - guessing it's some asynchronous thing. Anyone know how to get the newValue directly on a change?

11 REPLIES 11

I haven't tested this yet, but I did look at the directive code for snChoiceList. It looks to me that you would actually need to access the new value as attribute.selectedValue.   So in your code...



c.valueSelected = function(attribute) {  


        alert(attribute.selectedValue);  


};


Unfortunately attribute.selectedValue is undefined for me, sticking with my setTimeout workaround for now


Thanks for checking though



My version is glide-istanbul-09-23-2016__patch10b-12-07-2017 if that helps


mspeirs
Mega Expert

You could use $scope.$watch to look for changes to the model, instead of using the sn-on-change attribute.



$scope.$watch("attribute.value",function(newValue,oldValue) {


      if(newValue != oldValue) { // Prevents running on page load


              alert('ov: ' + oldValue + ' nv: ' + newValue);


      }


});


I would do, but I need to know specifically when this value changes due to a user interaction as I am setting the value using scripts elsewhere


It does trigger when the value changes due to a user interaction. It is essentially the same way that sn-on-change handles it, only we have complete control because it is our code. To see how ServiceNow is handling it under-the-hood, go to <your-instance>.service-now.com/scripts/js_includes_sp.js and search for snChoiceList. This is the definition of the choice list. If you scroll down just a little further you will see how it handles sn-on-change (a.k.a. snOnChange). I added some comments:




scope.$watch("model", function(newValue, oldValue){ // Triggered by a change to variable passed in as sn-model


  if (newValue !== oldValue){


      scope.snModel = newValue;


  if (scope.snOnChange) // If sn-on-change exists


      scope.snOnChange({selectedValue:newValue}); // Execute it


  }


});



So if sn-on-change exists, it executes the function. Notice that it is watching the value you passed in as sn-model which it assigned as just "model" in the init() function.



function init(){


  scope.model = scope.snModel;



If you are fine with your setTimeout method, great. But the method I mentioned above works as well and is essentially the same way ServiceNow is handling it under-the-hood.