Apex 5.1: Interactive Grids – How to customize toolbar buttons

Introduction

I wanted to slightly change the toolbar buttons in some Interactive Grid. Since in my application all buttons have an icon, I wanted to use the same icon also for IG buttons, especially for actions like “Save” or “Add row”.

What helped me were John Snyders excellent postings “How to hack Apex Interactive Grids”. In this specific case I mostly referred to the second part of the series.

But there were some things that aren’t explained and I needed to figure them out myself.

Toolbars – before and after

The users were used how the buttons looked like in the previous Tabular Form.

Tabular Form
toolbar_tab_form

There are 4 buttons

  • Cancel: go back to previous page
  • Delete: to delete the marked rows
  • Save: To save the current changes
  • Add Row: to insert a new record

The buttons were using the template type “Primary”, that is why they are blue.

Default Interactive Grid
IG_modify_toolbar_default_IG

The “Save” button was already added declarativly, by setting the property in the Attributes/toolbar section of the IG.

The “Add Row” button is created as soon as we allow to Edit.
Attributes/Edit/Allowed Operations/Add Row

As we can see, the “Cancel” button and the “Delete” button are missing. But more importantly, the buttons have no icons and are missing the color.

Customize Interactive Grid

Here is how to change that. I’m not showing how to add the cancel button. This can easily be positioned somehwere else, like in the region header. But the Delete button needs to be added close to the add button. And the visualization of the buttons should match with the rest of the application.

First give the grid a static ID. Here I use “IG_MYGRID”.

Adding the delete button

In Apex 5.1 many objects now have an “advanced/javascript code” property. This is incredibly useful. It is a kind of hook to add additional features programatically.

For an Interactive Grid we can use it to customize the grid further.

We first find our IG and its toolbar object. The toolbar consists of several toolbar groups. They are separated by thin vertical lines. The group “actions3” holds currently only the “Add Row” button. Here we want to add the “Delete” button too.

function(config) {
    let $ = apex.jQuery,
        toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(), // copy the whole toolbar
        toolbarGroup = toolbarData.toolbarFind("actions3"); // this is the group with the action=add row

    // add a new "delete" button
    toolbarGroup.controls.push({type: "BUTTON",
                                action: "selection-delete"
                               });

    //store the config
    config.toolbarData = toolbarData;
    return config;
}

And the result:

IG_modify_toolbar_with_delete_button

The button is there – that’s good. But it does look kind of ugly.
Not quite what we want yet.

We have to understand that an IG provides several actions. Here we used the “delete-selection” action. The actions already have several properties, like an icon. We can overwrite those properties for each visual component that is used to represent that action. In our case the toolbar button.

The trashcan icon might look better in your case, it depends on template/theme styling. In my case it comes with a slightly darker background. The same happens for the normal save icon (icon-ig-save).

Add and change the icons

Let’s add an icon also for the “Save” and the “Add Row” buttons.

Using the toolbarFind Method allows us, to identify the two new existing buttons. Check John Snyders blog to learn more about the toolbarFind method. It is very useful.

function(config) {
    let $ = apex.jQuery,
        toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(), // copy the whole toolbar
        toolbarGroup = toolbarData.toolbarFind("actions3"); // this is the group with the action=add row
        addrowAction = toolbarData.toolbarFind("selection-add-row"), //add row button
        saveAction = toolbarData.toolbarFind("save"); // Save button

    // add a new "delete" button
    toolbarGroup.controls.push({type: "BUTTON",
                                action: "selection-delete",
                                icon: "icon-ig-delete", // alternative FontAwesome icon: "fa fa-trash",
                                iconBeforeLabel: true,
                                hot: true
                               });

    
    // manipulate the buttons
    addrowAction.icon = "icon-ig-add-row"; // alternative font awesome icon: "fa fa-plus";
    addrowAction.iconBeforeLabel = true;
    addrowAction.hot = true;

    saveAction.iconBeforeLabel = true;
    saveAction.icon ="icon-ig-save-as"; // list of alternative grid icons (Font Apex):icon-ig-save,icon-irr-saved-report
    //saveAction.icon ="fa fa-save"; // list of alternative font awesome icons: fa-save,fa-check
    saveAction.hot = true;

    
    //store the config
    config.toolbarData = toolbarData;
    return config;
}

Result
IG_modify_toolbar_custom_with_icons

It is still not perfect. The “Save” and the “Add Row” buttons do have an icon now and the icon is positioned before the label. Still the icon for the “Delete” looks ugly.

I also set all buttons to “hot=true”. The save button already has that as default. Why to do so is explained in the next “css” section.

IG_modify_toolbar_hot_as_Primary

Styling the toolbar buttons with css

Instead of the normal grid icons I wanted to use FontApex or FontAwesome icons.
You have to experiment a little what works in your specific case.

The application where I added this grid, still uses FontAwesome. The users unfortunatly decided against switching to FontApex. They were used to the older items, and didn’t like how the new font looks in the menu. I sometimes regret a little that I gave them this choice. FontApex is the much better option, especially because of the modifiers that can be added. Check the Universal Theme template application for examples of that.

The problem in the Interactive Grid is, that the grid icons are added with a class a-icon which in turn is fixed to FontApex. This creates two additional problems. Since I didn’t use FontApex other icons where not included, only the ones that the grid provides. But I wanted the buttons to look like all other buttons in the application, including the same icon font.

This little css needs to be added. For example to the css inline section of the page.

#IG_MYGRID span.a-Icon.fa, #IG_MYGRID span.a-Icon.fa:before {
  font-family: FontAwesome !important; 
}
#IG_MYGRID_ig_toolbar .a-Button--hot {
    background-color: #0072b9;
    color: #ffffff;
    font-weight: inherit;
}

It overwrites the Font-Family and it uses the class “a-Button–hot” (which is added for “hot” buttons) to style the toolbar buttons blue. Unfortunatly I had to use !important for the Font-Family, because that was already so in the apex core.css.

I also did change the icons on the buttons to reuse the same icons as we had on the tabular form. Check the comments in the previous code, to see which icons are good alternatives if the matching font is available.

Result

IG with custom toolbar buttons

And we did it!

I think there are a few other ways how to reach the same result, but this is what worked well for me.

Other stuff and some comments

Page attribute “reload on Submit”

When moving from a tabular form to an interactive grid we can copy the SELECT statement and create a new IG region with that.

However we must change one page setting. The “Reload on Submit” must be changed from “Always” to “Only for Success” .

Page_Reload_on_Submit

Because of this setting, we can not use a tabular form and a IG on the same page. I would prefer to see both regions as long as the new IG is still in developement. But the setting must be different when showing a tabular form compared to showing an interactive grid.

How to find out about all this

If we want to know what actions are available we have two approaches. One is, find a button/menu point that does the action, inspect the element and look for the data-action attribute. For example this works for the add-row button.

data-action="selection-add-row"

The other way is to use the console and grab all actions.

We open the console on the page with the grid and run the following javascript commands

to show grid actions

apex.region( "IG_MYGRID" ).widget().interactiveGrid( "getActions" ).list()

or alternativly

apex.region("IG_MYGRID").widget().interactiveGrid("getActions").list().forEach(function(a) { console.log("Action Label: " + a.label + ", Name: " + a.name + (a.choice !== undefined ? ", Choice: " + a.choice : "") ); });

to show row actions

apex.region("IG_MYGRID").widget().interactiveGrid("getViews").grid.rowActionMenu$.menu("option")

Then check the object in the console to see what actions are possible, how they are named and which properties they have.