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 in 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.
Take a look at the Custom Installation Page and Asana sample apps for a demonstration of this feature.

To create and use a Custom Installation page, follow the steps below:
  1. Create the template with HTML, CSS, and JavaScript (JS).
  2. Add a postConfigs method to store 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 get started, create an iparams.html file and place it in the app’s config/ directory. The Custom Installation page is sandboxed in an IFrame and so you need to include all the required HTML, CSS, and JS.
You must include fresh_client.js to enable communication between the Install page and Parent page through the sandbox. To maintain design consistency, include a reference to the product style sheet. You can read about our UI guidelines here.

template.html
Copied Copy
1
2
<script src="https://static.freshdev.io/fdk/2.0/assets/fresh_client.js"></script> <link rel="stylesheet" type="text/css" href="https://static.freshdev.io/fdk/2.0/assets/freshdesk.css">

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
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" type="text/css" href="https://static.freshdev.io/fdk/2.0/assets/freshdesk.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" /> <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 ↓

Note:
1. You should either have iparams.json or iparams.html not both.
2. Use v4.2.1 or a higher version of the FDK to test the Custom Installation page in local settings.

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 inside 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 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>
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 inside 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
<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>
EXPAND ↓
validate

This method can be used to validate 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 iparams and click INSTALL during app installation.
  • When users edit iparams and click SAVE after app installation.

iparams.html

Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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>
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.

Log in with your Freshdesk account

Enter your helpdesk URL to proceed to login

Proceed

By clicking "Proceed", you agree to our Terms of Use.