DOM Manipulation the Service Portal way

nathanfirth
Tera Guru

One of the amazing features of Service Portal is how it encapsulates each widget into a self-contained component. This encapsulation greatly increases the maintainability and reduces code complexity by breaking the portal or application down into many smaller units of functionality (widgets). However, if you start using jQuery or performing DOM manipulation directly within the controller, you can quickly cause problems in your application.

Officially, this is not a good practice. According to the AngularJS Documentation:

Do not use controllers to manipulate the DOM — Controllers should contain only business logic. Putting any presentation logic into Controllers significantly affects its testability. AngularJS has databinding for most cases and directives to encapsulate manual DOM manipulation.

The Link Function to the rescue!

In AngularJS, DOM manipulation is typically only performed inside of the Link Function of a Directive, and in Service Portal, this is available via the "Link Function" field of the widget. By using the "element" object, you get access to the DOM of the widget.

Consider the following example:
g2

Here is another quick example calling a jQuery Plugin
g1

If you're using jQuery plugins, you may wish to create a custom directive to make it reusable across multiple widgets.

By using the Link Function and "element" object, you're staying within the confines of the current widget, and won't accidentally impact other widgets or elements on the page.

Further reading:

jQuery Plugins as Angular Directives
DOM Manipulation in AngularJS
Creating a Directive that Manipulates the DOM
DOM Manipulation the AngularJS way

Find many similar articles and tutorials at: https://serviceportal.io

6 REPLIES 6

Why not just put a class on the container (using the "parent class" field), and then add the background image to the class dynamically?

 

I would not recommend trying to swap out the image via DOM manipulation from the Link function, but the image is in the DOM on the container DIV.

Thanks for the pointer Natahan. Ill investigate this option