BackPrevious Page Next PageNext

Using Customized Controls in Tables

Defining a customized control

Managing customized controls

Sample of customized control contents

Customized control is a user defined web action dialog for performing sorting and filtering operations. It works only in page report tables that are created using query resources. You can define the size, position, and contents of a customized control, make it triggered from an object in a page report table, publish the report to JReport Server, then at runtime end users can trigger the customized control which is shown as a dialog to perform the specified web actions.

In JReport Designer the report designer can store the definition of a customized control into a file with the extension .wctrl to the customized control library which is the Customized Control folder under the installation root. JReport Server saves customized controls in DBMS.

Customized controls do not take part in the report layout and are not exported in the report results.

Defining a customized control

  1. Right-click a column header label or group-by field as the trigger in a page report table, and select Display Type from the shortcut menu.
  2. In the Web Behaviors box of the Display Type dialog, choose an event from the Events column, then click in the Actions column and click Choose button that appears in the text box to display the Web Action List dialog.

    Web Action List

  3. Select Customized Control to create a customized control, or select Customized Control from Lib to reference a customized control file from the library, and then click OK.
  4. Click OK in the Display Type dialog to finish defining the customized control.

At runtime when the specified event occurs on the trigger object in the table, a dialog based on the customized control definition will be displayed. End users can use it to perform the defined web actions.

Managing customized controls

With the Manage Customized Controls dialog you can manage the customized control files saved in the customized control library as follows (to open the dialog, click Report > Manage Customized Controls).

Manage Customized Controls

Sample of customized control contents

The contents of customized control is HTML fragment and should be plain text that is children DOM element of HTML Body. You can use web action APIs in the HTML fragment. For details about the APIs, access RptComponent.js in the <server_install_root>\public_html\webos\jsvm\src\com\jinfonet\api folder.

For example, suppose the contents of a customized control is defined like this:

<style>
#plugin {
background-color: gray;
}

#plugin td {
background-color: white;
}

.item--available {
}

.item--unavailable{
color: #CCCCCC;
}

</style>
<table id="plugin" cellspacing="1px" style="margin:0px;width:100%;height:300px;border:1px solid silver;background-color:;">
<tr style="height:30px;"><td>
<table style="text-align:center;width:100%;background-color:;">
<tr>
<td><button id="btnSortA" onclick="this.doSort('Ascending')">Ascending</button></td>
<td style="border-left:1px solid gray;"><button id="btnSortD" onclick="this.doSort('Descending')">Descending</button></td>
</tr>
</table>
</td></tr>
<tr style="height:25px;"><td style="background-color:#cccccc;padding:3px;">
<input id="searchbox" style="width:85%;margin-right:3px;" type="text" onkeyup="this.search(e)"/>
<div style="width:10px;height:19px;float:right;cursor:pointer;"
onclick="this.clearSearch()">x</div>
</td></tr>
<tr style="height:150px;"><td>
<div id="fc-values" onclick="this.selectValue(e)" style="width:100%;height:150px;overflow:auto;"></div>
</td></tr>
<tr style="height:30px;">
<td style="background-color:#cccccc;"><button onclick="this.doFilter()">Apply</button><button onclick="this.clear()">Clear</button></td>
</tr>
</table>

<script type="text/javascript">


var comp; // Data container
var field; // DBField
var filter;

var _onGetDataContainer = function(msg){
var result = msg.result;
if(result.err == 0){
comp = result.obj.comp;
if(!comp) return;
comp.getAssocDBField(context.dsid, _onGetDBField);
}else{
System.err.println(result.msg);
throw new Error(result.msg);
}
}.$bind(this);

var _onGetDBField = function(msg){
var result = msg.result;
if(result.err == 0){
field = result.obj.field;
// To enable sort
Report.getFilterCtrl(field, comp, _onGetFilterCtrl);
}else{
System.err.println(result.msg);
throw new Error(result.msg);
}
}.$bind(this);

var _onGetFilterCtrl = function(msg){
var result = msg.result;
if(result.err == 0){
filter = result.obj.ctrl;
if(!filter) return;
// To enable filter
_renderValues.call(this, filter);
}else{
System.err.println(result.msg);
throw new Error(result.msg);
}
}.$bind(this);

var _canSort = function(){
var b = !!comp && !!field;
return b ? comp.isSortable() : false;
};

var _canFilter = function(){
var b = !!comp && !!field && !!filter
return b ? comp.isFilterable() : false;
};

var _renderValues = function(filter, values){
var td = document.getElementById("fc-values"),
i, len, val, item, buf, showAll;

showAll = !values;
values = values || filter.getAllValues();
td.innerHTML = "";
var isAll = filter.isAllSelected();
for(i=showAll ? -1:0, len=values.length; i<len; i++){
val = i < 0 ? {disp:"All", real:"__ALL__", selected:isAll, available:true} :
values[i];
item = document.createElement("LI");
item.className = val.available ? "item--available" : "item--unavailable";
buf = ["<input type='checkbox' id='fc-index-",i,"' "];
buf.push("value=\"", val.real, "\"");
if(val.selected){
buf.push("checked");
}
buf.push("/>", val.disp);
item.innerHTML = buf.join("");
td.appendChild(item);
}
};

this.doSort = function(type){
if(!_canSort()) return;
comp.sort(field, type);
};

this.selectValue = function(e){
e = e || window.event;
var ele = e.srcElement||e.target, key, checked;
if(ele.tagName != "INPUT") return;
key = ele.value;
checked = ele.checked;
if("__ALL__" === key){
filter.selectAll(checked);
_renderValues.call(this, filter);
}else{
filter.select(key, checked);

// The element for "All" should be updated checked status.
ele = document.getElementById("fc-index--1");
if(filter.isAllSelected()){
ele.checked = true;
}else{
ele.checked = false;
}
}
};

this.doFilter = function(){
if(!_canFilter()) return;
filter.applyFilter();
this.hide();
};

this.clear = function(){
if(!filter) return;
filter.clearSelects();
_renderValues.call(this, filter);
};

this.search = function(e){
if(!filter) return;
e = e || window.event;
var ele = e.srcElement||e.target, value = ele.value, values;
if(value){
values = filter.search(value);
}
_renderValues.call(this, filter, values);
};

this.clearSearch = function(){
document.getElementById("searchbox").value="";
if(!filter) return;
_renderValues.call(this, filter);
};

Report.getDataContainerBy(context.dsid, _onGetDataContainer);

</script>

Suppose that the trigger object is a group-by field Region, at runtime the customized control dialog looks like as follows:

BackPrevious Page Next PageNext