- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-01-2023 03:15 PM
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?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-04-2023 09:49 AM
@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:
Catalog Client Script setup:
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:
Policy setup: (Makes variable 2 on tab 2 mandatory based on variable 2 tab 1 value)
Variable with type Custom holding the custom widget to control the tabs
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:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-21-2024 03:52 PM
Sounds like the indexes could be mixed up. Are you able to share your setup?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-26-2024 09:03 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-26-2024 07:24 PM
Hi @abrouf
Thanks for the screenshots as it clears up what's going on with your setup. Your setup as far as sections is about the same as mine. Two sections. With two containers you should only have two tabs but you have six tabs.
The concept is that when clicking a tab it changes the current_section variable to hold the value of the selected tab. For example if I click tab 2, current_section's value should be 2.
For the UI Policy, any variable that I want visible when current_section equals 2 should be true and any variable that I don't want visible should be false.
If you want to stick with the UI Policy route with more tabs/sections you'll need more than two UI Policies to accommodate all the variations. Or a script can be used.
The basic concept is the tabs are use to set a value. Based on the value display the appropriate variables and hide the others.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-27-2024 03:21 PM
Hi ChrisBurks,
I have extended the HTML and client controller scripts up to 6 tabs, also created 6 UI policies, also tried with return true i,e current_section is 1, 2,3,4,5,6 for tab 1,2,3,4,5,6 respectively, but all entered data are still disappearing when click on next tab. Any further input is greatly appreciated.
Thank you.
abrouf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-27-2024 05:22 PM
Hi @abrouf
If the data is being cleared after clicking on a different tab and revisiting the tab, then don't set the box to clear the value in the UI Policy.