Omnis Technical Note TNJS0009Mar 2020

Theming an Omnis JavaScript application

for Omnis Studio 10 or above
By Andrei Augustin, Omnis Engineer

As many of you may know already, we can change the visual aspect of an Omnis JavaScript application with CSS by editing the user.css file (situated our writable directory path, /html/css/user.css) and setting the $cssclassname property for a component on our remote form.

This is very advantageous as everyone can change the way the components in their application look on the web page in order to integrate the app better with their brand colours and style.

Today, we will take this one step further by showing you how to create more than one stylesheet and seamlessly switch in between your application’s styles at runtime. The use cases for this would be to offer an enhanced end-user experience, so for example your application could have a dark and bright theme.

First step, prepare our stylesheets

Let’s start by preparing two stylesheets, one for the ‘dark theme’ and one for the ‘bright theme’. For the purpose of this example, I will keep it simple and create only one CSS class for a button.

Here is what my dark theme looks like:

Dark theme

And here is what my bright theme looks like:

Bright theme

As you can see, these CSS files are called dark-theme.css and bright-theme.css respectively, therefore we will need to include them into our remote form.

When you create a new remote form and test it, Omnis will use the jsctempl.htm file as a template for the HTML file of our remote form.
This means that any changes we make to the jsctemp.htm will be replicated in any future remote forms we create (note that the remote form is created when you do test remote form for the first time, so if you don’t see any changes, delete your remote form .htm file from within the html directory in the writable directory and then do a test remote form in Omnis again so that the htm file will be re-generated with the updated template).

Here is how we can import our new stylesheets by editing the jsctempl.htm:

JS template

And the code:
<!-- Edit user.css to specify any CSS classes assigned using the $cssclassname property -->
<link type="text/css" href="css/user.css" rel="stylesheet" media="print, screen" />
<link type="text/css" href="css/dark-theme.css" rel="alternate stylesheet" media="print, screen" title="Dark Theme" class="themeStylesheet"/>
<link type="text/css" href="css/bright-theme.css" rel="alternate stylesheet" media="print, screen" title="Bright Theme" class="themeStylesheet"/>

As you can see, I have only added two new lines after the existing link for the user.css stylesheet, and made sure I use a rel type of alternate stylesheet, give it a title and a class. We will use the title in the future to refer to the stylesheet so it’s important we give it a specific title!

The next step is to create a JS function on our main remote form’s $init which we can then call whenever we need to switch stylesheet. Something along these lines will do the job:

JavaScript: window.setActiveStylesheet = function(stylesheetTitle) {
JavaScript: var nodesToDisable = document.querySelectorAll('link.themeStylesheet');
JavaScript: var nodesToEnable = document.querySelectorAll('link[title="' + stylesheetTitle + '"].themeStylesheet');
JavaScript: for (var i=0; i<nodesToDisable.length; i++) {
JavaScript: nodesToDisable[i].disabled = true;
JavaScript: }
JavaScript: for (var i=0; i<nodesToEnable.length; i++) {
JavaScript: nodesToEnable[i].disabled = false;
JavaScript: }
JavaScript:};
JavaScript: window.setActiveStylesheet("Bright Theme");
JavaScript: window.currentStylesheet = 'bright';

Now we can integrate our switch button!

I will have a client-executed $event for this button and it will execute the following javascript:

On evClick
  JavaScript: switch (window.currentStylesheet) {
  JavaScript: case 'bright':
  JavaScript: window.setActiveStylesheet("Dark Theme");
  JavaScript: window.currentStylesheet = 'dark';
  Do $cinst.$backcolor.$assign(rgb(0,0,0))
  JavaScript: break;
  JavaScript: case 'dark':
  JavaScript: window.setActiveStylesheet("Bright Theme");
  JavaScript: window.currentStylesheet = 'bright';
  Do $cinst.$backcolor.$assign(rgb(255,255,255))
  JavaScript: break;
  JavaScript: }

Overall, the $init will set the active stylesheet to the stylesheet with title Bright Theme and the window object gets a new variable called currentStylesheet with a value of bright. The button will then switch on currentStylesheet of the window object and if it’s bright, it will set the current stylesheet to the stylesheet with a title of Dark Theme and change the currentStylesheet on the window to dark and also change the remote form’s background to rgb(0,0,0), which is pitch black. When the currentStylesheet is dark, it will do the vice-versa and set the current stylesheet to the stylesheet with title Bright Theme, it will set the currentStylesheet on the window object to a value of bright and it will change the remote form’s background colour to rgb(255,255,255) which is white.

Now, let's not forget to set the $cssclassname on our button to the CSS class name which in this case we defined as themedButton in the dark-theme.css and the bright-theme.css:

CSS class name

And let’s not forget to also set the $backpattern of the remote form to kPat1:

Back patter

That’s it! If we now do a test form, we can see our bright theme at work:

Bright theme button

Hovering over the button in the bright theme:

Bright theme button hover

After we click on the button, it will switch themes:

Switched theme

Hovering over the button in dark theme:

Switched theme hover

And obviously clicking on the button again will switch back to the bright theme.

This can now be taken much further, you can have many more themes and you can have multiple buttons or checkboxes to select the theme you want.

I hope this will be a helpful resource for you when working on your awesome Omnis JS application and special thanks go to Jason Gissing for the inspiring code snippets.

 

Search Omnis Developer Resources

 

Hit enter to search

X