Currently JReport enables customizing a dialog to perform web actions such as sorting and filtering in a table of a page report at runtime, by using customized controls.
A customized control is a user defined web action dialog containing normal web controls that can process actions. The report designer first defines a customized control to be triggered from a component in a page report table in JReport Designer and then publish the report to JReport Server. Next the server end users can trigger the customized control which is shown as a dialog to perform web action as defined in the report.
In JReport Designer, you can store the properties 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.
that appears in the text box.<server_install_root>\public_html\webos\doc folder. There is a sample of the contents provided in the Sample of customized control contents section at the end of the doc.Next publish the report to JReport Server. Run the report on the server, click the triggered column header label, a dialog will be displayed for performing web actions.
You can manage the properties of a customized control and the customized control files in the customized control library using the Customized Control Manager.
To open the Customized Control Manager, click Edit > Customized Control Manager on the menu bar. See the manager.
In the Customized Control Manager, you can perform the following:
Creating a new customized control file
Click the
button, provide a name to the new file in the New Customized Control File dialog, and then define the customized control properties in the Customized Control – Web Action Builder dialog.
Editing a customized control file
Right-click the file and select Edit from the shortcut menu. Then modify the customized control properties in the Customized Control – Web Action Builder dialog.
Renaming a customized control file
Right-click the file and select Rename from the shortcut menu. Input a new name and then click outside of the name area to accept the change.
Creating a copy of a customized control file
Right-click the file and select Duplicate from the shortcut menu. A copy will be created and listed in the manager. You can then change the name of the copy file and the properties of the customized control.
Removing a customized control file
Select the file and click
. Or right-click the file and select Delete from the shortcut menu.
Sorting the customized control files
By default the customized control files are listed in the ascending order according to their names. Click
and the files will be in the descending order. Next you can click
to change the order back to ascending.
Note that the descending order will not be remembered after you click OK and exit the dialog. The next time you access the dialog it is always the ascending order.
Copy all the following codes as the contents of a customized control:
<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; // db field
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;
// TODO 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;
// TODO 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>
The dialog looks like as follows:
|
| ||
|
x
| ||