Tabbed Table Widget for Portal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-15-2017 04:30 AM
Hi All,
We use a couple of simple list widgets on our portal. When you click the view all link it takes you to a new page with a full table view. This the 'Data table from URL definition' widget.
We would like to either amend this widget or create a widget that displays the table but has a tab at the top to change the filter that is used on the table. We would like one tab to show incidents where active = true and the other tab to show incidents where active = false.
Any help on this would be greatly appreciated.
Thanks

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-16-2017 07:26 AM
Hi Sam,
I'm tagging the share widget creator geoffluk. Perhaps he can provide you with a quick answer as I'm not familiar with the widget myself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-17-2017 04:26 PM
Hi Sam,
It sounds like you want to set up something similar to what ServiceNow has in their HI My Issues interface (Incidents, Change Requests, Enhancements, Problems, Community Posts).
To start using the widget, you need to make changes to 3 parts of it:
1. Update the HTML code to display your own tables. So inside the <ul> you need to put in your own <li> for each table you want displayed.
2. For each table widget instance you create (e.g. Data Table w/ Instance) you need to provide an ID. You might need to expose these fields in the Instance Options.
3. In the .click() you need to provide the ID for the switch cases. 1 ID for each case.
For #3 above, when using the switch, the ID should be exactly the same for the case statement as with the hideTables() call. For example, say you have an Incident table with the ID = "table-incident". So in this case you'll need to use
switch(id) {
// the ID of a table
case "table-incident":
hideTables("#table-incident");
break;
}
Please let me know if you have any other questions about the widget!
---------------------------
I created the widget mostly as a guide to building a very basic tabbed interface. The widget takes advantage of the following things:
Bootstrap styling for the tabs: you can use the standard "nav-tabs" or the "pills"
jQuery's .click() action to determine which tab was clicked/tapped and set it to the active one
AngularJS ngShow directive if you need to "filter" the tables by roles or users
And here's the breakdown of the 3 components:
- HTML - obviously this is where the tabs/pills are built. You can add in as many tabs as you would like. The ng-show directive is used to allow the tabs/pills to be shown/hidden based on conditions. You should set up HTML IDs here so that you can target the individual tabs for other use.
- Server Script - No need to user this unless you'd like to limit visibility of the tabs by roles. For example you could have a Change Request tab that is only visible to users with the "change_request" role. In the Server Script you'd set up a condition that checks whether the logged in user has the role, and then set up the ng-show or ng-if in the HTML.
- Client Controller - Here's where most of the work is done. It's broken up into 2 parts: what happens when a tab is "clicked" and a helper function that takes care of hiding all of the tables. The first part is the .click() action that removes the "active" class from all tabs and then sets the active class for the clicked tab. It then goes into the switch to determine which of the tables you now want to display.
As commented in my shared widget on SerivceNow Share, there is a slicker way of hiding the tables than having a very large switch and a helper function for hiding everything. However, I wanted to explicitly build it out very large and primitively so that it could be more adaptable for other people's uses. By using much more simple Javascript logic I hope that novice developers would be able to pick it up and modify for their own use. Basically, I tried to build it out in as many simple steps as could be, so that it can be easily re-used, or at least understood if someone new to scripting were to try and use it. We've streamlined ours much more than what I created for the shared widget, because we have a very narrow use case. I hope that others can take this widget and create some really awesome(r) things with it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-18-2017 03:08 AM
Hi Geoff,
Thanks for the above, apologies for the further questions, and if they seem a but basic, just not used to HTML. This is how I currently have the code:
HTML
<div class="clearfix"></div>
<div id="table-tabs">
<!--ul class="nav nav-tabs nav-justified"-->
<!-- If you prefer to have pills instead of tabs, simply comment out the above <ul> element and uncomment the below <ul> element -->
<ul class="nav nav-tabs nav-pills">
<!-- use the ng-show directive to display or hide tabs based on conditions such as by Role -->
<li ng-show="data.your_condition_here" id="cdl-open-incidents" class="active"><a href="#cdl-open-incidents">Incident</a></li>
<li ng-show="data.your_condition_here" id="cdl-closed-incidents"><a href="#cdl-closed-incidents">Problem</a></li>
</ul>
</div>
Server Script
(function () {
/*
Add any condition you may need. Example could be to check if the user has a specific Role: data.isItilAgent (below)
*/
data.your_condition_here = true;
data.active=true;
//data.isItilAgent = gs.getUser().hasRole('itil');
})();
Client Controller
function ($scope, $sce) {
/**
* This jQuery 'click' action selects the active tab and displays
* the table to be displayed. It also sets the tab as "active" for
* Bootstrap styling.
*
* @param None.
* @return Nothing.
*/
$("#table-tabs ul li").click(function (e) {
e.preventDefault();
// Set the "active" tab for Bootstrap styling
$("#table-tabs ul li").removeClass("active");
$(this).addClass("active");
// Select which table to display
var id = $(this).attr("id");
switch (id) {
// the ID of a table
case "cdl-open-incidents":
hideTables("#cdl-open-incidents");
break;
// the ID of a table
case "cdl-closed-incidents":
hideTables("#cdl-closed-incidents");
break;
}
return false;
});
/**
* This method hides all tables of the specified class,
* and then displays the table that is passed in as
* the parameter.
*
* @param option the name of the table that you want to display,
* as a string. It should be the ID of the table,
e.g. "table-name"
* @return Nothing.
*/
function hideTables(option) {
$(".table-class").hide();
if (option) {
$(option).show();
}
}
}
I get the tabs displaying but not the tables. Any help where I am going wrong is greatly appreciated.
Thanks
Sam
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-22-2017 07:03 AM
Hi Geoff
I have the same issue like Sam.
It looks like it ignores the IDs, the Widget Instances have still have IDs like "xa5075f28db304b0073b773200f9619d5" (not as configured).
I'm on Jakarta Patch 1 Hotfix 1.
Thanks
Marc
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-22-2017 01:36 PM
That ID may belong to the parent, whereas the ID we use in the instances form will appear in the element below the one with the ID = xa5075f28db304b0073b773200f9619d5.
Can you provide a screenshot or code snippet of the rendered HTML?
This is what my resulting HTML looks like:
Note that my ID = x592bc14edb90870020e93ade9d961939 belongs to the DIV outside of the ID = tickets-incident