Highlight the active/current (pressed) button html by default

babarat1
Tera Contributor

Hi All, this is for Service Portal.

I have 2 buttons Active and Closed

I want the Active button to be highlighted/selected by default on load, however when closed button is selected the highlight and focus should change to closed and active should go back to primary. I tried the below code but it does not keep the active button highlighted/selected

 

 

 

<div class="pull-right newButtons">
    <button name="Active" role="link" type="button" class="btn btn-primary btn-sm m-l-xs" ng-click="activeRecord()" aria-label="${Active records}">${Active}</button>
    <button name="Closed" role="link" type="button" class="btn btn-primary btn-sm m-l-xs" ng-click="ClosedRecord()" aria-label="${Closed records}">${Closed}</button>
  </div> 

 

 

 

Client

 

 

 

.newButtons{
  padding-top: 13px;
  padding-right: 10px;   
}

.btn-primary:hover, .btn-primary:active, .btn-primary:focus {
  color: #ffffff !important;
  background-color: #ff4d4d !important;
}

 

 

@Ankur Bawiskar @Saurav9 @Mohith Devatte @Mark Stanger @Gunjan Kiratkar @Mike_R 

3 REPLIES 3

Robert Smith
Tera Expert

The :active selector is only used while the button is being clicked, and the :focus selector is used while the element is being focused upon (like after the click). Although, the focus will leave the button once something else is clicked on within the browser. 

So you could create another class in your CSS like so: 

 

 

 

.btn-primary:hover,
.btn-primary.btn-is-active{
  color: #ffffff !important;
  background-color: #ff4d4d !important;
}

 

 

 

Then you can use Javascript to grab the event.target (button clicked). Look for the parent element that contain both of your buttons, then remove the class you have added before from the children. Finally, you can then add your class back to your target element that was clicked. 

 

HTML Example: 

 

 

<div>
<!-- =============================================
    Take note that I added an ID attribute to the parent element 
    and also added $event as parameters to the methods you provided
    in your code. 

    I also added the new class that has been created so the button 
    will present itself as "active" onload of your page. 
================================================-->
<div id="new-button-wrapper" class="pull-right newButtons">
  
    <button name="Active" role="link" type="button" 
            class="btn btn-primary btn-is-active btn-sm m-l-xs" 
            ng-click="activeRecord($event)" 
            aria-label="${Active records}">${Active}</button>
  
    <button name="Closed" role="link" type="button" 
            class="btn btn-primary btn-sm m-l-xs" 
            ng-click="ClosedRecord($event)" 
            aria-label="${Closed records}">${Closed}</button>
  </div> 
</div>

 

 

 

Javascript Example: 

 

 

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


	function setClassOnActiveButton (e){
		// get parent element of child on click
		var poppa = $(e.target).parent()[0].id;
		// grab all the children and remove the class
		var children = $('#'+poppa).children();
		for(var i=0; i < children.length; i++){
			children[i].classList.remove('btn-is-active');
		}
		// add the class back to the target child element
		$(e.target).addClass('btn-is-active');
	}
	
	$scope.activeRecord = function(e){
		console.log('active');
		setClassOnActiveButton(e)
		// other code here
	}
	
	$scope.ClosedRecord = function(e){
		console.log('closed');
		setClassOnActiveButton(e)
		// other code here
	}
};

 

 

 

 

Hi Robert, Thanks for the reply I had been trying the same but it didn't work for some reason> I think there's some mistake from my side. Hereby pasting all server and client scripts

 

@Robert Smith 

HTML

 

 

<div>
<div id="new-button-wrapper" class="pull-right newButtons">
  
    <button name="Active" role="link" type="button" 
            class="btn btn-primary btn-is-active btn-sm m-l-xs" 
            ng-click="activeRecord($event)" 
            aria-label="${Active records}">${Active}</button>
  
    <button name="Closed" role="link" type="button" 
            class="btn btn-primary btn-sm m-l-xs" 
            ng-click="ClosedRecord($event)" 
            aria-label="${Closed records}">${Closed}</button>
</div> 
</div>

 

 

css

 

 

.newButtons{
  padding-top: 13px;
  padding-right: 10px;   
}

.btn-primary:hover,
.btn-primary.btn-is-active{
  color: #ffffff !important;
  background-color: #ff4d4d !important;
}





 

 

Server

 

 

(function(){
	/*  "use strict"; - linter issues */
	// populate the 'data' object
	var sp_page = $sp.getValue('sp_page');
	var pageGR = new GlideRecord('sp_page');
	pageGR.get(sp_page);
	data.page_id = pageGR.getValue("id");
	$sp.getValues(data);
	if (data.field_list) {
		data.fields_array = data.field_list.split(',');
	} else {
		data.field_list = $sp.getListColumns(data.table);
	}

	if (input) {
		data.p = input.p;
		data.o = input.o;
		data.d = input.d;
		data.q = input.q;
	}
	data.p = data.p || 1;
	data.o = data.o || $sp.getValue('order_by');
	data.d = data.d || $sp.getValue('order_direction');

	data.page_index = (data.p - 1);
	data.window_size = $sp.getValue('maximum_entries') || 10;
	data.window_start  = (data.page_index * data.window_size);
	data.window_end = (((data.page_index + 1) * data.window_size));
	data.filter = $sp.getValue("filter");

	var gr = new GlideRecordSecure(data.table);
	if (!gr.isValid()) {
		data.invalid_table = true;
		data.table_label = data.table;
		return;
	}
	data.table_label = gr.getLabel();

	/*options.table = data.table;
	options.fields = data.field_list;
	options.o=data.o;
	options.d= data.d;
	options.filter=data.filter;
	options.window_size=data.window_size;
	options.view = data.view;
	options.useInstanceTitle = true; // to make sure Data Table widget uses headerTitle always
	options.headerTitle = options.title;
	options.show_breadcrumbs=true;
	options.enable_filter=true;
	data.dataTableWidget = $sp.getWidget('copy_of_data_table_widget_2', options);
	*/


    var pageid = $sp.getParameter("id"); 

	var showBreadcrumbs = pageid == 'abss_all_tickets' ? true : false; //If pageid is abss then it is set to true, else false
	var activeFilter = "active=true";
	var widgetParams = {
		table: data.table, 
		fields: data.field_list,
		o: data.o,
		d: data.d,
		filter: activeFilter,
		window_size: data.window_size,
		view: 'sp',
		title: options.title,
		show_breadcrumbs: showBreadcrumbs,
		enable_filter:true,
		show_keywords: true
	};
	data.dataTableWidget = $sp.getWidget('copy_of_data_table_widget_2', widgetParams);
	//data.dataTableWidget = $sp.getWidget('widget-data-table', widgetParams);
	
})();

 

 

Client

 

 

function ($scope, $location, $rootScope, spUtil, $interpolate, $window) {
$scope.$on('data_table.click', function(e, parms){
var p = $scope.data.page_id || 'form';
var s = {id: p, table: parms.table, sys_id: parms.sys_id, view: 'sp'};
$location.search(s);
});

$scope.activeRecord = function(){
$scope.$broadcast("data_table.setFilter", "active=true");
}

$scope.ClosedRecord = function(){
$scope.$broadcast("data_table.setFilter", "active=false");
}

this.data.filterText = "";
this.showFilter = false;

this.onClick = function($event, item, url, action) {
$event.stopPropagation();
$event.preventDefault();
if (typeof url == "string") {
	var urlExp = $interpolate(url);
	url = urlExp(item);
	$location.url(url);
} else if (url && typeof url == "object") {
	var newURL = $location.path() + "?id=" + url.id + "&table=" + url.table + "&sys_id=" + url.sys_id + "&view=" + url.view;
	$window.open(newURL,"_blank");
				
} else {
	var evt = {};
	evt.url = url;
	evt.table = item.className;
	evt.sys_id = item.sys_id;
	evt.record = item;
	evt.rectangle_id = c.options.sys_id;
	evt.action = action;
	// put out the selection with simple list "sl_" prefix
	$location.search('sl_sys_id', evt.sys_id);
	$location.search('sl_table', evt.table);
	$location.search('spa', 1); // spa means "I've got this"
	$rootScope.$broadcast('$sp.list.click', evt);
}
};

	
function setClassOnActiveButton (e){
// get parent element of child on click
var poppa = $(e.target).parent()[0].id;
// grab all the children and remove the class
var children = $('#'+poppa).children();
for(var i=0; i < children.length; i++){
	children[i].classList.remove('btn-is-active');
}
// add the class back to the target child element
$(event.target).addClass('btn-is-active');
}

$scope.activeRecord = function(e){
console.log('active');
setClassOnActiveButton(e)
$scope.$broadcast("data_table.setFilter", "active=true");
}

$scope.ClosedRecord = function(e){
console.log('closed');
setClassOnActiveButton(e)
$scope.$broadcast("data_table.setFilter", "active=false");
}
}	

 

 

 

@babarat1 the code piece I provided should only apply to the cosmetic side of the widget, so we shouldn't have to worry about the server side piece unless it is throwing an error in the console trying to read something from the object the server provides. 

 

I noticed in your script you have the methods declared in the upper portion and also my addition in the lower portion. This shouldn't matter I wouldn't think since the lower portion is overwriting them but probably best to remove those.  Also, I found a typo in my Javascript and edited my response. Please update the

$(event.target).addClass('btn-is-active');

to

$(e.target).addClass('btn-is-active');

If you are still have issues please look for any errors in the console to see if there is something breaking before it makes the change of adding the class. 

 

If you find any errors related to your script after that please post them.