Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

[Service Portal] Overriding angular directives

Community Alums
Not applicable

Curious if there is any documentation on overriding angular directives in Service Portal? I want to overwrite the <sp-help-tag> directive. I thought it could be done using an angular provider. I found an example of how to accomplish this for the `spModel` directive, in this article

function(spModelDirective) {
return angular.extend({}, spModelDirective[0], {
templateUrl : 'custom_model.xml'
});
}

I tried this:

function(spHelpTagDirective) {
return angular.extend({}, spHelpTagDirective[0], {
templateUrl : 'custom_help.xml'
});
}

That doesn't seem to be working. Any ideas? I may not have the syntax correct.

The piece I am confused about is why is the directive in the example above is referred to as "spModelDirective" and not just "spModel". Looking at the source code in the console:

find_real_file.png

The directive is called 'spModel'. The same for 'spHelpTag':

find_real_file.png

It seems simple enough to just create a new angular directive, and a provider to point to the new template. I also noticed there is a difference between the two directives:

'spModel' has 

return attrs.templateUrl || sp_model.xml

Whereas the 'spHelpTag' does not. Wondering if that may be why it isn't possible to extend the directive?

Ultimately, I would like to change the functionality of the 'sp-help-tag' directive, so if anyone has any ideas, feel free to chime in!

Cheers!

Tim

5 REPLIES 5

Oleg
Mega Sage

Could you describe more detailed what you need to implement? It would be good if you describe the scenario of usage and the goals, which you want to achieve.

The article describes how one could define new directive based on existing one. One defines new lblspModelCustomTemplate directive. So one can use <lblsp-model-custom-template> instead of <sp-modal> without duplication the whole code of spModal directive. It don't change the behavior of <sp-modal>. I mean that if you would place both <lblsp-model-custom-template> and <sp-modal> on one page, then the existence of <lblsp-model-custom-template> on the page will not change the behavior of <sp-modal> (which will be loaded before loading of <lblsp-model-custom-template>). The same can be done in more simple way by coping the code of spModal to the code of new directive lblspModelCustomTemplate.

I guess that it's not what you want because you write about "overriding". I suppose that you want to change the behavior of <sp-help-tag> placed on the page indirectly by some other widget. I think that you can't override the implementation of spHelpTag directive at least in the way described in the referenced article.

Community Alums
Not applicable

Thanks for your response! 

I want to hide the 'More Information' and chevron in the catalog item form:

find_real_file.png

So, it would look like this:

find_real_file.png

I posted another question about doing this in the widget with jQuery.

As I stated in the other question, I can do this manually by typing the jQuery 'hide()' in the browser console, but I cannot seem to get the code to execute in the Link function or the client script. I think it may be a timing thing; the element is not rendered at the time the page/widget loads, so the 'hide()' will not work. I have tried various methods to doing this (checking for the document to be ready, etc), without any luck. 

I though this way (overriding the angular directive) might be another approach, thus the reason I posted this second question.

Cheers,

 

Tim 

I'm still not sure that I understand your scenario. Let us you have a Catalog Item, like "New LDAP Server", which have some variables with help. Then you can create Client Script, like the following, which hide the required information:

function onLoad() {
	var $ = this.jQuery;
	setTimeout(function () {
		$("sp-help-tag").hide();
	}, 0);
}

find_real_file.png

The script hides all <sp-help-tag> elements.

You can open item_option_new table and filter the records by "Show help" equal true to find all catalog items, which has helps and add the script to the catalog items. You can write small script which do that. Alternatively you can add the onLoad Catalog Client to all catalog items by including common Variable Set. In the way it should be possible to implement your requirements.

Community Alums
Not applicable

Thanks again for your response. 

What I am trying to do is hide the 'more information' text in the <sp-help-tag> directive. I want the actual help text to still appear, but not show the chevron and the 'more information' text; as per the images I posted above.

As per your example code, I can hide the div container onLoad, however I accomplished this in the client script of the widget:

$timeout(function() {
	$('div.m-b-xs.text-muted').each(function() {
		$(this).hide();
	});
}, 350, false);

This has to happen for every catalog item, so it would be inefficient to use an onLoad client script to do so. Unless, of course, it was done using a UI script or something of that nature.

Here is the HTML code for the <sp-help-tag> directive:

<div class="help-tag">
    <div class="m-b-xs text-muted" ng-click="field.expand_help = !field.expand_help"
        ng-if="::(field.help_text || field.instructions)">
        <i ng-class="field.expand_help ? 'fa fa-chevron-up' : 'fa fa-chevron-down'"
            aria-expanded="{{field.expand_help}}" class="m-r-xs accordion-toggle">
        </i>
        {{::field.help_tag}}
    </div>
    <div ng-if="field.expand_help" class="text-muted well wrapper-xs m-b-sm">
        <span title="{{::field.help_tag}}" class="m-b-xs m-t-xs" ng-bind="::field.help_text"></span>
        <span ng-bind-html="::trustedHTML(field.instructions)"></span></div>
</div>

I want it to look like this:

<div class="help-tag">
   <div ng-if="field.expand_help" class="text-muted well wrapper-xs m-b-sm">
        <span title="{{::field.help_tag}}" class="m-b-xs m-t-xs" ng-bind="::field.help_text"></span>
        <span ng-bind-html="::trustedHTML(field.instructions)"></span></div>
</div>

What I was attempting to accomplish, hence the reason and title for this post, is use an alternate directive/html template to display the help text. I don't believe it is possible, though, given what I have discovered over the course of doing this work. It seems the solution at this point, though it's not a elegant as I would like, is to hide the element when the widget loads, using a timeout.

Thanks again for your input!

Cheers,

Tim