Cireson Portal: Dynamic Forms by Template ID, Part 2

Continuing from our last article we are going to move forward with the process of automating the display of our designated custom tab, but first lets do a quick review.

The last entry is available here: Part 1

Last time we worked through the basics of why you would want to use a solution like this, as well as how we can customize a portal form to display our custom property extensions for the workitem classes, and now we are going to discuss how we can manipulate the form on load to display the custom tab automatically based on the template id of the form.

Here are the basics.

We want to hide the GENERAL tab and display our PROJECT form whenever a form is loaded that is for a PROJECT service request. We are designated what is and isn’t a project service request by a setting in the TemplateId field of the service request. We can see what the value of the template id property is of a request by opening the developer tools of the browser (F12) and going to the console and typing in the following:

pageForm.viewModel.get(“TemplateId”)

In most cases this is going to be NULL, unless you’ve already set it. We will discuss how to set the template id by default in a future post, but for today we are going to simply set the TemplateId ourselves and this simply use this service request over and over for our testing. To set the TemplateId use the following command:

pageForm.viewModel.set(“TemplateId”,”project”)

Now if you use the GET method show in the previous command you should see ‘project’ returned, but we will still need to save the changes to the service request before it will be committed to the database. We can do this by simply saving the the service request in the usual manner. In this case let’s simply click ‘Apply’ so the changes are committed but we remain in the form.

Now it’s time for us to focus on the javascript portion of our solution. We are going to use the custom.js file that sits in the customspace. This file is loaded in a few different places in the portal, but primarily it’s loaded on the load of all workitem and asset management forms. Since it is available to us, along with any code within it, in these forms this is what we will use to inject our code on form load.

We want to accomplish two things with the code. First we want to show the PROJECT tab by default, and second we want to hide the GENERAL tab. Let’s look at how we can activate the PROJECT tab first:

function fn_ShowTab(name,form){
   console.log("This is a Non-Standard Request");
   $('a[data-toggle=tab]').each(function(){
      if(this.innerText === name){
         $(this).trigger('click');
      } else if (this.innerText === "GENERAL") {
         $(this).hide();
      }
   });
}

This function will hide any tab by the ‘name’ that is passed to it inside the ‘form’ that is passed in as well. Lets work through the function in detail.

The first line simply logs an entry that lets us know we’ve identified a ‘Non-standard Request’.

The second line is jQuery and looks for the ‘data-toggle’ element in the form that contains the value ‘tab’. When the object is found (one or more) an array maybe a returned and the .each() function will run a line of code for each element that is found. In our case we are running a function for each one.

Within the function we are looking at the text of the HTML element to see if it is equal to the name we passed into the function. If it it passes the check then we user the trigger function on the element which has the same effect as ‘clicking’ the tab in the browser. This activates the tab for us. If the check doesn’t pass the second check is fired to see if it’s the ‘GENERAL’ tab and if so then we hide that tab.

This bit of code successfully shows our custom tab by default AND hides the GENERAL tab for us. We are now halfway 2/3rd of the way there.

Now lets look at the next function required for the solution:

function fn_HideTab(name,form){
   console.log("This is NOT a Non-Standard Request");
   $('a[data-toggle=tab]').each(function(){
      if(this.innerText === name){
         $(this).hide();
      }
   });
}

This time we are looking to hide a tab, rather than activate it. The reason for this is a scenario where the service request is NOT a project type so we want to hide the project tab. We do this by passing in the name of the tab we want to hide along with the form that contains that tab.

You’ll notice that this function works nearly the same as the previous function, though we’ve simplified it a bit and are only checking each of the returned tab elements to see if it is equal to the name we passed. If it is then we hide the tab from view, and if not it simply ignores the tab.

We’ve nearly completed our solution at this point, but we need to identify how to properly load the code and how to activate it. The following code will control our two functions on form load for the service request workitem forms.

/* Service Request Tasks */
app.custom.formTasks.add('ServiceRequest', null, function(formObj, viewModel){
   formObj.boundReady( function () {
      if(viewModel.TemplateId == 'project') {
         fn_ShowTab("PROJECT", formObj)
      }else{
         fn_HideTab("PROJECT", formObj)
      }
   });
});

This code starts by using a custom add function that is included in the portal to add a custom task to the service request form.

The second line is designed to run the function it contains only when all of the elements of the form has been loaded. This makes sure that all of the elements are available within the page prior to running the function.

Finally, when the function is run we check the TemplateId and and if it matches we run the fn_ShowTab for the PROJECT tab, and if not then we run the fn_HideTab for the PROJECT tab.

That’s all there is to it. We can add additional statements to look for tabs with other names in order to hide or show those tabs as well for other types of requests. The overhead here is pretty minimal since most of the data is already contained in the viewmodel for the object already, and all we are adding is a few additional lines of JSON code.

That being said, be reasonable. A large number (10+?) could possibly have a performance impact. Underneath that number, I don’t believe it would even be noticeable.

In our next installment we will focus on how we can modify the XML of a ServiceRequest template to include a TemplateId, which it does not by default nor does it display the field in the forms of the console.

5 thoughts on “Cireson Portal: Dynamic Forms by Template ID, Part 2

  1. Hi, great post! Im trying to get it to work at my end, but run into some issues. So I hope you can help me out.. Probably a minor issue.

    Thanks in advance!!

    Im trying to hide a tab (multiple tabs later) based on a boolean field being true/checked.

    app.custom.formTasks.add(‘ChangeRequest’, null, function (formObj, viewModel) {
    formObj.boundReady(function () {
    if(viewModel.customfield01==’true’){
    fn_HideTab(“TAB01”, formObj)
    }
    });
    });

    function fn_HideTab(name,form){
    $(‘a[data-toggle=tab]’).each(function(){
    if(this.innerText===name){
    $(this).hide()
    }
    });
    };

    Like

    1. Hey Paul, thanks for your question. Have you checked to see if the value for the field comes across as a bool (true/false) or as a string ‘true’. Basically, you’ll want to use the following if it’s a true boolean:

      viewModel.customField01 === true

      rather than

      viewModel.customField01 === ‘true’

      For a true comparison in javascript you should also use === rather than == whenever possible.

      Like

  2. Hi Seth,
    Can you please let me know how we can modify the XML of a ServiceRequest template to include a TemplateId.

    I am trying to hide tab by following your article, rest of the things are working except template ID is not always null.

    Like

Leave a comment