snChoiceList Directive snOnChange issue

Thomas Wright-1
Mega 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.