Custom Installation Page

To collect values for installation parameters, you can build and use a Custom Installation page with certain UI elements and workflows that are unavailable in a standard installation page. For example, a Custom Installation page can:

  • Contain elements such as nested fields, toggles, sliders, date and time pickers, mappers, and so on.
  • Make installation forms dynamic; the value of a parameter determines the other parameters to be displayed.
  • Help perform client-side validation of the installation parameter values entered.

To create and use a Custom Installation page:

  1. Create the iparams.html file, specifying all required HTML, CSS, and JavaScript (JS) information.
  2. In the iparams.html file, add the postConfigs method to retrieve the iparams as form fields with values and store them.
  3. In the iparams.html file, add the getConfigs method to retrieve the stored iparams’ values alone and populate the Edit Settings page.
  4. To perform client-side validation of the iparams entered, in the iparams.html file, add the validate method.
  5. Retrieve the stored iparams and use them in apps.

Note: To handle the secure iparam values entered in the Custom Installation page, the Request method is used. In SMI, when a serverless component is invoked, the iparams defined in a Custom Installation page are passed as a JSON payload.

Create

To create a custom installation page:

  1. Navigate to the config directory and create an iparams.html file.
    Note: Ensure that the config directory contains only one of the two files - iparams.json or iparams.html.
  2. In the iparams.html file, include:
    • The required HTML, CSS, and JS dependencies.
    • The fresh_client.js file, to enable access to certain platform features within the Installation page.
    • A reference to the product style sheet, to maintain design consistency.
  3. For omni apps, to render a product-specific Custom Installation page during run-time, in the iparams.html file, use the client.context.productContext.name attribute. The attribute specifies the name of the product (freshsales or freshworks_crm) in which the app is being installed.

    Example

    Copied Copy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <script> var currentProduct = client.context.productContext.name; if(currentProduct == "freshsales"){ // Manipulate DOM elements relevant to freshsales } else { // Manipulate DOM elements relevant to freshworks_crm } </script>
  4. To retrieve product account specific information such as the domain name and api key associated with an account, in iparams.html, use a text type input element with the data-bind attribute.

    Example

    Copied Copy
    1
    2
    <input type="text" name="api_key" data-bind="product.api_key"> <input type="text" name="domain" data-bind="product.domain">
Note: You can add external assets, such as .css and .js, in the config/assets folder to render the Custom Installation page.

Sample iparams.html

Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" type="text/css" href="https://static.freshdev.io/fdk/2.0/assets/freshworks_crm.css"> <script src="https://static.freshdev.io/fdk/2.0/assets/fresh_client.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" /> <link rel="stylesheet" type="text/css" href="./assets/iparams.css"> <script src="./assets/iparams.js"></script> <style> .dropdown { width: 10%; color: black; border: 5; } #error_div { color: red; } .select2-container { width: 70%; } .select2-container--default { width: 80% !important; } .select2-locked { padding: 0px !important; } </style> <script type= "text/javascript"> jQuery("#error_div").hide(); jQuery("#department").select2({ width: "resolve" }); </script> <script type= "text/javascript"> function getConfigs(configs) { jQuery("#error_div").hide(); jQuery("input[name=api_key]").val(configs["api_key"]); jQuery("input[name=first_name]").val(configs.requester["first_name"]); jQuery("input[name=last_name]").val(configs.requester["last_name"]); for(var i= 0; i < configs.department.length; i++ ) { jQuery("#department option[value=" + configs.department[i] + "]").attr("selected",true); } jQuery("#department").select2({ width: "resolve" }); if(configs.conditions) { jQuery("input[name=\"condition\"]").attr("checked",false); for(var a= 0; a < configs.conditions.length; a++ ) { jQuery("input[name=\"condition\"][value="+ configs.conditions[a]+"]").attr("checked",true); } } } </script> <script type= "text/javascript"> function validate() { let isValid = true; var input = jQuery("input[name=api_key]").val(); if(!input.match(/^[A-z]+$/)) { jQuery("#error_div").show(); isValid = false; } else { jQuery("#error_div").hide(); } return isValid; } </script> <script type= "text/javascript"> function postConfigs() { var requester = {}; var department = []; var conditions = []; var api_key = jQuery("input[name=api_key]").val(); var first_name = jQuery("input[name=first_name]").val(); var last_name = jQuery("input[name=last_name]").val(); requester["first_name"] = first_name; requester["last_name"] = last_name; jQuery("#department option:selected").each(function(){ company.push(jQuery(this).val()); }); jQuery("input[name=\"condition\"]:checked").each(function(){ conditions.push(jQuery(this).val()); }); return { __meta: { secure: ["api_key"] }, api_key, requester, department: company, conditions: conditions } } </script> </head> <body> <div class="requester-fields"> <h3>Requester Fields</h3> <label for="api_key">API key</label> <input type="text" name="api_key"> <span id="error_div" class="error" style="display: none;">Please enter a valid input. Please enter only alphabets.</span> <label for="first_name">First Name</label> <input type="text" name="first_name"> <label for="last_name">Last Name</label> <input type="text" name="last_name"> </div> <div class="account-fields"> <h3>Department Fields</h3> <select class="select2-fields int-select select2-offscreen" data-disable-field="Department" data-placeholder=" " id="department" multiple="multiple" name="company[]" rel="select-choice" tabindex="-1"> <option value="Department">Department</option> <option value="City">City</option> <option value="Country">Country</option> <option value="Email">Email</option> <option value="Phone">Phone</option> <option value="PostalCode">Postal Code</option> <option value="State">State</option> </select> </div> <label class="checkbox-inline"><input name="condition" type="checkbox" value="order"> Display orders from sample app</label> <label class="checkbox-inline"><input name="condition" type="checkbox" value="type"> Display type from sample app</label> </body> </html>
EXPAND ↓
PostConfigs

To store the installation parameters/form fields configured through iparams.html and the corresponding values entered on the Custom Installation page, include this method in the iparams.html file. The method is triggered when, on the Installation page, INSTALL is clicked. The method stores the iparams and corresponding values entered in the custom installation page, as JSON key-value pairs. Secure iparam values are passed using the meta tag in this method.

Sample iparams.html

Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script type= "text/javascript"> function postConfigs() { var requester={}; var department = []; var conditions = []; var first_name = jQuery("input[name=first_name]").val(); var last_name = jQuery("input[name=last_name]").val(); requester["first_name"] = first_name; requester["last_name"] = last_name; jQuery("#department option:selected").each(function(){ department.push(jQuery(this).val()); }); jQuery("input[name="condition"]:checked").each(function(){ conditions.push(jQuery(this).val()); }); return { requester, department: department, conditions: conditions } } </script>
EXPAND ↓
GetConfigs

To retrieve the stored iparams’ values and populate them on the Edit Settings page, include this method in the iparams.html file. The method is triggered when you click the Settings icon on the Installed Apps Listing page.

Sample iparams.html

Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script type= "text/javascript"> function getConfigs(configs) { jQuery("input[name=first_name]").val(configs["first_name"]); jQuery("input[name=last_name]").val(configs["last_name"]); for(var i= 0; i < configs.department.length; i++ ) { jQuery("#department option[value=" + configs.department[i] + "]").attr("selected",true); } jQuery("#department").select2(); if(configs.conditions) { jQuery("input[name="condition"]").attr("checked",false); for(var a= 0; a < configs.conditions.length; a++ ) { jQuery("input[name="condition"][value="+ configs.conditions[a]+"]").attr("checked",true); } } } </script>
EXPAND ↓
Validate

To validate the values entered on the installation page or the Edit settings page, include this method in the iparams.html file. The method is triggered when:

  • During installation, users enter iparam values and click INSTALL on the Installation page.
  • After installation, users edit iparam values and click SAVE on the Edit Settings page.

If the method returns false, the installation is stopped or the iparam values are not saved.

Sample iparams.html

Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
function validate() { let isValid = true; var input = jQuery("input[name=last_name]").val(); if(!input.match(/^[A-z]+$/)) { jQuery("#error_div").show(); isValid = false; } else { jQuery("#error_div").hide(); } return isValid; }
EXPAND ↓
Retrieve

For information on how to retrieve the configured iparams and to use them in the app components, see the Retrieve section.

Test

Note: To test the custom installation page on local settings, use the latest version of the FDK.

  1. From the command prompt, navigate to the app project folder, and run the following command: $ fdk run

    If the app contains a custom installation page, the following message is displayed: To test the custom installation page, visit - http://localhost:10001/custom_configs

  2. Navigate to the specified location. The Custom Installation page is displayed.
  3. For omni apps, a Select Product drop-down list is displayed. Select the product for which you want to test the installation parameters. The Custom Installation page is displayed with product specific iparam fields.
  4. Enter appropriate values in the fields and click Install to test the Installation page.