--- title: "Configure the client" url: https://docs.catalyst.zoho.com/en/tutorials/payslip-generator-app/nodejs/configure-client/ description: "Build a web app that uses Catalyst components to generate a PDF from a dynamic custom payslip template, and email the generated document to the end-user." last_updated: 2026-11-04T10:10:44Z service: All Services type: tutorial related_links: - name: "Client Directory Structure" url: /en/cli/v1/project-directory-structure/client-directory/ - name: "Web Client Hosting" url: /en/cloud-scale/help/web-client-hosting/introduction/ --- # Configure the Client Now, let’s configure the client component. The [client directory](https://docs.catalyst.zoho.com/en/cli/v1/project-directory-structure/client-directory/) contains: * The `index.html` file that contains the HTML code for the front-end application * The `main.css` file that contains the CSS code for the front-end application * The `main.js` file that contains the JavaScript code * The `client-package.json` configuration file We will be coding `index.html`, `main.css`, and `main.js`. > **Note:** Please go through the code in this section to make sure you fully understand it. Copy the code below and paste it into the respective files located in the `client/directory` of your project using an IDE and save the files. **index.html** ```xml <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" /> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="main.js"></script> <link rel="stylesheet" type="text/css" href="main.css"/> <script> window.addEventListener("DOMContentLoaded", function () { // Retrieve input elements var basicSalaryInput = document.getElementById("basicSalary"); var allowancesInput = document.getElementById("allowances"); var deductionsInput = document.getElementById("deductions"); var netSalaryInput = document.getElementById("netSalary"); // Add event listeners to input fields basicSalaryInput.addEventListener("input", calculateNetSalary); allowancesInput.addEventListener("input", calculateNetSalary); deductionsInput.addEventListener("input", calculateNetSalary); // Function to calculate net salary function calculateNetSalary() { // Retrieve values from input fields var basicSalary = parseFloat(basicSalaryInput.value) || 0; var allowances = parseFloat(allowancesInput.value) || 0; var deductions = parseFloat(deductionsInput.value) || 0; // Calculate net salary var netSalary = basicSalary + allowances - deductions; // Update the net salary input field netSalaryInput.value = netSalary.toFixed(2); } }); </script> </head> <body> <div class="container mt-5 mb-5"> <h2>Payslip Generator</h2> <form onsubmit="generatePayslip();return false;"> <div class="row"> <div class="form-group col-md-6"> <label for="employeeName">Employee Name:</label> <input type="text" id="employeeName" name="employeeName" required /> </div> <div class="form-group col-md-6"> <label for="employeeId">Employee ID:</label> <input type="text" id="employeeId" name="employeeId" required /> </div> </div> <div class="row"> <div class="form-group col-md-6"> <label for="designation">Employee Designation:</label> <input type="text" id="designation" name="designation" required /> </div> <div class="form-group col-md-6"> <label for="employeeEmail">Employee Email:</label> <input type="text" id="employeeEmail" name="employeeEmail" required /> </div> </div> <div class="row"> <div class="form-group col-md-6"> <label for="basicSalary">Basic Salary:</label> <input type="number" id="basicSalary" name="basicSalary" min="0" oninput="validity.valid||(value='');" required /> </div> <div class="form-group col-md-6"> <label for="allowances">Allowances:</label> <input type="number" id="allowances" name="allowances" min="0" oninput="validity.valid||(value='');" required /> </div> </div> <div class="row"> <div class="form-group col-md-6"> <label for="deductions">Deductions:</label> <input type="number" id="deductions" name="deductions" min="0" oninput="validity.valid||(value='');" required /> </div> <div class="form-group col-md-6"> <label for="netSalary">Net Salary:</label> <input type="number" id="netSalary" name="netSalary" readonly /> </div> </div> <div class="row"> <div class="form-group col-md-6"> <label for="paymentMethod">Payment Method:</label> <select id="paymentMethod" name="paymentMethod" required> <option value="">Select</option> <option value="Bank Transfer">Bank Transfer</option> <option value="Cheque">Cheque</option> <option value="Cash">Cash</option> </select> </div> </div> <input type="submit" value="Submit" /> </form> </div> </body> </html> ``` **main.css** ```css .container { background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); padding: 40px; margin-top: 50px; margin-bottom: 50px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } h2 { background: linear-gradient(to right, #4caf50, #45a049); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-align: center; margin-bottom: 40px; } /* Styling for the form labels */ label { transition: color 0.3s ease; /* Add a subtle animation on hover */ } label:hover { /* Change the color on hover */ color: #4caf50; } /* Styling for the form input fields */ input[type="text"], input[type="number"], select { /* Increase the height of the input fields */ height: 40px; /* Add a subtle box shadow */ } /* Styling for the form input groups */ .form-group { display: flex; align-items: center; margin-bottom: 10px; } .form-group label { flex: 0 0 200px; /* Set a fixed width for the labels */ margin-right: 10px; /* Add some spacing between label and input */ } .form-group input, .form-group select { flex: 1; /* Allow the inputs to take up remaining space */ } /* Styling for the submit button */ input[type="submit"] { /* Add a gradient background */ background-image: linear-gradient(to right, #4caf50, #45a049); /* Add a box shadow */ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); margin-top: 15px; width: 150px; margin-left: 600px; } input[type="submit"]:hover { /* Darken the background on hover */ background-image: linear-gradient(to right, #45a049, #398e3d); } ``` > **Note:** The Node.js function package’s name `payslip_generator_function` has been added in the code for `main.js` in the line **13**. If you have provided a different package name, ensure you replace accordingly. **main.js** ```javascript function generatePayslip() { // Retrieve form values const employeeName = document.getElementById('employeeName').value; const employeeId = document.getElementById('employeeId').value; const designation = document.getElementById('designation').value; const paymentMethod = document.getElementById('paymentMethod').value; const employeeEmail = document.getElementById('employeeEmail').value; const basicSalary = parseFloat(document.getElementById('basicSalary').value); const allowances = parseFloat(document.getElementById('allowances').value); const deductions = parseFloat(document.getElementById('deductions').value); $.ajax({ url: '/server/payslip_generator_function/generatepayslip', //provide your function endpoint here type: 'post', contentType: 'application/json', data: JSON.stringify({ employeeName, employeeId, basicSalary, allowances, deductions, designation, paymentMethod, employeeEmail }), success: function (data) { alert(data); window.location.reload(); }, error: function (error) { console.log(error); alert(error.responseText); window.location.reload(); } }); } ``` The client directory is now configured. Let’s go over the working of the function and the client code: * The end-user enter inputs the employee details in the client-side. When the end-user clicks **Submit**, a `POST` call in `main.js` triggers the `/generatepayslip` API endpoint and the data is passed to the function in a JSON format. * The function triggers the [PDF & Screenshot SDK](https://docs.catalyst.zoho.com/en/sdk/nodejs/v2/smartbrowz/generate-pdfnscreenshot/#generate-visual-documents-using-template) and the request body is passed and the PDF document is generated. The PDF is then stored in a temporary location. * The [Send Mail SDK](https://docs.catalyst.zoho.com/en/sdk/nodejs/v2/cloud-scale/mail/send-email/) is triggered and the PDF document is read from the temporary location and attached to the email. The email is sent to the employee from the email ID set up using the [Mail](https://docs.catalyst.zoho.com/en/cloud-scale/help/mail/introduction/) component. * A response containing the acknowledgement message will be displayed on the client-side, after the PDF document has been emailed.