Customizing the Data Table Widget, Part III

“Many of life’s failures are people who did not realize how close they were to success when they gave up.”
Thomas Alva Edison

In addition to the reference links that I wanted to add to my version of the Data Table widget, I also wanted to add the capability to add buttons or icons to each row for specific actions. This seemed like something that could be accomplished relatively easily, and configured just like the many other options associated with the various flavors the Data Table. My thought was to be able to configure things to look something like this:

Data Table with example button and action icon

For the icons, my plan was to just leverage the Retina Icons that I had stumbled across the other day, and then lift the associated HTML right out of the old snh-form-field tag. But first, I had to come up with a way to pass in all of the information needed to configure each button. There is a way to use a table as a source for complex widget options, but this was just an experiment at this point, so I decided to go the quick and easy way and just pass in a JSON array of button specification objects that would look something like this:

[
  {
    "name": "button",
    "label": "Button",
    "heading": "Button",
    "color": "primary",
    "hint": "Click this button to do something",
    "action": "doSomething"
  },{
    ... etc ...
  }
]

I haven’t worked out all of the details yet, but you get the idea. That’s the basic concept, anyway … all we have to do now is to code it up!

The first order of business is to create the new widget option to hold the button specifications. One quick way to do that is to just edit the Option Schema directly, as it just happens to be a JSON object itself. In fact, there is already one option defined (enable_filter), so it is a simple matter to just use that one as an example and create a second one for our purposes:

[
   {
      "hint":"If enabled, show the list filter in the breadcrumbs of the data table",
      "name":"enable_filter",
      "default_value":"false",
      "section":"Behavior",
      "label":"Enable Filter",
      "type":"boolean"
   },{
      "hint":"A JSON object containing the specification for row-level buttons and action icons",
      "name":"buttons",
      "default_value":"",
      "section":"Behavior",
      "label":"Buttons",
      "type":"String"
   }
]

Once we have updated the Option Schema, editing an instance of the widget will include a place to enter the specifications for any desired buttons. Now we have to add code to the widget’s Server Script to pull in the value of the new option and turn it from a String to an Object. Since there is no guarantee that the instance author will provide a parsable JSON object, we will have to put in a little defensive code to check for a few possibilities.

if (data.buttons) {
	try {
		var buttoninfo = JSON.parse(data.buttons);
		if (Array.isArray(buttoninfo)) {
			data.buttons = buttoninfo;
		} else if (typeof buttoninfo == 'object') {
			data.buttons = [];
			data.buttons[0] = buttoninfo;
		} else {
			gs.error('Invalid buttons option in SNH Data Table widget: ' + data.buttons);
			data.buttons = [];
		}
	} catch (e) {
		gs.error('Unparsable buttons option in SNH Data Table widget: ' + data.buttons);
		data.buttons = [];
	}
} else {
	data.buttons = [];
}

And finally, we have to alter the HTML to include any configured buttons or icons. Modifications will need to be made in two places, one for the column headings and the other for the data columns. Here is what we will add for the column headings:

<th ng-repeat="button in data.buttons" class="text-nowrap center" tabindex="0">
  {{button.heading || button.label}}
</th>

And this is what we will toss in for each row of data:

<td ng-repeat="button in data.buttons" class="text-nowrap center" tabindex="0">
  <a ng-if="!button.icon" href="javascript:void(0)" role="button" class="btn-ref btn btn-{{button.color || 'default'}}" ng-click="buttonclick(button.name, item)" title="{{button.hint}}" data-original-title="{{button.hint}}">{{button.label}}</a>
  <a ng-if="button.icon" href="javascript:void(0)" role="button" class="btn-ref btn btn-{{button.color || 'default'}}" ng-click="buttonclick(button.name, item)" title="{{button.hint}}" data-original-title="{{button.hint}}">
    <span class="icon icon-{{button.icon}}" aria-hidden="true"></span>
    <span class="sr-only">{{button.hint}}</span>
  </a>
</td>

That puts everything on the screen and clickable, but we still some code to perform whatever action each button is intended to perform. That’s a tad bit more complicated, so I think we’ll tackle that the next time out ….

3 thoughts on “Customizing the Data Table Widget, Part III”

  • Hi I am trying to achieve this , does all these modifications go to data table widget?

    i am trying but unable to see the buttons( new to portal)

    • Yes, the modifications are made to the data table widget, but once those have been completed, you also have to use the newly created Buttons option to configure the buttons on your specific instance of the widget (on your specific page). See the sample button configuration JSON object at the beginning of the article. I have just a couple of things more to wrap up on this, after which I will post a complete Update Set. That might be the easier way to get this implemented than to try and make all of the modifications manually.

  • Hi, i cloned data table widget and data table Instance widget. add option schema to both of them , add the server script to data table Instance widget and HTML to data table, is this correct? I am unable to see the buttons yet

Comments are closed.