Add tabs to Catalog Item form

Dazler
Mega Sage

Hi,

 

I have a catalog item form that is rather large in variables.  I use containers to clean it a little, but it would look better and more presentable in tabs.

 

I found this article, https://www.servicenow.com/community/developer-articles/how-to-create-a-tabbed-catalog-item-in-servi....  But, I don't want to have to adjust the OOB widget for SC Catalog Item.  

 

I found another article that shows how to create this same effect using a widget within a Custom variable and ui policies.

https://www.servicenowelite.com/blog/2019/11/20/catalog-item-sections


But I am not sure how I can accommodate for mandatory fields.  Especially on the tabs.  

 

Has anyone created a tabbed version on the catalog item similiar to the second article?  

1 ACCEPTED SOLUTION

@Dazler- With the second option you posted only one widget is needed. The widget is used to control which "tab" is selected. All the variables are created normally within the record producer thus allowing you to use UI policies and/or Client scripts as you would normally. (depending on requirements you might need to get a little creative)

The basic idea behind it is that you start with hiding all the variables.

The current_section variable holds the index number of the tab that would be selected; default first tab

The widget that holds the tab selectors populates the hidden current_section variable with the corresponding tab number

A Client script is used to show/hide variables based on the value in current_section (tab index number)

I'll add some screenshots of a mock up I did that includes using a variable that is mandatory in it's variable setup and a variable that is made mandatory via a UI policy based on a variable value that is in a different tab.

 

In my mock I changed some things to make it a little more clear (I hope) than what is presented in the link you posted.

Record Producer Variable setup:

record_producer_variable_setup.png

 

Catalog Client Script setup:

client_scripts.png

 

Client Script: Initial Display

//Initial Display OnLoad 
function onLoad() {
    g_form.setDisplay('variable1_tab1', true);
    g_form.setDisplay('variable2_tab1', true);
}

 

Client Script: Variable Controller

//Variable Controller OnChange  (current_section)
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }

    if (newValue == '0' || newValue == '1') {
       //display variables for tab 1
        g_form.setDisplay('variable1_tab1', true);
        g_form.setDisplay('variable2_tab1', true);

        //variables that should not dipslay on tab 1
        g_form.setDisplay('variable1_tab2', false);
        g_form.setDisplay('variable2_tab2', false);
    }

    if (newValue == '2') {
       //display variables for tab 2
        g_form.setDisplay('variable1_tab2', true);
        g_form.setDisplay('variable2_tab2', true);

       //variables that should not display on tab 2
        g_form.setDisplay('variable1_tab1', false);
        g_form.setDisplay('variable2_tab1', false);
    }

}

 

UI Policies:

ui_policies.pngPolicy setup: (Makes variable 2 on tab 2 mandatory based on variable 2 tab 1 value)

ui_policy_setup.png

 

Variable with type Custom holding the custom widget to control the tabs

type_custom_variable.png

 

For the widget I didn't get fancy. I simply used what is already in Service Portal. But below is the widget setup.

Body HTML Template

<div>
  <button ng-click="setTabIndex('1',$event)" class="btn btn-primary" data-tab-index="1">Tab 1</button>
  <button ng-click="setTabIndex('2', $event)" class="btn btn-default" data-tab-index="2">Tab 2</button>
</div>

 

Client Controller

api.controller = function($scope) {
    /* widget controller */
    var c = this;

	//g_form is avaiable via the page from $scope. Making it shorter here.
    var gform = $scope.page.g_form;

    $scope.setTabIndex = function(index, $event) {
        var oldValue = gform.getValue('current_section');
        if (index == '2') {
            mandatoryCheck('variable2_tab1', oldValue, index, $event);
            return;
        }

        gform.setValue('current_section', index);
        $event.target.classList.remove('btn-default');
        $event.target.classList.add('btn-primary');
		setActiveButton();
    }

    function setActiveButton(){
		var activeTab = gform.getValue('current_section');
		$('[data-tab-index="' + activeTab + '"]').removeClass('btn-default').addClass('btn-primary');

		$('[data-tab-index]').filter(function(){
			return $(this).attr('data-tab-index') != activeTab;
		}).removeClass('btn-primary').addClass('btn-default');

	}

    function mandatoryCheck(variableName, oldValue, newValue, $event) {
        if (gform.isMandatory(variableName) && gform.getValue(variableName) == "") {
            gform.showErrorBox(variableName, "Populate Mandatory field before moving on");
            gform.setValue('current_section', oldValue)
            return;
        }

        gform.setValue('current_section', newValue);
        $event.target.classList.remove('btn-default');
        $event.target.classList.add('btn-primary');
		setActiveButton();
    }

};

 

Again, I didn't get fancy with the code. It's simple so that it should be clear. It could be more optimized I'm sure but I'm sure you have specific requirements and if you use this it would be up to you to take the concept in modify to your needs.

 

Here is a working example of the functionality:

https://youtu.be/6b0sK16li6o

 

View solution in original post

Reply to a ServiceNow Community question: Add tabs to Catalog Item form https://www.servicenow.com/community/developer-forum/add-tabs-to-catalog-item-form/m-p/2603033#M1012488
17 REPLIES 17

Yes, after keeping "Clear the variable value" to false, the issue has been resolved.

Thank you for your help.

-abrouf

Hi @ChisBurks,

It works, thank you. Could you please guide me I am trying to add "Next" button to the form to go from one tab to another? Your input is greatly appreciated.

Thank you.

-abrouf

I only made four tabs here but the concept is the same for six or more. Here are the four UI Policies

ChrisBurks_0-1732757823741.png

 

Here is policy number one. If the tab_index is equal to 1 make the visibility for the item for tab one true and the rest false.

ChrisBurks_1-1732757914231.png

 

Here is policy two basically doing the same thing except the value is 2 and the variable that should show on tab two, its visibility is true and the rest false.

ChrisBurks_2-1732757975572.png

 

And policy three the same. Item(s) visibility for tab 3 should be true and the rest false.

ChrisBurks_4-1732758421177.png

Note: All of them Reverse if false is unchecked because there is more than just two scenarios.

 

 

tabbed_sc_item.gif

 

Also note that this can be done with just hiding and showing containers instead of messing with all the variables you would just control the visibility of the containers.

 

 

Amit Gujarathi
Giga Sage
Giga Sage

HI @Dazler ,
I trust you are doing great.

To create a tabbed version of the catalog item form while considering mandatory fields, you can follow the steps outlined below:

  1. Create a custom variable set for each tab you want to display. Each variable set will contain the variables relevant to that tab.

  2. Add a container widget for each tab in the catalog item form. This will serve as the placeholder for the variables within each tab.

  3. Within each container, add a custom HTML widget. This widget will contain the UI policies and client scripts necessary to control the visibility and mandatory nature of the variables within the tab.

  4. Configure UI policies for each variable within the custom HTML widget. These policies will determine when a variable should be visible or mandatory based on user input.

  5. Use client scripts within the custom HTML widget to handle the logic and enforce mandatory fields when necessary.

<!-- Container for Tab 1 -->
<div class="tab">
    <h2>Tab 1</h2>
    <widget id="variable_set_1_widget" ui_script="variable_set_1_ui_script" />
</div>

<!-- Container for Tab 2 -->
<div class="tab">
    <h2>Tab 2</h2>
    <widget id="variable_set_2_widget" ui_script="variable_set_2_ui_script" />
</div>

<!-- Container for Tab 3 -->
<div class="tab">
    <h2>Tab 3</h2>
    <widget id="variable_set_3_widget" ui_script="variable_set_3_ui_script" />
</div>

Was this answer helpful?


Please consider marking it correct or helpful.


Your feedback helps us improve!


Thank you!


Regards,


Amit Gujrathi



Hi @Amit Gujarathi,

 

I am doing well.  Thank you for asking.  Hope all is well with you!

 

I am a little lost, in #3 you said to "Within each container, add a custom HTML widget.".  So if I had 3 tabs needed, then I would have to create 3 different widgets for each tab.  Or is it just 1 widget?

 

Also, how would I configure UI policies and clients scripts within the HTML widget?  If you have an example for me to view, that would be great.