Developers and Administrators

1. HTML Snippets and Canvas Directives
1.1. Create first Snippet

HTML widgets can be customized using HTML snippets or HTML files. These files / snippets accept HTML 5.0 code.

The HTML Snippets can be found under Settings / Edit Snippets menu.

Here is an example of a HTML snippet.

Using the "+" button you can add a new snippet or a new folder.

  • Create a folder called "hands-on" by clicking on the "+" button next to the snippets.
  • Click on the "+" sign again, next to the newly created "hands-on" folder. Create a new snippet called "workflow_form".

Do not add the '.html' extension, as this will be added automatically.

As an alternative, you can create a HTML file under "apq-c3-custom/html" folder directly on the Apliqo UX installation server. The file name and relative path will be then referenced in the HTML widget, similar to the snippet, as described in the instructions below.

1.2. Using HTML Snippets

We can start by creating the first HTML snippet example. First create a new Wizard. As part of the wizard step, create a sub-step with the type Dashboard. Call this Dashboard "Budget Selection".

Please note that the selected cube isn’t important, because we are going to code all the components of this dashboard in HTML.

While in "Edit mode" change the type of the Dashboard widget to "HTML".

Now you will see a message saying:

Error: HTML widget config is missing in the advanced options

We can configure the widget. To do this, click on the "</>" button next to the widget type selection as shown below. This will automatically open the snippet editor:

  • Create a new HTML snippet or use an already existing one.
  • Inside the snippet window type the following code and click Save.
<div>

    <h1>My first HTML widget!</h1>

</div>
Click to copy
  • Attach the snippet to the HTML widget by clicking on the pin button next to the snippet name.
  • Close the snippet editor and save the Dashboard settings.
1.3. Canvas HTML tags

As part of the HTML snippets we can interact with TM1 using the Canvas tags. There are multiple types of supported Canvas tags and you can find all of them in the Help articles. For the following lesson we will focus on the SUBNM.

Open the newly created HTML snippet and copy the code provided below.

<div style="padding-left: 3%; padding-top: 3%; font-size: 15px;">
    <div style="margin: auto;">
        <div>
            Select the following options before you proceed.
        </div>
        <br>
        <div>
            <input type="radio" id="w1" name="setup" value="new" ng-model="$ctrl.formData.selection" ng-checked="false">
            <label for"w1">Setup new budget</label>
            <br>
            <input type="radio" id="w2" name="setup" value="exit" ng-model="$ctrl.formData.selection">
            <label for "w2">Exit Wizard</label>
        </div>
        <br>
        <div class="apq-c3-filterbar-filters setup_wrapper" ng-if="$ctrl.formData.selection === 'new'">
            <div class="one_one apq-c3-filter-label float-left">
                Version:
            </div>
            <div>
                <tm1-ui-subnm-apq
                    tm1-instance="UX_Demo"
                    tm1-dimension="Version"
                    tm1-subset="Default"
                    tm1-attribute="Description"
                    tm1-default-element="Actual"
                    tm1-ui-class="apq-c3-uidropdown"
                    tm1-button="true"
                    ng-model="$ctrl.formData.version">
                </tm1-ui-subnm-apq>
            </div>
            <div class="two_one apq-c3-filter-label float-left">
                Comment:
            </div>
            <div class="two_two">
                <textarea rows="3" cols="40" ng-model="$ctrl.formData.comment" ></textarea>
            </div>
            <div>
                <input type="checkbox" name="agree" value="header" id="c1" ng-model="$ctrl.formData.agree" ng-checked="false">
                <label for "c1">Agree to the <a href="https://apliqo.com/termsandconditions/">Terms and Conditions </a></label>
            </div>
        </div>
    </div>
</div>
Click to copy

Part of the code responsible for the SUBNM selection:

               Version:
            </div>
            <div>
                <tm1-ui-subnm-apq
                    tm1-instance="UX_Samples"
                    tm1-dimension="Version"
                    tm1-subset="Default"
                    tm1-attribute="Description"
                    tm1-default-element="Actual"
                    tm1-ui-class="apq-c3-uidropdown"
                    tm1-button="true"
                    ng-model="$ctrl.formData.version">
                </tm1-ui-subnm-apq>
            
Click to copy

To make the content look better in the page:

  • Create a style.css file in the css folder: ApliqoServer\webapps\webAppName\apq-c3-custom\css using the code provided below
  • Refresh the browser by clearing the cache.
  .setup_wrapper {
    display: grid;
    grid-template-columns: 150px auto;
    grid-gap: 5px;
    grid-auto-rows: minmax(15px, auto);
  }
  .one_one {
    grid-column: 1;
    grid-row: 1;
  }
  .one_two { 
    grid-column: 2;
    grid-row: 1;
  }
  .two_one {
    grid-column: 1;
    grid-row: 2;
  }
  .two_two {
    grid-column: 2;
    grid-row: 2;
  }
  .two_both {
    grid-column: 1 / 2;
    grid-row: 2;
  }
  .three_one {
    grid-column: 1;
    grid-row: 3;
  }
  .three_two {
    grid-column: 2;
    grid-row: 3;
  }
  .four_one {
    grid-column: 1;
    grid-row: 4;
  }
  .four_two {
    grid-column: 2;
    grid-row: 4;
  }
  .five_one {
    grid-column: 1;
    grid-row: 5;
  }
  .five_two {
    grid-column: 2;
    grid-row: 5;
  }
  .six_one {
    grid-column: 1;
    grid-row: 6;
  }
  .six_two {
    grid-column: 2;
    grid-row: 6;
  }
Click to copy

The result should look like this:

The subnm selection can be easily changed by configuring those parameters differently: 

tm1-dimension="Version"
tm1-subset="Default"
tm1-attribute="Description"
tm1-default-element="Actual"
Click to copy

For example:

tm1-dimension="Region"
tm1-subset="All Countries"
tm1-attribute="Code and Description"
tm1-default-element="USA"
Click to copy

Before going to the next section change the code back to the original one. 

1.4. Create HTML buttons

With the use of HTML snippets we can also create a custom html buttons that can navigate anywhere in the app, but also external link can be used. We will take a look at both cases, as different code will be used to configure them. 

For the purpose of this exercise create and publish new dashboard (any cube source, title e.g. HTML buttons) 

Create a button to navigate inside the app:

  • Change the widget type to HTML 
  • Open HTML code snippet editor 
  • Add new snippet titled Buttons

To navigate inside the app we will use this code: 

<button ui-sref="apq-c3-app({initView:'a9.v8'})" style="" class="">Navigate to wizard</button>
Click to copy

<button>Button Title</button> 

  • create a button 

style=""

  • add button style  

class=""

  • specify button class

ui-sref="apq-c3-app({initView:'a9.v8'})"

  • dashboard / view / wizard location in the app

It can be checked and copied from the developer console. 

Create a button with external link:

  • Open HTML code snippet editor again 
  • Select Buttons snippet
  •  Paste the code provided below: 
<div class="btn btn-secondary">
<a href="https://getbootstrap.com/docs/4.0/components/buttons/">Bootstrap Buttons</a></div>
Click to copy

<a href="">Title</a>

  • to navigate outside of the app use this tag

Learn more about button customization by using to the link provided in this exercise - Bootstrap Buttons

2. Wizard functions
2.1. Advanced wizard functions and workflow integration

Base on the wizard steps created in the previous chapter we can continue to add more dynamic functionality to our workflow concept.

Use the code below to add a new JavaScript file named custom_wizard_functions to the “js” folder: ApliqoServer\webapps\webAppName\apq-c3-custom\js

// *** Function to choose the path for the wizard at step 1
    startWizard(step) {

        let formData = step.wizardData.formData;

        console.log("[Debug] step data: ", CustomWizard);
        console.log("[Debug] form data: ", formData);

        var nextStep = formData.selection;

        formData.process = "running";
        // WizardCtrl.self.options.hideNextButton = true;

        switch (nextStep) {
            case "new":
                {
                    var comment = formData.comment;
                    var version = formData.version;

                    // fix empty textbox
                    if (formData.comment)
						var comment = formData.comment;
					else
						var comment = '';
					
                    CustomWizard.self.$tm1Ui.processExecute('UX_Demo', '}bedrock.server.wait', 'pWaitSec', '5').then(function (result) {
                        console.log('[Debug] Result: ', result, '; next step: ', nextStep);

                        // Check TI result
                        if (result.success)
                        {

                            CustomWizard.self.$timeout(()=>{
                                CustomWizard.self.Settings.change('UX_Demo.Version.Version',version);
                            }, 0)

                            // WizardCtrl.self.options.wizard.hideNextButton = false;
                            formData.process = "success";
                            WizardCtrl.self.options.wizard.hideNextButton = false;
                            WizardCtrl.self.pfwizardCtrl.next();
                        }
                        else {
                            console.error("Error in executing TI. Process message: ", result.message.message)
                            formData.process = "error";
                            WizardCtrl.self.options.wizard.hideBackButton = false;
                        }
                    })
                    break;
                }

            case "exit":
                {
                    // Navigate to the exit
                    CustomWizard.self.$state.go('apq-c3-wizard', {
                        wizardName: 'a1.z1',
                        wizardStep: 'a1.z1.t4',
                        initView: 'a1.z1.t4.v2',
                        viewType: 'Dashboard'
                    }, { reload: true, notify: true });
                }
            }
        }

    // *** Function to check the status of the form data
    checkDataChanged(step) {

        let formData = step.wizardData.formData;

        var nextStep = formData.selection;
        

        switch (nextStep) {
            case "exit":
            {
                WizardCtrl.self.options.wizard.hideNextButton = false;
                break;
            }
            case "new":
                {
                    var agreed = formData.agree;

                    if (agreed)
                        WizardCtrl.self.options.wizard.hideNextButton = false;
                    else
                    WizardCtrl.self.options.wizard.hideNextButton = true;
                    break;
                }
            default:
                WizardCtrl.self.options.wizard.hideNextButton = true;
                break;
            }

    }
Click to copy

Remember to configure this part of the code to match your wizard: 

CustomWizard.self.$state.go('apq-c3-wizard', {
            wizardName: 'a2.f3.z1',
            wizardStep: 'a2.f3.z1.t2',
            initView: 'a2.f3.z1.t2.v1',
            viewType: 'View'
Click to copy

Where to find the correct id:

  • Wizard ID: select wizard title and open the advanced options panel. Hover over the title - the id will appear as a tooltip. 
  • Step ID: select the step which id you want to check, open the advanced options panel. Hover over the title - the id will appear as a tooltip. 
  • SubStep ID: select the Substep which id you want to check, open the advanced options panel. Hover over the title - the id will appear as a tooltip.

In the advanced settings of the dashboard add the following lines:

"wizard": {
    "formDataChanged": "checkDataChanged",
    "nextCallback": "startWizard",
    "hideNextButton": true
  }
Click to copy

Instead of pasting the code this configuration can be also done using new Advanced Options GUI:

  • Click on the settings (wrench) icon 
  • Select Wizard Config
  • In the textbox for On Form Data Change Function input checkDataChanged
  • Click the plus icon next to the Wizard Config
  • Click the plus icon next to the Back & Next Buttons 
  • Select Next 
  • In the textbox for Next Callback Function input startWizard
  • Save the changes

This file contains the following functions:

  • checkDataChanged

This function is used to check when selections inside the HTML form is changed. 

After selecting 'Setup new Budget' and checking the box to 'Agree to the terms and Conditions' the Next button will appear. 

Same will happen after selecting 'Exit Wizard' option.

  • startWizard

This function is used to handle the action that happens when the next button is pressed. For example if the 'Exit Wizard' option is selected, clicking Next button will result in wizard navigating back to the first step. 

3. Working with Task Scheduler

Before going through this section make sure that the Task Scheduler is correctly configured. Information about the setup process for new tasks is available in a dedicated Task Scheduler Configuration article.

The Task Scheduler is an administrative feature available for members of the APQ Admin group. It allows to plan automated tasks, e.g. sending a Report(s) to e-mail address(es), downloading report printouts directly to disk, or scheduling a specific TM1 Process to run with given parameters.

After the configuration Task Scheduler will be available on the Settings list:  

3.1. Creating new task

We will start working with the task scheduler by creating a new folder and task: 

  • Click '+' icon visible next to the Public Job folder 
  • In the popup input the folder name: Course 
  • Click Create 
  • Click on the '+' icon visible next to the newly created folder

In the popup: 

  • Select Task option 
  • input the task name: Task 1 
  • Click Create 

New folder as well as task should be visible on the list. 

3.2. Add new Action

The next step will be to plan your first action. 

Available action types that can be added to the task are:

  • Process, runs a TI process with specified parameter values
  • Chore, runs a classic TM1 chore, that can contain multiple processes
  • Wait, allows to delay further actions by specified amount of time
  • Report, its purpose is to generate PDF files

In this Course we will focus on the Report action, which is the most extensive action available in the Task Scheduler. 

Follow this steps to create first Report action: 

  • Select Task 1 from the list and make sure that the Task Name - Task 1 appeared in the Task Details
  • Click on the '+' icon visible in the Action section 
  • New Report action  will appear under Actions section 
  • Enter the action name: Report 1 
  • Save the changes 

After saving the changes Action Details panel for our new Report opened and now we can configure it: 

  •  Select Save to Disc option. (All the report are by default saved in the WEB-INF/print  folder but the Relative Directory can be changed)
  • Open Report tab 

Now we will add the attachments we want to be saved to disk:

  • Click on the '+' icon visible in the Attachments section

Report can consist of one or more attachments: Views, Dashboards or Wizards.

There are several customizable options available: 

  • Name
  • Page Size
  • Page Orientation
  • Output Format
  • Select Dashboard Type 
  • Choose Exec Dashboard
  • Click Save  
  • Click Execute 

Check the WEB-INF/print folder and make sure that the pdf file was generated.

3.3. Additional configuration of the Report action
3.3.1. Send email

Apart from the option to generate pdf file and save it to disk discussed in intermediate course, Report action offers more possibilities. One of them is to send an email with the pdf file(s).

Follow those steps:

  • Select Task 1 from the list
  • In the Email tab check Send Email action 
  • Input information to the Subject, Recipient(s) and Body text fields (email won't be send if any of those information is missing) 
  • Click Save and Execute
  • Make sure that the email was send to the email address added under Recipient(s)
3.3.2. Merge files

Another available option is Merge PDF(s). If you have added many attachments to your report, by default each of them will be saved to disk or sent by e-mail as a separate pdf file. Merge option allows us to to combine those attachments into single pdf file.

Follow the steps: 

  • In the email tab choose Save to Disk option
  • Check Merge PDF(s) option 
  • Input the Merge File Name 
  • If you want the filename to include today's date, check Append Timestamp option
  • Open Report tab 
  • Click on the '+' icon visible in the Attachments section
  • Select View Type 
  • Choose Sales Planning  
  • Click Save  
  • Click Execute

Check the WEB-INF/print folder and make sure that the merged pdf file was generated.

3.3.3. Configure Burst

The Burst option allows to generate multiple reports with different filter settings. It can be set by using the existing Subset or adding custom MDX query.  

First we will use existing Subset:

  • navigate to Burst tab
  • click on the plus icon 
  • select Dimension Subset from the drop-down list

Users can select Instance, Dimension and define Placeholder Name. The {{Placeholder Name}} will be replaced with the corresponding setting service element value from the selected dimension/hierarchy.


  • select UX_Demo instance
  • choose Region dimension 
  • from the Subset drop-down list select All C Elements 
  • in the Placeholder Name input: region 
  • click Save and then Execute

Check the WEB-INF/print folder and make sure that multiple files for both attachments were generated and the Placeholder Name (region) was replaced with corresponding value from Region dimension.

Now we will configure Burst using custom MDX query:

  • navigate to Burst tab 
  • remove existing Dimension Subset by click on the 'trash can' icon 
  • click on the plus icon 
  • select Dimension MDX from the drop-down list
  • select UX_Samples instance
  • choose Region dimension 
  • in the MDX text box input: {[Region].[Region].[2],[Region].[Region].[9]} to select Europe and Asia 
  • in the Placeholder Name input: region 
  • click Save and then Execute

Check the WEB-INF/print folder and make sure that two files have been generated for each attachment: Europe(2) & Asia(9). 

3.3.4. Timestamp and Relative Directory
3.3.4.1. Timestamp

It is an useful option that allows us to create a new folder with a current date inside the print folder. The format is customizable. Also you can get more info about it after clicking on the button visible next to it.

Follow the steps:

  • In the Email tab check the option to Append Timestamp 
  • Change the format to dd.MM.yyyy
  • Save the changes and execute the task 

Folder with the current date should appear in the print folder. 

3.3.4.2. Relative Directory

The option is used to create a new folder inside WEB-INF/Print folder. 

It can be combined with the timestamp option - in this case the the timestamp will be added to the newly created folder. 

Follow the steps below:

  • In the Email tab add Relative Directory e.g.  New Folder 
  •  Save the changes and execute the task 

New Folder with the current date should appear in the print folder. 

3.4. Setting up a schedule

Users can also set schedules so that the actions can be automatically executed. Task needs to be Active for this option to work correctly.

To set up a schedule: 

  • click on the plus icon inside the Schedule section 
  • select Set the new schedule option
  • you can add a schedule name but it's not mandatory 

All tasks can be scheduled on a reoccurring basis. The user can choose from 4 available repeat settings: Monthly, Weekly, Daily and Custom. Additional options will be available after selecting one of them. 

  • select Every Day option
  • set the Time to 5 mins from now
  • click Apply Schedule
  • Save the changes  

Check the WEB-INF/print folder (after the 5min or any other time amount that you set) and make sure that the pdf file was generated.

Schedule can be also used to send email(s) to selected recipient(s) on the reoccurring basis. 

0 Comments

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.