Helium Advance Training

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

image-20260301-062532.png

 

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 Pluugin
client-side : en.json { "datatable": { "toolbar" :{ "demote" : "Demote Plugin" } } }

Exercise 8 - Use german translation

  1. Create de.json file in src/main/webapp/webapps/HETrueWidget/custom/lang

  2. 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>
  1. Update de.json with translation value

{ "datatable": { "toolbar" :{ "promote" : "Promote german" } } }
  1. Create tvc-trainingPluginStrings_de.properties in src/main/webapp/WEB-INF/classes

  2. Update tvc-trainingPluginStrings_de.properties with value as below

helium.datatable.toolbar.ExcelExport = Excel German helium.datatable.toolbar.Filter = Filter German
  1. Deploy all files and restart server

  2. Change browser language to german and reload helium widget

image-20260301-103641.png

 

 

image-20260301-095819.png

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

 

image-20260301-104002.png

 

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/css

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

 

image-20260301-104516.png

Exercise 9 - Deploy custom resources

  1. Create js file in src\main\webapp\webapps\HETrueWidget\helium\custom\training\js\custom.js with below content

App.toaster.info("custom js loaded")
  1. Create css file in src\main\webapp\webapps\HETrueWidget\helium\custom\training\js\custom.css with below content

.widget .widget-content header { background: lightblue; }
  1. Deploy all files and restart server

image-20260301-110528.png
image-20260301-110902.png

 

Datatable Advance Topics

Config settings in Datatable widget :

image-20260301-115342.png

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>
image-20260301-121249.png

Table config settings

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/admin/index.html#datatable-TableConfig

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>
image-20260301-125620.png

 

Entry Processor

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/admin/index.html#datatable-TableConfig

https://products.technia.com/app/docs/tvc-documentation-2026.1.0/tvc/adminguide/structurebrowser/index.html#using-entry-processors

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"); } } }
8b07b56e-324c-4a0f-bcff-197a9e02121c.png

 

 

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

  1. 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>
  1. Add column in table

<Column ref="tvc:tablecolumn:training:issue/Critical.xml" />

  1. 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

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/admin/index.html#cell_renderers_replaced_by_templates

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/admin/index.html#datatable-ColumnTemplate

Exercise 14 - Cell renderer

  1. 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>
  1. 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}}

 

 

d004d493-31f9-42f8-8328-5114b0e58980.png

Mass Update

Exercise 15 - Mass update and custom coloring

  1. 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>
  1. create colorMapping json file in webapps/HETrueWidget/helium/custom/color

{ "Completed": "#6C7075" }

 

 

 

Column validation

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/admin/index.html#datatable-ClientSideValidation

Exercise 16 - Custom validator

  1. 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>
  1. 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);
  1. update custom css file

.widget .widget-content header { background: lightblue; } .DTE_Field.inline.fields .error { position: relative !important; top: 0 !important; }

 

  1. update translation file

{ "datatable": { "toolbar" :{ "demote" : "Demote Plugin", "promote" : "Promote Plugin" } }, "training": { "description": { "validator": { "message": "Description must be less than 10 characters" } } } }
image-20260301-192950.png

Open form in sidepanel

Exercise 17 - Open form in sidepanel

  1. update Description column

<Column ref="tvc:tablecolumn:training:issue/Edit.xml" />
  1. 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>
  1. 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>

 

  1. 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>
image-20260301-201742.png

Advance Form Topics

PostRender

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/admin/index.html#configuration_3

Exercise 18 - Using postrender in form

  1. 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>
  1. 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>
  1. 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>

 

  1. 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);
image-20260302-051656.png

Field Validation

Exercise 19 - Custom validator

  1. 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>
  1. 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);
  1. 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

  1. 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>
  1. 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>
  1. 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);
image-20260302-075030.png

 

Autosubmit , DependsOn, repopulateOn, help messages

Exercise 21 -Autosubmit , DependsOn, repopulateOn, mode, help messages

  1. 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>
  1. 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>
  1. 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>
image-20260309-015708.png

 

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/tutorial/widget-tutorial.html

https://products.technia.com/app/docs/tvc-helium-documentation-2026.1.0/helium/performance/index.html

TECHNIA CONFIDENTIAL