Custom Installation Page

The custom installation page enables developers to build installation pages that contain UI elements and workflows that are unavailable on the Standard Installation page.

Sample Use Cases

  • Use interface elements, such as nested fields, toggles, sliders, date and time pickers, mappers, and more, on the installation page.
  • Build dynamic forms where a value entered for one parameter determines the next parameter that is shown.
  • Perform client-side validation of entered parameters

To create and use a Custom Installation page, follow the given steps.

  1. Create a template with HTML, CSS, and JavaScript (JS).
  2. Add a postConfigs method to store the installation parameters.
  3. Add a getConfigs method to retrieve the installation parameters and populate the Edit Settings page.
  4. [Optional] Perform client-side validation on the entered parameters.
  5. Retrieve the stored installation parameters and use them in your apps.

Note:
As part of the Custom Installation page, Request API can be used by initializing the client. For more information, see Request API.

Create

To create a custom installation page:

  1. In the config directory, 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.
Note:
1. Use the latest version of FDK to test the Custom Installation page in your computer.
2. 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/freshservice.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("#company").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.contact["first_name"]); jQuery("input[name=last_name]").val(configs.contact["last_name"]); for(var i= 0; i < configs.company.length; i++ ) { jQuery("#company option[value=" + configs.company[i] + "]").attr("selected",true); } jQuery("#company").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 contact={}; var company = []; 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(); contact["first_name"] = first_name; contact["last_name"] = last_name; jQuery("#company 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, contact, company: company, conditions: conditions } } </script> </head> <body> <div class="contact-fields"> <h3>Contact 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>Company Fields</h3> <select class="select2-fields int-select select2-offscreen" data-disable-field="Company" data-placeholder=" " id="company" multiple="multiple" name="company[]" rel="select-choice" tabindex="-1"> <option value="Company">Company</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

This method is used to store key value pairs containing names and values of iparam fields in JSON format and also pass secure iparam keys using the meta tag. The postConfigs() method is triggered when a user clicks the INSTALL button, and it is mandatory to include this function in iparams.html.

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
<script type= "text/javascript"> function postConfigs() { var requester={}; var deparment = []; 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("#deparment option:selected").each(function(){ deparment.push(jQuery(this).val()); }); jQuery("input[name="condition"]:checked").each(function(){ conditions.push(jQuery(this).val()); }); return { __meta: { secure: ["api_key"] }, api_key, requester, deparment: deparment, conditions: conditions } } </script>
EXPAND ↓
GetConfigs

This method is invoked when the user clicks the Settings icon in the Installed Apps Listing page to edit the installation parameters. The getConfigs() method is used to retrieve the existing installation parameters and populate them in the Edit Settings page. It is mandatory to include this function in iparams.html.

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.deparment.length; i++ ) { jQuery("#deparment option[value=" + configs.deparment[i] + "]").attr("selected",true); } jQuery("#deparment").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

This method can be used to validate the input values provided by users during installation. If false is returned, users will not be allowed to proceed with the installation.

The validate() method is invoked in the following scenarios:

  • When users enter the iparams and click INSTALL during app installation.
  • When users edit the iparams and click SAVE after app installation.

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

To fetch installation parameters, see the Retrieve section.

Testing

To test your app in local settings, follow these steps:

  1. Open your console, navigate to your project folder, and execute the following command: $ fdk run Apps that contain a Custom Installation page will display the following: To test the custom installation page, visit - http://localhost:10001/custom_configs
  2. Enter values in the fields and click the Install button to test the app installation.