Helium Advance Training
Plugins
If you want to create custom functionality using TVC/Helium, the recommended approach is to build it as a plugin. It allows your custom code to use many powerful features that are already available in TVC/Helium. Instead of building everything from scratch, you can reuse what TVC/Helium already provides, which makes your development easier and faster.
https://products.technia.com/app/docs/tvc-documentation-2026.1.0/tvc/devdocs/index.html#Plugin
Custom Translations (i18n)
Helium supports both server-side and client-side internationalization
Translation Files Location
server-side: 'src/main/webapp/WEB-INF/classes/tvc-nameStrings_en.properties’
client-side: ‘src/main/webapp/helium/custom/lang/en.json’ or 'src\main\webapp\webapps\HETrueWidget\custom\lang\en.json'
server-side : tvc-nameStrings_en.properties
helium.datatable.toolbar.ExcelExport = Excel plugin
helium.datatable.toolbar.Filter = Filter Pluuginclient-side : en.json
{
"datatable": {
"toolbar" :{
"demote" : "Demote Plugin"
}
}
}Exercise 8 - Use german translation
Create de.json file in src/main/webapp/webapps/HETrueWidget/custom/lang
Update widget toolbar promote command label as below
<Command>
<Label>datatable.toolbar.promote</Label>
<FontIcon>icon forward</FontIcon>
<OnClick>App.table.action.promote</OnClick>
<Alt>Tooltip-Sample Promote</Alt>
</Command>Update de.json with translation value
{
"datatable": {
"toolbar" :{
"promote" : "Promote german"
}
}
}Create tvc-trainingPluginStrings_de.properties in src/main/webapp/WEB-INF/classes
Update tvc-trainingPluginStrings_de.properties with value as below
helium.datatable.toolbar.ExcelExport = Excel German
helium.datatable.toolbar.Filter = Filter GermanDeploy all files and restart server
Change browser language to german and reload helium widget
Please ensure below settings in tvc.properties for widget only mode
tvc.helium.resources.directory.path = /webapps/HETrueWidget/helium
tvc.3ddashboard.heTrueWidget.custom.resources = /webapps/HETrueWidget/helium/custom
Custom Resources
TVC Helium allows including custom scripts and stylesheets and make them available to the client.
Simply putting the files to be included somewhere below /helium/custom. A good recommendation is to use the following structure for the files.
/helium/custom/js
/helium/custom/cssPlease ensure below settings in tvc.properties for widget only mode
tvc.helium.resources.directory.path = /webapps/HETrueWidget/helium
tvc.3ddashboard.heTrueWidget.custom.resources = /webapps/HETrueWidget/helium/custom
Exercise 9 - Deploy custom resources
Create js file in src\main\webapp\webapps\HETrueWidget\helium\custom\training\js\custom.js with below content
App.toaster.info("custom js loaded")Create css file in src\main\webapp\webapps\HETrueWidget\helium\custom\training\js\custom.css with below content
.widget .widget-content header {
background: lightblue;
}Deploy all files and restart server
Datatable Advance Topics
Config settings in Datatable widget :
Exercise 10 - Hands on Datatable widget settings
<DataTable xmlns="http://technia.com/helium/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/WidgetDataTable.xsd">
<Title>Issue Table Widget</Title>
<Responsive>false</Responsive>
<FixedHeader>true</FixedHeader>
<HotKeysNavigation>true</HotKeysNavigation>
<TableConfig namespace="training:issue">IssuesTable.xml</TableConfig>
<Toolbar>
<Command>
<Label>datatable.toolbar.promote</Label>
<FontIcon>icon forward</FontIcon>
<OnClick>App.table.action.promote</OnClick>
<Alt>Tooltip-Sample Promote</Alt>
</Command>
<Command>
<Label>Demote</Label>
<FontIcon>icon backward</FontIcon>
<OnClick>App.table.action.demote</OnClick>
<Alt>tooltip here for Demote</Alt>
</Command>
<ServiceCommand ref="tvc:servicecommand:training:issue/CreateIssue.xml"/>
<ServiceCommand ref="tvc:servicecommand:training:issue/CreateIssueByForm.xml" />
<DataGroup/>
<ExportExcel />
<ExportPDF />
<Search />
<ToggleColumnVisibility />
<AdvanceSorting />
</Toolbar>
</DataTable>Table config settings
Exercise 11 - Server side table
<TableConfig xmlns="http://technia.com/helium/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/TableConfig.xsd">
<Title>Issue Table</Title>
<DataLoader>
<DataSet namespace="training:issue">IssuesSet.xml</DataSet>
</DataLoader>
<ForceReload>true</ForceReload>
<Table namespace="training:issue">IssuesTable.xml</Table>
<DisplayMode>flat</DisplayMode>
<RowSelect>multi</RowSelect>
<Pagination size="100" disabled="false" />
<ClientSideProcessing enabled="false" threshold="8000" />
<EvalCurrentPage>true</EvalCurrentPage>
<FixedColumns>1</FixedColumns>
<RowDragAllowed>true</RowDragAllowed>
</TableConfig>
Entry Processor
Exercise 12 - Entry processor
<TableConfig xmlns="http://technia.com/helium/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/TableConfig.xsd">
<Title>Issue Table</Title>
<DataLoader>
<DataSet namespace="training:issue">IssuesSet.xml</DataSet>
</DataLoader>
<ForceReload>true</ForceReload>
<Table namespace="training:issue">IssuesTable.xml</Table>
<DisplayMode>flat</DisplayMode>
<RowSelect>multi</RowSelect>
<Pagination size="100" disabled="false" />
<ClientSideProcessing enabled="false" threshold="8000" />
<EvalCurrentPage>true</EvalCurrentPage>
<FixedColumns>1</FixedColumns>
<RowDragAllowed>true</RowDragAllowed>
<!--OpenWithMenu>true</OpenWithMenu-->
<EntryProcessor>com.technia.training.table.entryProcessor.SampleEntryProcessor</EntryProcessor>
</TableConfig>package com.technia.training.table.entryProcessor;
import com.technia.tvc.core.db.select.Statement;
import com.technia.tvc.core.db.table.evaluator.EntryProcessor;
import com.technia.tvc.core.db.table.evaluator.EvaluatedData;
import com.technia.tvc.core.db.table.evaluator.EvaluationInput;
import com.technia.tvc.core.gui.table.Table;
import com.technia.tvc.core.gui.table.TableClient;
import com.technia.tvc.log4j.Logger;
public class SampleEntryProcessor implements EntryProcessor {
private static final Logger logger = Logger.getLogger(SampleEntryProcessor.class);
@Override
public void prepareEvaluation(EvaluationInput evaluationInput) {
evaluationInput.addSelectBus("attribute[Material Category]");
}
@Override
public void process(EvaluatedData evaluatedData, Table table, TableClient tableClient) {
TableClient.Entry entry = evaluatedData.getEntry();
String current = evaluatedData.getObjectData().getSelectValue(Statement.CURRENT);
String priority = evaluatedData.getObjectData().getSelectValue("attribute[Priority]");
/* All the examples below represent the opposite of the default entry values. */
// Row Highlight
if (("Medium").equals(priority)) {
entry.setHighlighted(true);
logger.debug("As row object is in Medium priority we have highlighted it using entry processor");
}
// Row Selected
if (("Peer Review").equals(current)) {
entry.setSelected(true);
logger.debug("As row object is in Peer Review state we have Selected it using entry processor");
}
// Row Visible = false
if (("Plastic").equals(priority)) {
entry.setVisible(false);
logger.debug("As row object contains Material Category valus as Plastic we have hidden it using entry processor");
}
// Row Navigable =false
if (("Metal").equals(priority)) {
entry.setNavigable(false);
logger.debug("As row object contains Material Category valus as Metal we have untNavigable it using entry processor");
}
// Row Selectable = false
if (("Low").equals(priority)) {
entry.setSelectable(false);
logger.debug("As row object contains Material Category valus as Rubber we have unSelectable it using entry processor");
}
}
}
Column Configs
Data Handlers
https://products.technia.com/app/docs/tvc-documentation-2026.1.0/tvc/devdocs/index.html#data_handler
Exercise 13 - Data handler
Add new column Critical to table
<?xml version="1.0" encoding="UTF-8"?>
<Column xmlns="http://technia.com/TVC/Table" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/TVC/Table http://products.technia.com/tvc/schema/latest/TableColumn.xsd">
<Name>Critical</Name>
<Label>Critical</Label>
<DataHandlerClass>com.technia.training.table.datahandler.CriticalDataHandler</DataHandlerClass>
<Editable>false</Editable>
<Setting value="helium/templates/table/autocolorable" name="template"/>
<Setting value="true" name="Colorable"/>
</Column>Add column in table
<Column ref="tvc:tablecolumn:training:issue/Critical.xml" />
Write data handler class
package com.technia.training.table.datahandler;
import com.technia.tvc.core.db.table.evaluator.DefaultDataHandler;
import com.technia.tvc.core.db.table.evaluator.EvaluatedData;
import com.technia.tvc.core.db.table.evaluator.EvaluationInput;
import com.technia.tvc.core.gui.table.Cell;
import com.technia.tvc.core.gui.table.Column;
import com.technia.tvc.core.gui.table.impl.BooleanCell;
import com.technia.tvc.core.db.table.evaluator.SelectedData;
public class CriticalDataHandler extends DefaultDataHandler {
@Override
public void prepareEvaluation(Column column, EvaluationInput input) {
System.out.println("Context object Id:"+ input.getEnv().getObjectId());
input.addSelectBus("attribute[Priority]");
input.addSelectBus("attribute[Internal Priority]");
// super.prepareEvaluation(column, input);
}
@Override
public Cell createCell(Column column, EvaluatedData data) {
return new BooleanCell(column);
}
@Override
protected void populateImpl(Cell cell, EvaluatedData data) {
SelectedData selectedData =data.getObjectData();
String priority = selectedData.getSelectValue("attribute[Priority]");
String internalPriority = selectedData.getSelectValue("attribute[Internal Priority]");
if(priority.equals("High") && internalPriority.equals("P3")){
cell.addValue("true");
}else{
cell.addValue("false");
}
}
}
Cell Renderer
Exercise 14 - Cell renderer
Update Critical column to table
<?xml version="1.0" encoding="UTF-8"?>
<Column xmlns="http://technia.com/TVC/Table" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/TVC/Table http://products.technia.com/tvc/schema/latest/TableColumn.xsd">
<Name>Critical</Name>
<Label>Critical</Label>
<DataHandlerClass>com.technia.training.table.datahandler.CriticalDataHandler</DataHandlerClass>
<Editable>false</Editable>
<Setting value="webapps/HETrueWidget/helium/custom/training/templates/critical" name="template"/>
</Column>Write cell renderer and save in webapps/HETrueWidget/helium/custom/training/templates
{{debug cell.values}}
{{#compare cell.values.0.value 'false' operator="==="}}
<span class="ui green label">
<i class="thumbs up icon"></i>
</span>
{{/compare}}
{{#compare cell.values.0.value 'true' operator="==="}}
<span class="ui red label">
<i class="thumbs down icon"></i>
</span>
{{/compare}}
Mass Update
Exercise 15 - Mass update and custom coloring
Add
<AllowMultipleEdit>true</AllowMultipleEdit>in Priority and InternalPriority columns
<?xml version="1.0" encoding="UTF-8"?>
<Column xmlns="http://technia.com/TVC/Table" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/TVC/Table http://products.technia.com/tvc/schema/latest/TableColumn.xsd">
<Name>internalPriority</Name>
<Label>Internal Priority</Label>
<Expression>attribute[Internal Priority]</Expression>
<HeaderNoWrap>true</HeaderNoWrap>
<Editable>true</Editable>
<AllowMultipleEdit>true</AllowMultipleEdit>
</Column><?xml version="1.0" encoding="UTF-8"?>
<Column xmlns="http://technia.com/TVC/Table" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/TVC/Table http://products.technia.com/tvc/schema/latest/TableColumn.xsd">
<Name>priority</Name>
<Label>Priority</Label>
<Expression>attribute[Priority]</Expression>
<HeaderNoWrap>true</HeaderNoWrap>
<AllowMultipleEdit>true</AllowMultipleEdit>
<Editable>true</Editable>
<Setting value="helium/templates/table/autocolorable" name="template"/>
<Setting value="true" name="Colorable"/>
</Column>create colorMapping json file in webapps/HETrueWidget/helium/custom/color
{
"Completed": "#6C7075"
}
Column validation
Exercise 16 - Custom validator
update Description column
<?xml version="1.0" encoding="UTF-8"?>
<Column xmlns="http://technia.com/TVC/Table" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/TVC/Table http://products.technia.com/tvc/schema/latest/TableColumn.xsd">
<Name>description</Name>
<Label>Description</Label>
<Expression>description</Expression>
<HeaderNoWrap>true</HeaderNoWrap>
<Editable>true</Editable>
<ColumnWidth>120</ColumnWidth>
<Setting name="options">{
"validator": "App.training.descValidator",
"validatorMessage": "training.description.validator.message"
}</Setting>
</Column>update custom js file
(function(window, App, $) {
var training = {
descValidator:function(input){
console.log("descValidator method called", input)
return input.length < 10;
},
};
App.training = $.extend({}, App.training || {}, training);
})(window, App, jQuery);update custom css file
.widget .widget-content header {
background: lightblue;
}
.DTE_Field.inline.fields .error {
position: relative !important;
top: 0 !important;
}
update translation file
{
"datatable": {
"toolbar" :{
"demote" : "Demote Plugin",
"promote" : "Promote Plugin"
}
},
"training": {
"description": {
"validator": {
"message": "Description must be less than 10 characters"
}
}
}
}Open form in sidepanel
Exercise 17 - Open form in sidepanel
update Description column
<Column ref="tvc:tablecolumn:training:issue/Edit.xml" />Edit.xml
<Column>
<Name>Actions</Name>
<Label>Additional Details</Label>
<RegisteredSuite>Components</RegisteredSuite>
<ColumnType>helium-column-actions</ColumnType>
<Sortable>false</Sortable>
<Setting name="menu" value="tvc:menu:training:issue/Actions.xml" />
</Column>Actions.xml
<Menu>
<Command>
<Label>Quick View</Label>
<FontIcon>ti-c ti-eye-c</FontIcon>
<Setting name="OnClick">App.training.openDashboardInSidePanel</Setting>
<Setting name="OnClickParams">{"options": {"dashboardRef": "tvc:dashboard:training:issue/IssueInfoSidePanel.xml"}}</Setting>
</Command>
</Menu>
update translation file
(function(window, App, $) {
var training = {
descValidator:function(input){
console.log("descValidator method called", input)
return input.length < 10;
},
openDashboardInSidePanel: function(data) {
App.page.sidepanel.openDashboard(
data.options.dashboardRef,
data.row.objectId
);
}
};
App.training = $.extend({}, App.training || {}, training);
})(window, App, jQuery);IssueInfoSidePanel.xml
<?xml version="1.0" encoding="UTF-8"?>
<Dashboard xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/Dashboard.xsd">
<Locked>true</Locked>
<Floating>false</Floating>
<Widgets>
<Widget ref="tvc:widget:training:issue/IssueDetails.xml">
<Id>issue</Id>
<Width>12</Width>
<Height adjustHeight="true">4</Height>
<X>0</X>
<Y>0</Y>
<Locked>true</Locked>
<Collapsed>false</Collapsed>
</Widget>
</Widgets>
</Dashboard>
IssueDetails
<?xml version="1.0" encoding="UTF-8"?>
<FormWidget xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/WidgetForm.xsd">
<Title>Type: ${TYPE} , Name: ${NAME}</Title>
<FormConfig namespace="training:issue">IssueDetails.xml</FormConfig>
<ResolveContextId>page</ResolveContextId>
<FormMode>view</FormMode>
</FormWidget>
IssueDetails
<?xml version="1.0" encoding="UTF-8"?>
<Form xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/Form.xsd">
<Section >
<Label>General</Label>
<Field namespace="training:issue" name="Title.xml" />
<Field namespace="training:issue" name="Type.xml" />
<Field namespace="training:issue" name="State.xml" />
<Field namespace="training:issue" name="Description.xml">
<Editable>true</Editable>
</Field>
<Field namespace="training:issue" name="Policy.xml" />
<Field namespace="training:issue" name="Owner.xml" />
<Field namespace="training:issue" name="Originated.xml" />
<Field namespace="training:issue" name="Modified.xml" />
</Section>
</Form>
Type.xml
<?xml version="1.0" encoding="UTF-8"?>
<Field xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/FormField.xsd">
<Label>Type</Label>
<Expression>type</Expression>
<Editable>false</Editable>
</Field>
Advance Form Topics
PostRender
Exercise 18 - Using postrender in form
Add <PostRender> in IssueDetails widget xml
<?xml version="1.0" encoding="UTF-8"?>
<FormWidget xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/WidgetForm.xsd">
<Title>Type: ${TYPE} , Name: ${NAME}</Title>
<FormConfig namespace="training:issue">IssueDetails.xml</FormConfig>
<ResolveContextId>page</ResolveContextId>
<FormMode>view</FormMode>
<PostRender>App.training.formPostRender</PostRender>
</FormWidget>
Add few more fields in form :- Priority, Internal Priority, Resolution Date
<?xml version="1.0" encoding="UTF-8"?>
<Field xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/FormField.xsd">
<Label>Priority</Label>
<Expression>attribute[Priority]</Expression>
<Editable>true</Editable>
</Field>
<?xml version="1.0" encoding="UTF-8"?>
<Field xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/FormField.xsd">
<Label>Internal Priority</Label>
<Expression>attribute[Internal Priority]</Expression>
<Editable>true</Editable>
</Field>
<?xml version="1.0" encoding="UTF-8"?>
<Field xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/FormField.xsd">
<Label>Resolution Date</Label>
<Expression>attribute[Resolution Date]</Expression>
<Editable>true</Editable>
</Field>
Add these fields in form xml
<?xml version="1.0" encoding="UTF-8"?>
<Form xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/Form.xsd">
<Section >
<Label>General</Label>
<Field namespace="training:issue" name="Title.xml" />
<Field namespace="training:issue" name="Type.xml" />
<Field namespace="training:issue" name="State.xml" />
<Field namespace="training:issue" name="Description.xml">
<Editable>true</Editable>
</Field>
<Field namespace="training:issue" name="Policy.xml" />
<Field namespace="training:issue" name="Owner.xml" />
<Field namespace="training:issue" name="Originated.xml" />
<Field namespace="training:issue" name="Modified.xml" />
<Field namespace="training:issue" name="Priority.xml" />
<Field namespace="training:issue" name="InternalPriority.xml" />
<Field namespace="training:issue" name="ResolutionDate.xml" />
</Section>
</Form>
Add postrender logic in custom js
(function(window, App, $) {
var training = {
descValidator:function(input){
console.log("descValidator method called", input)
return input.length < 10;
},
openDashboardInSidePanel: function(data) {
App.page.sidepanel.openDashboard(
data.options.dashboardRef,
data.row.objectId
);
},
formPostRender: function() {
var form = this;
var priority = form.getFieldInstanceByDataIdentifier(
'attribute[Priority]'
);
var resolutionDate = form.getFieldInstanceByDataIdentifier(
'attribute[Resolution Date]'
);
priority.on('change', function() {
var priorityValue = priority.getValue();
var isRequired =
priorityValue === 'High' || priorityValue === 'Medium';
form.setFieldRequired(resolutionDate, isRequired);
});
}
};
App.training = $.extend({}, App.training || {}, training);
})(window, App, jQuery);
Field Validation
Exercise 19 - Custom validator
update Description Field
<?xml version="1.0" encoding="UTF-8"?>
<Field xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/FormField.xsd">
<Label>Description</Label>
<Expression>description</Expression>
<Editable>true</Editable>
<!-- Validation -->
<!--
<Validation>
<Required>true</Required>
<MinLength>3</MinLength>
<MaxLength>30</MaxLength>
<Pattern>^(Hello|Goodbye)\sWorld$</Pattern>
</Validation>
-->
<!-- <Recommended>true</Recommended> -->
<Setting name="options">{
"validator": "App.training.descValidator",
"validatorMessage": "training.description.validator.message"
}</Setting>
</Field>
update custom js file
(function(window, App, $) {
var training = {
descValidator:function(input){
console.log("descValidator method called", input)
return input.length < 10;
},
openDashboardInSidePanel: function(data) {
App.page.sidepanel.openDashboard(
data.options.dashboardRef,
data.row.objectId
);
},
formPostRender: function() {
var form = this;
var priority = form.getFieldInstanceByDataIdentifier(
'attribute[Priority]'
);
var resolutionDate = form.getFieldInstanceByDataIdentifier(
'attribute[Resolution Date]'
);
priority.on('change', function() {
var priorityValue = priority.getValue();
var isRequired =
priorityValue === 'High' || priorityValue === 'Medium';
form.setFieldRequired(resolutionDate, isRequired);
});
}
};
App.training = $.extend({}, App.training || {}, training);
})(window, App, jQuery);update translation file
{
"datatable": {
"toolbar" :{
"demote" : "Demote Plugin",
"promote" : "Promote Plugin"
}
},
"training": {
"description": {
"validator": {
"message": "Description must be less than 10 characters"
}
}
}
}
Field Render
Exercise 20 -Field Render
update Priority Field
<?xml version="1.0" encoding="UTF-8"?>
<Field xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/FormField.xsd">
<Label>Priority</Label>
<Expression>attribute[Priority]</Expression>
<Editable>true</Editable>
<Template>webapps/HETrueWidget/helium/custom/training/templates/formfield/issue-priority</Template>
<Setting name="options">{
"useTemplateInEditMode": false
}</Setting>
</Field>Add template in src\main\webapp\webapps\HETrueWidget\helium\custom\training\templates\formfield\issue-priority.handlebars
<label class=" alpaca-control-label">Priority</label>
{{debug data}}
<div class="alpaca-control">
<a class="ui {{priorityColorHelper data}} label">{{data}}</a>
</div>
Add helper in custom js file
(function(window, App, $) {
var training = {
descValidator:function(input){
console.log("descValidator method called", input)
return input.length < 10;
},
openDashboardInSidePanel: function(data) {
App.page.sidepanel.openDashboard(
data.options.dashboardRef,
data.row.objectId
);
},
formPostRender: function() {
var form = this;
var priority = form.getFieldInstanceByDataIdentifier(
'attribute[Priority]'
);
var resolutionDate = form.getFieldInstanceByDataIdentifier(
'attribute[Resolution Date]'
);
priority.on('change', function() {
var priorityValue = priority.getValue();
var isRequired =
priorityValue === 'High' || priorityValue === 'Medium';
form.setFieldRequired(resolutionDate, isRequired);
});
}
};
App.training = $.extend({}, App.training || {}, training);
Handlebars.registerHelper('priorityColorHelper', function(priority) {
var priorityValue = priority || '';
switch (priorityValue.toLowerCase()) {
case 'urgent':
return 'red';
case 'high':
return 'orange';
case 'medium':
return 'yellow';
case 'pre-assigned':
return 'green';
default:
return '';
}
});
})(window, App, jQuery);
Autosubmit , DependsOn, repopulateOn, help messages
Exercise 21 -Autosubmit , DependsOn, repopulateOn, mode, help messages
update IssueDetails form
<?xml version="1.0" encoding="UTF-8"?>
<Form xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/Form.xsd">
<SubmitStrategy>AUTO</SubmitStrategy>
<Section >
<Label>General</Label>
<Field namespace="training:issue" name="Title.xml" />
<Field namespace="training:issue" name="Type.xml" />
<Field namespace="training:issue" name="State.xml" />
<Field namespace="training:issue" name="Description.xml">
<Editable>true</Editable>
</Field>
<Field namespace="training:issue" name="Policy.xml" />
<Field namespace="training:issue" name="Owner.xml" />
<Field namespace="training:issue" name="Originated.xml" />
<Field namespace="training:issue" name="Modified.xml" />
<Field namespace="training:issue" name="Priority.xml" id = "priority" />
<Field namespace="training:issue" name="InternalPriority.xml" id = "internalPriority" dependsOn="priority" dependsOnValue="High,Medium"/>
<Field namespace="training:issue" name="ResolutionDate.xml" id = "resolutionDate" />
</Section>
</Form>
<?xml version="1.0" encoding="UTF-8"?>
<Field xmlns="http://technia.com/helium/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/helium/schema http://products.technia.com/helium/schema/latest/FormField.xsd">
<Label>Priority</Label>
<Expression>attribute[Priority]</Expression>
<Editable>true</Editable>
<Template>webapps/HETrueWidget/helium/custom/training/templates/formfield/issue-priority</Template>
<Setting name="options">{
"useTemplateInEditMode": false,
"helperMessage": "Help message for this field or an i18n key"
}</Setting>
</Field>
update CreateIssueForm form
<Form>
<Title>Create Issue</Title>
<Layout>
<Columns>1</Columns>
</Layout>
<Section>
<Field id="typeField">
<Label>Type</Label>
<Expression>type</Expression>
<Editable>true</Editable>
<FieldType>select</FieldType>
<Setting name="options">
{
"autocomplete": {
"handler" : {
"name": "type",
"localize": "true",
"contains": "true",
"caseSensitive": "false",
"rootTypes":["Part","DOCUMENTS","Issue"]
},
"selectize" : {
"hideSelected": true,
"maxItems": 1,
"allowEmptyOption": true
}
}
}
</Setting>
</Field >
<Field id="policyField">
<Label>Policy</Label>
<Expression>policy</Expression>
<FieldType>select</FieldType>
<Editable>true</Editable>
<Validation>
<Required>true</Required>
</Validation>
<Options><![CDATA[{
"repopulateOn":{
"field":"typeField",
"autocompletehandler":"com.technia.helium.form.create.PolicyAutoCompleteHandler"
},
"autocomplete": {
"handler": {
"name": "dataset",
"dataset": "tvc:dataset:training:issue/ChangeObjects.xml",
"value": "$<id>"
},
"selectize": {
"preload": true,
"maxItems": 1
}
}
}]]></Options>
</Field>
<Field id="description">
<Label>Description</Label>
<Editable>true</Editable>
<FieldType>textarea</FieldType>
</Field>
<Field id="priority">
<Label>Priority</Label>
<Editable>true</Editable>
<FieldType>select</FieldType>
<Defaults>
<Value value="Low" selected="true">
<Label>Low</Label>
</Value>
<Value value="Medium">
<Label>Medium</Label>
</Value>
<Value value="High">
<Label>High</Label>
</Value>
</Defaults>
</Field>
</Section>
</Form>Add dataset
<?xml version="1.0" encoding="UTF-8"?>
<PathQuery>
<PathType>Proposed Activity.Where</PathType>
<PathSelect>owner.to[Proposed Activities].from.to[Change Action].from.id</PathSelect>
<Expand>
<From>true</From>
<To>false</To>
<Depth>1</Depth>
<RelationshipPattern>
<Relationship>relationship_EBOM</Relationship>
</RelationshipPattern>
</Expand>
</PathQuery>(function(window, App, $) {
var training = {
descValidator:function(input){
console.log("descValidator method called", input)
return input.length < 10;
},
openDashboardInSidePanel: function(data) {
App.page.sidepanel.openDashboard(
data.options.dashboardRef,
data.row.objectId
);
},
formPostRender: function() {
var form = this;
var priority = form.getFieldInstanceByDataIdentifier(
'priority'
);
var resolutionDate = form.getFieldInstanceByDataIdentifier(
'resolutionDate'
);
priority.on('change', function() {
var priorityValue = priority.getValue();
var isRequired =
priorityValue === 'High' || priorityValue === 'Medium';
form.setFieldRequired(resolutionDate, isRequired);
});
}
};
App.training = $.extend({}, App.training || {}, training);
Handlebars.registerHelper('priorityColorHelper', function(priority) {
var priorityValue = priority || '';
switch (priorityValue.toLowerCase()) {
case 'urgent':
return 'red';
case 'high':
return 'orange';
case 'medium':
return 'yellow';
case 'pre-assigned':
return 'green';
default:
return '';
}
});
})(window, App, jQuery);
Advance Chart
Options https://apexcharts.com/docs/options
Exercise 22 - Custom Options
Update Owner Bar Chart
<?xml version="1.0" encoding="UTF-8"?>
<Chart>
<Options>{
"plotOptions": {
"bar": {
"columnWidth": "25%",
"distributed": true
}
}
}</Options>
<DrillDown>tvc:dashboard:training:issue/IssuesDashboard.xml</DrillDown>
<Tooltip>true</Tooltip>
<Legend>true</Legend>
<DataSeries>
<Serie>
<DataLoader>
<DataSet>tvc:dataset:training:issue/IssuesSet.xml</DataSet>
</DataLoader>
<Expression>owner</Expression>
<ChartType>bar</ChartType>
</Serie>
</DataSeries>
</Chart>
Series Stacked Chart
<?xml version="1.0" encoding="UTF-8"?>
<Chart>
<Sort>
<Value ascending="false" />
</Sort>
<Options>{
"legendPosition": "top"
}</Options>
<Tooltip>true</Tooltip>
<Legend>true</Legend>
<Stack>true</Stack>
<DataSeries>
<Serie>
<DataLoader>
<DataSet>tvc:dataset:training:issue/IssuesSet.xml</DataSet>
</DataLoader>
<Expression>attribute[Priority]</Expression>
<SeriesExpression>current</SeriesExpression>
<ChartType>bar</ChartType>
<Name>Software Part</Name>
</Serie>
</DataSeries>
</Chart><Chart>
...
<FunctionOptions>{
"chart": {
"events": {
"animationEnd": "App.hex.customEventListener",
"beforeMount": "App.hex.customEventListener",
"mounted": "App.hex.customEventListener",
"updated": "App.hex.customEventListener",
"mouseMove": "App.hex.customEventListener",
"mouseLeave": "App.hex.customEventListener",
"click": "App.hex.customEventListener",
"legendClick": "App.hex.customEventListener",
"markerClick": "App.hex.customEventListener",
"selection": "App.hex.customEventListener",
"dataPointSelection": "App.hex.customEventListener"
}
}
}</FunctionOptions>
...
</Chart>