Intégration
To use BlueIron in SAINET, when declaring a new GridAdvancedFormater
,
set its type
to ‘blueiron’.
<GridAdvancedFormater ID="CHAECH_PRES1_FORMATTER" type="blueiron">
...
</GridAdvancedFormater>
Besides the BlueIron descriptor itself contained in the formatter, SAINET supports also other tags to enhance the rendering (see below).
<GridAdvancedFormater ID="CHAECH_PRES1_FORMATTER" type="blueiron" [multithreading="true"]>
<init>...</init>
<columns>...</column>
<header>...</header>
<footer>...</footer>
<inputs>...</inputs>
<blueiron>...</blueiron>
<handles>...</handles>
</GridAdvancedFormater>
The multithread
attribute allows BlueIron to read the input and process
it with multiple threads (false by default). This is possible if there is
no database access during the processing.
The
In this script, all the datafield values of the HeaderDescriptor will be injected as String. Moreover, the following variables will be declared:
Variable | Description |
---|---|
userSession |
The UserSession. |
grid |
The GridDescriptor that is currently used. |
selector |
The Selector of the GridDescriptor for a quick usage. |
options |
The HeaderDescriptor. |
With this tag, it is possible to dynamically add constraint to the data retrieved from the database (see CHA72):
<init>
selector.addAndWhere("$CHAECH.DATECR_PK <= '" + CHA_LAST_DATE +"'");
if(CHA_SOLDE_PREC == '0') { selector.addAndWhere("$CHAECH.DATECR_PK >= '" + CHA_FIRST_DATE +"'"); }
</init>
It is possible to create new columns in BlueIron, but since they won’t
be attached to any known datafield in SAINET, it is needed to do this
mapping manually. This is done with the
This tag can contain one or many
Name | Type | Description |
---|---|---|
id * |
String | ID of the new column created by BlueIron. This attribute is mandatory. |
format |
String | Defines the format of the output column and will also impact how the data will be displayed. |
width |
Integer or ‘Auto’ | Defines the size of the column. |
datafieldId |
String | Defines the datafield ID to map to. It will be used as fallback if the format or label is not defined. |
label |
String | Defines an i18n String for the label of the column. |
enumName |
String | Defines the EnumName. |
displayCode |
String | TextOnly ,CodeOnly or CodeAndText . Only for enums. |
Here is an exemple used in CHA72:
<columns>
<column id="DATE_DEBUT_PERIODE" format="Date" width="0" />
<column id="DATE_FIN_PERIODE" format="Date" width="0" />
<column id="DATE_ECRITURE_LBL" format="String" width="9" label="FR={Date} DE={Datum}" />
<column id="DATE_ECRITURE_LBL" format="String" width="9" label="FR={Date} DE={Datum}" />
<column id="DISPLAY" format="Boolean" width="0" label="Affiche" />
<column id="QUANTITE" format="Financial" width="10" label="FR={Quantité} DE={Menge}" />
<column id="DEBIT" format="Financial" width="10" label="FR={Débit} DE={Debit}" />
<column id="CREDIT" format="Financial" width="10" label="FR={Crédit} DE={Kredit}" />
<column id="SOLDE" format="Financial" width="10" label="FR={Solde} DE={Saldo}" />
<column id="NB_ROWS" format="Integer" width="0" label="N" />
</columns>
This section allows to declare a header/footer that will be placed on the
top/bottom of the list. The structure is a <table>
but is independant of
the list’s table, however it uses the list’s data for its content. Like a
standard html table, one can declare one or more <tr>
tags in which one
or more <td>
tags can be declared. The same number of <td>
must be
declared in each <tr>
tag !
The <header>
node supports the following attributes:
Name | Description |
---|---|
macroId |
ID of a UNI93 macro. In this case, no <tr> /<td> nodes are expected. |
withinTable |
Defines if the header/footer is embedded in <thread> /<tfoot> or is generated outside the whole <table> . When true , the header/footer will be displayed on all the pages when printing. This value is false by default. |
Supported attributes are for <tr>
and <td>
:
Name | Description |
---|---|
class |
A list of css classes spearated by spaces. Thoses classes has to be declared in UNI_GEN. |
style |
A list of css styles spearated by semicolumns. |
colspan |
Colspan of the cell (only for <td> ). |
The <td>
can contain mixed content which is:
- Simple text.
- Internationalized text with the format
FR={...}
DE={...}
. - Reference to a column id of the list with the format
${columnId}
.
Here is an exemple (still the CHA72):
<header withinTable="true">
<tr>
<td style="width:75px">No Chantier</td>
<td style="width:250px" class="grag">${NO_CHAN}</td>
<td style="width:75px">Période du</td>
<td style="width:250px" class="grag">${DATE_DEBUT_PERIODE}</td>
</tr>
<tr>
<td>Désignation</td>
<td class="grag">${NOM_CHAN}</td>
<td>Période au</td>
<td class="grag">${DATE_FIN_PERIODE}</td>
</tr>
<tr style="height:15px">
<td />
<td />
<td />
<td />
</tr>
</header>
It is also possible to delegate the creation of the header/footer to a velocity macro (UNI93) with the following snippet:
<header macroId="HEADER_MACRO" />
And the corresponding macro in UNI93:
#macro(header_macro)
#set($dossier = $VELOHLP.getEntity("ADRDOS.ID_PK", $ID))
<table>
<tr class="norg">
<td>ID:</td>
<td>$dossier.ID_PK</td>
</tr>
<tr class="norg">
<td>Dossier:</td>
<td>$dossier.DLABEL</td>
</tr>
</table>
#end
All the columns of the breaking row are directly available (for instance $ID
above will point the the ID
column).
In order to genrerate a break, a call to outputRow.breakHeader(boolean)
is necessary. It will
generate a page break before the outputRow
and the latter will be used as source to fill the
header. The boolean of the breakHeader
method defines if the outputRow
must be hidden or not.
It is also possible to use the methods outputRow.pageBreakBefore()
or
outputRow.pageBreakAfter()
if the header/footer don’t need any data
from the inner grid.
It is possible to define extra grid-based inputs in this node to gather other data from the application. Those ids will then referencable in the BlueIron descriptor as source of step.
<inputs>
<grid id="SAL04_N2" selector="FROM $SALEMP WHERE $SALEMP.ID_PK = '101'" />
<grid id="SAL04_N22" gridViewId="SAL04_N2" />
<grid id="SAL04_N3" taskId="SALV4" raw="true" />
</inputs>
All the defined grids will be sequentially filled by calling get[Raw]GridData
before the
BlueIron processing is actually done (hence, they will be filled even if not used).
Here are the attributes of the grid
node:
Name | Type | Description |
---|---|---|
id * |
String | ID of the input. If gridViewId is not defined, this has to be the ID of an existing GridView. |
gridViewId |
String | The GridView ID of the input. If not defined, this will be the id value. |
taskId |
String | The ID of the task to use to fille the GridView. If not defined, then the current task will be used. |
raw |
Boolean | Tells if the getGridData call to fill the GridView must be raw or not. false by default. |
selector |
String | Defines the full selector of the GridView (FROM $<table> WHERE ... ). |
predicate |
String | Defines a single predicate that willbe ORed with all the values. |
There are some special values that can be put in the selector
attribute.
In order to have the same selector as the main grid, use the value sameAsSource
. It is needed that both the
main grid and the extra input grid are based on the same table otherwise error will occur if some datafield don’t exist.
Since the main grid will be filled before all, it is possible to use some special constructs
in the selector of the input grid by using ${<column_id>}
. For instance, it is possible to define
the following input grid:
<grid id="SAL04_N2" selector="FROM $SALEMP WHERE $SALEMP.ID_PK IN (${ID_PK})" />
In the example above, the value ${ID_PK}
will be replaced by a SQL string containing all the values of the
column ID_PK
in the main grid, resulting in something like this: FROM $SALEMP WHERE $SALEMP.ID_PK IN ('100','101','200')
.
The predicate content can only have one single variable. Then the predicate will be repeated for every values in the corresponding column.
<grid id="SAL04_N2" predicate="$SALEMP.ID_PK LIKE '${ID_PK}%'" />
In the example above, the resulting selector will be FROM $SALEMP WHERE (($SALEMP.ID_PK LIKE '05%') OR ($SALEMP.ID_PK LIKE '06%'))
.
Note that, unlike the selector
attribute, the variable value isn’t encapsulated in quotes. The whole
predicate string will be then ANDed with any existing predicates in the grid selector.
This tag will contains the real BlueIron descriptor.
It is not necessary to declare any InputStep because a special GridInputStep based on the GridView will be created with the same ID. Hence the root step must simply declare its source with the ID of the GridView.
<GridView ID="CHAECH_PRES1">
...
</GridView>
<blueiron output="final">
<step id="final" source="CHAECH_PRES1">
...
</step>
</blueiron>
It is also possible to use the generic identifier grid
as the source of
the step. This alias will reference the main GridDescriptor.
Then you will be able to reference a column of the GridView by using its ID.
Handles are intended to be small JavaScripts that are being executed for each outputted row from BlueIron. The goal is to be able to completely customize the output of the list (for instance, setting backgroud color, font size, css style, …).
One or more handle can be defined by the tag handle
with the possible
following attribute:
Name | Type | Description |
---|---|---|
column | String | Column to be referenced by the cell variable. It is possible for multiple handles to point to the same column. |
If the column is not specified in the handle, then there will be no variable available relative to the cell.
The variables below will be defined in the script’s context:
Name | Type | Description |
---|---|---|
row |
Row (BlueIron) | The BlueIron row being currently outputted. |
outputRow |
Row (SAINet) | The SAINet row being currently outputted. This will be generally the variable you’re interested in. |
column |
Column (BlueIron) | The BlueIron column (only if the column attribute is set). |
cell |
Cell (SAINet) | The SAINet Cell (only if the column attribute is set). |
value |
Object | The value of the Cell (only if the column attribute is set). |
rowLevel |
Integer | The level of the row, as defined in BlueIron (see here). |
rowIndex |
Integer | The index of the row, as defined in BlueIron (see here). |
rowTypeIndex |
Integer | The type index of the row, as defined in BlueIron (see here). |
isTitleRow |
Boolean | True if the row is a title row. |
isTotalRow |
Boolean | True if the row is a total row. |
isDataRow |
Boolean | True if the row is a data row. |
options |
Map | Pointer to the options. |
Here are the default handles that are applied:
Property | defaultValue | Description |
---|---|---|
defaultStyles |
true | Applies the default styles ruptitn on title rows and ruptotn on total rows. |
maxLevelDefaultStyles |
3 | Defines the maximum level to apply the styles (the n in ruptitn and ruptotn). Starts from zero. |
removeZeroValues |
true | If a numerical value is zero in the output cell, this value will be replaced by an empty cell. |
maxLevelRemoveZeroValues |
-1 | If removeZeroValues is true, defines the maximum level to apply the styles (see maxLevelDefaultStyles ). Starts from zero. |
styleIfGreaterThanZero |
[null] | Style to apply on numerical values that are greater than zero. The style applies only on the cell. |
styleIfLessThanZero |
[null] | Style to apply on numerical values that are bigger than zero. The style applies only on the cell. |
duplicateKeys |
[null] | Defines a list of key columns to identify duplicates. Constains column IDs, separated by commas. |
duplicateColumns |
[null] | Defines a list of columns where the value should be hidden if the row is identified as duplicate by using the duplicateKeys columns. It is possible to use #asInput or #asOutput . |
mandatoryColumns |
[null] | Defines a list of columns which must contain a value, othwerise the row is removed. |
lenientColumns |
[null] | Defines a list of columns in which at least one of them must contain a value, otherwise the row is removed. |
hideEmptyColumns |
[null] | Defines a list of columns which will be hidden if there is no value in the column at all. |
rawStyleOnTotalRows |
true | Defines the ‘rawNumber’ style on all the cells of a TOTAL row. This is espcially to avoid having a ‘tick’ on a total row cell. |
applyDefault |
true | Applies all the default handles listed above. |
looseColumnSearch |
false | Allow a column to be inexistant when using the duplicateKeys ,duplicateColumns ,mandatoryColumns or leniantColumns attributes. |
Here is an example of handles implementation in CHA72:
<handles applyDefault="false">
<handle column="DATE_ECRITURE_LBL"><![CDATA[if(isTitleRow && rowLevel==0) { outputRow.breakHeader(true); }]]></handle>
<handle column="DATE_ECRITURE_LBL"><![CDATA[if(isTitleRow) { outputRow.addStyle("ruptit"+(rowLevel+1)+"g"); }]]></handle>
<handle column="DATE_ECRITURE_LBL"><![CDATA[if(isTotalRow && rowLevel>0) { outputRow.addStyle("ruptot"+(rowLevel+1)+"d"); cell.addStyle("ruptot"+(rowLevel+1)+"g"); }]]></handle>
<handle column="DATE_ECRITURE_LBL"><![CDATA[if(isTotalRow && rowTypeIndex<=2 && rowLevel==0) { outputRow.addStyle("grad"); cell.addStyle("grag"); }]]></handle>
<handle column="DATE_ECRITURE_LBL"><![CDATA[if(isTotalRow && rowTypeIndex==2 && rowLevel==0) { outputRow.addStyle("ruptot1d"); cell.addStyle("ruptot1g"); }]]></handle>
<handle column="DATE_ECRITURE_LBL"><![CDATA[if(isTotalRow) { cell.setColspan(4); }]]></handle>
<handle column="SOLDE"><![CDATA[if(value!=null && value<0) { cell.addStyle("TXT_F00"); }]]></handle>
<handle column="QUANTITE"><![CDATA[if(value!=null && value<0) { cell.addStyle("TXT_F00"); }]]></handle>
</handles>
SAINet injects new Jexl functions that can be used in BlueIron are listed below.
There are other native functions (such as parse
) also described here.
Function | Return | Description |
---|---|---|
date:addMillis(date) |
Date | Adds one millisecond to date . A new date instance is returned. |
date:addSecond(date) |
Date | Adds one second to date . A new date instance is returned. |
date:addMinute(date) |
Date | Adds one minute to date . A new date instance is returned. |
date:addHour(date) |
Date | Adds one hour to date . A new date instance is returned. |
date:addDay(date) |
Date | Adds one day to date . A new date instance is returned. |
date:addMonth(date) |
Date | Adds one month to date . A new date instance is returned. |
date:addYear(date) |
Date | Adds one year to date . A new date instance is returned. |
Function | Return | Description |
---|---|---|
date:addMillis(date, nb) |
Date | Adds nb milliseconds to date . A new date instance is returned. |
date:addSecond(date, nb) |
Date | Adds nb seconds to date . A new date instance is returned. |
date:addMinute(date, nb) |
Date | Adds nb minutes to date . A new date instance is returned. |
date:addHour(date, nb) |
Date | Adds nb hours to date . A new date instance is returned. |
date:addDay(date, nb) |
Date | Adds nb days to date . A new date instance is returned. |
date:addMonth(date, nb) |
Date | Adds nb months to date . A new date instance is returned. |
date:addYear(date, nb) |
Date | Adds nb years to date . A new date instance is returned. |
Function | Return | Description |
---|---|---|
date:setTime(date, hourOfDay, minute, second) |
Date | Returns a new date with hourOfDay ,minute and second (millis will be zero). The other values are the same as date . |
date:setTime(date, hourOfDay, minute, second, millis) |
Date | Returns a new date with hourOfDay ,minute ,second and millis . The other values are the same as date . |
date:setDate(date, dayOfMonth, month, year) |
Date | Returns a new date with dayOfMonth ,month and year . The other values are the same as date . |
Function | Return | Description |
---|---|---|
date:getDate(year, month, dayOfMonth) |
Date | Returns a new date with year , month and dayOfMonth . |
date:getDateTime(year, month, dayOfMonth, hour, minute, second) |
Date | Returns a new date with year , month ,dayOfMonth ,hour ,minute and second . |
date:date(year, month, dayOfMonth) |
Date | Alias of date:getDate . |
date:date(year, month, dayOfMonth, hour, minute, second) |
Date | Alias of date:getDateTime . |
date:create(year, month, dayOfMonth, hour, minute, second) |
Date | Alias of date:getDateTime . |
date:now() |
Date | Returns a ne date with the current timestamp. |
Function | Return | Description |
---|---|---|
date:startOfDay(date) |
Date | Returns a new date starting at 00:00:00 of the day. |
date:startOfMonth(date) |
Date | Returns a new date starting at 00:00:00 of the first day of the month. |
date:startOfYear(date) |
Date | Returns a new date starting at 00:00:00 of the first day of the year. |
date:endOfDay(date) |
Date | Returns a new date at 23:59:59 of the day. |
date:endOfMonth(date) |
Date | Returns a new date at 23:59:59 of the last day of the month. |
date:endOfYear(date) |
Date | Returns a new date at 23:59:59 of the last day of the year. |
Function | Return | Description |
---|---|---|
date:year(date) |
int | Returns a year of the date . |
date:month(date) |
int | Returns a month of the date . |
date:date(date) |
int | Returns a date (day of month) from date . |
date:dayOfWeek(date) |
int | Returns a day of week from date . |
date:weekOfYear(date) |
int | Returns a week of the year from date . |
date:hour(date) |
int | Returns the hour of the date . |
date:minute(date) |
int | Returns the minute the date . |
date:second(date) |
int | Returns the second of the date . |
date:millis(date) |
int | Returns the millisecond of the date . |
Function | Return | Description |
---|---|---|
date:daysInMonth(year, month) |
int | Returns the number of days in the month of the specified year . |
date:daysInYear(year) |
int | Returns the number of days in the specified year . |
date:weeksInYear(year) |
int | Returns the number of weeks in the specified year . |
Function | Return | Description |
---|---|---|
date:yearsDiff(date1, date2) |
long | Returns the number of years between date1 and date2 . |
date:monthsDiff(date1, date2) |
long | Returns the number of months between date1 and date2 . |
date:daysDiff(date1, date2) |
long | Returns the number of days between date1 and date2 . |
date:hoursDiff(date1, date2) |
long | Returns the number of hours between date1 and date2 . |
date:minutesDiff(date1, date2) |
long | Returns the number of minutes between date1 and date2 . |
date:secondsDiff(date1, date2) |
long | Returns the number of seconds between date1 and date2 . |
date:millisDiff(date1, date2) |
long | Returns the number of milliseconds between date1 and date2 . |
Function | Return | Description |
---|---|---|
date:yearsBetween(date1, date2) |
double | Returns the rest of years between date1 and date2 . |
date:monthsBetween(date1, date2) |
double | Returns the rest of months between date1 and date2 . |
date:daysBetween(date1, date2) |
double | Returns the rest of days between date1 and date2 . |
date:hoursBetween(date1, date2) |
double | Returns the rest of hours between date1 and date2 . |
date:minutesBetween(date1, date2) |
double | Returns the rest of minutes between date1 and date2 . |
date:secondsBetween(date1, date2) |
double | Returns the rest of seconds between date1 and date2 . |
date:millisBetween(date1, date2) |
double | Returns the rest of millis between date1 and date2 . |
Function | Return | Description |
---|---|---|
bd:round(value, unitStr) |
BigDecimal | Returns a new BigDecimal, which is the rounded value with the given unitStr (string unit). |
bd:round(value, unit) |
BigDecimal | Returns a new BigDecimal, which is the rounded value with the given unit . |
bd:round(value, unit, mode) |
BigDecimal | Returns a new BigDecimal, which is the rounded value with the given unit and mode (CEILING, DOWN, FLOOR, HALF_DOWN, HALF_UP, HALF_EVEN, UP). |
Function | Return | Description |
---|---|---|
bd:scale(value, scale) |
BigDecimal | Returns a new BigDecimal, which is the scaled value with the given scale . |
bd:scale(value, scale, mode) |
BigDecimal | Returns a new BigDecimal, which is the scaled value with the given scale and mode (CEILING, DOWN, FLOOR, HALF_DOWN, HALF_UP, HALF_EVEN, UP). |
Function | Return | Description |
---|---|---|
res:getCombo(comboId) |
Map<String,String> | Returns the Combo content of comboId . |
Function | Return | Description |
---|---|---|
header:hasHeader(gridViewId, keyMapping) |
boolean | Returns true if there is a header content. |
header:generate(gridViewId, keyMapping) |
boolean | Generates the header, based on the gridViewId and the keyMapping . |
header:generateAndTagRow(outputRow, gridViewId, keyMapping) |
boolean | Generates the header, based on the gridViewId and the keyMapping . The output row will be tagged with a property ‘sainet_header’ that will be set as the style on the SAINet row. |
The gridViewId
must be declared in the <inputs>
node.
The keyMapping
variable is a list of pairs that is used to find the corresponding header row in the GridView. The first part
of the pair is the column ID in gridViewId
and the second one is its corresponding value.
The outputRow
is the BlueIron output row available in the execution context.
Here is an example:
header:generate("REG05_HEADER", ["ID", NOCPTE])