Custom Button Widget
Custom Buttons is a feature in Facilio where you can invoke certain actions to be performed upon click. That includes functions, connected app widgets and more.
#
TriggersFunction | Description | Example |
---|---|---|
hide | Hides the custom button dialog | app.interface.trigger(‘hide’); |
resize | Resizes the custom button dialog window | const resizeOptions = { width: ‘500px’, height: ‘400px’, top: ‘50px’ } app.interface.trigger(‘resize’, resizeOptions); |
reloadData | Reloads summary page. This can be useful when the record data is updated from the connected app widget. | app.interface.trigger(‘reloadData’); |
#
Example Usecase : Invoice PDF- Javascript
- HTML
- CSS
Generating Invoice PDF using custom button
<script type="text/javascript">var app = new Vue({ el: '#app', data: { currentUser: null, photoUrl: '', baseUrl: '', vendorData: {}, invoiceData: {}, invoiceLineData: [], tableData: [], rec: {}, getPhotoUrl: null, site: '', counter: 1 }, mounted() { window.facilioApp = FacilioAppSDK.init(); window.facilioApp.on("app.loaded", (data) => { window.facilioApp.interface.trigger("resize", { height: "1000px", width: "900px", }); this.currentUser = window.facilioApp.getCurrentUser(); this.invoiceData = data.context; this.site = this.getSite(data?.context?.siteId); this.vendorData = data.context.vendor_custom_vendorinvoices_1; console.log(this.vendorData); this.init(); this.getPhotoUrl = this.vendorData?.logo_vendorsUrl let imageUrl = this.getPhotoUrl; imageUrl = imageUrl?.replace("/api", ""); console.log(imageUrl); if (imageUrl != "" && imageUrl != null) { window.facilioApp.common.toBase64({ url: imageUrl }).then((data) => { this.getPhotoUrl = `${'data:image/png;base64'},${data}` }); console.log(data); } }); }, methods: { init() { this.fetchData(); this.getInvoiceLineItem(); }, print() { window.print(); }, fetchData() { console.log(isEmpty(this.currentUser)) }, async getVendorData(id) {
}, async getInvoiceLineItem() { let params = { viewName: "all", filters: `{"invoice_custom_vendorinvoicelineitems_1":{"operatorId":36,"value":["${this.invoiceData.id}"]}}`, includeParentFilter: true }; let { list, error, data } = await window.facilioApp.api.fetchAll('custom_vendorinvoicelineitems', params); this.invoiceLineData = list; console.log(this.invoiceLineData); list.forEach(data => { let tableObj = { "ID": data.id, "workorder": data?.job_title_custom_vendorinvoicelineitems?.subject ? data?.job_title_custom_vendorinvoicelineitems?.subject : "--", "rate": data?.rate_custom_vendorinvoicelineitems ? data?.rate_custom_vendorinvoicelineitems : "--", "quantity": data?.quantity_custom_vendorinvoicelineitems ? data?.quantity_custom_vendorinvoicelineitems : "--", "subtotal": "$" + data?.sub_total_custom_vendorinvoicelineitems ? data?.sub_total_custom_vendorinvoicelineitems : "--", } let woDate = data?.execution_date_custom_vendorinvoicelineitems; if (woDate != "" && woDate != null) { woDate = (new Date(woDate)).toDateString(); tableObj.woExecutedDate = woDate; } else { tableObj.woExecutedDate = "--"; } this.tableData.push(tableObj) }) }, async getSite(siteId) { let params = { viewName: 'all', includeParentFilter: this.includeParentFilter, } let { list, error, meta } = await window.facilioApp.api.fetchAll('site', params) if (error) { let { message } = error this.$message.error(message || 'Error occured while fetching site') } else { this.siteData = list || [] for (let i = 0; i < this.siteData?.length; i++) { if (this.siteData[i]?.id == siteId) { this.site = this.siteData[i]?.name; } else { this.site = "--"; } } } }, },})</script>
<html> <body> <div id="app" class="invoice-page"> <div class="fc-blue-12"> INVOICE </div> <div> <div style="text-align:center"> <img :src="getPhotoUrl" width="75" height="55" /> </div> <div class="vendor-name"> <div>{{vendorData?.name}}</div> </div> <div class="pdf-header"> <div class="margin6"> <div class="bold textColor">Billing Address </div> <div class="address-box"> TMG Properties (Tmg Properties), <br> P.o Box 112, </n> Ashland, VA 23005 </n> <br> p: (940) 368-2344 </div> </div> <table class="invoice-details"> <tr> <td class="bold">Invoice ID </td> <td class="pad20">{{invoiceData?.id}}</td> </tr> <tr> <td class="bold">Site</td> <td class="pad20">{{site}}</td> </tr> <tr> <td class="bold">Invoice Name </td> <td class="pad20">{{invoiceData?.name}}</td> </tr> <tr> <td class="bold">Invoice Date </td> <td class="pad20">{{new Date(invoiceData?.invoice_date_custom_vendorinvoices).toDateString()}}</td> </tr> </table> </div> <div class="top30"> <table class="invoice-table-container" v-if="invoiceLineData"> <tr> <th>S.No</th> <th>Job Title</th> <th>Execution Date</th> <th>Quantity</th> <th>Rate</th> <th>Subtotal</th> </tr> <tr :key="key" v-for="(lineItem,key) in invoiceLineData"> <td>{{key+1}}</td> <td>{{lineItem?.job_title_custom_vendorinvoicelineitems?.subject}}</td> <td>{{(new Date(lineItem?.execution_date_custom_vendorinvoicelineitems)).toDateString()?(new Date(lineItem?.execution_date_custom_vendorinvoicelineitems)).toDateString():"--"}}</td> <td>{{lineItem?.quantity_custom_vendorinvoicelineitems}}</td> <td>${{lineItem?.rate_custom_vendorinvoicelineitems}}</td> <td>${{lineItem?.sub_total_custom_vendorinvoicelineitems}}</td> </tr> </table> </div> <div class="totalDisplay"> <div class="subtotal alignRight"> <div class="inline textColor">Total : </div> <div class="inline">${{invoiceData?.invoice_total_custom_vendorinvoices}}</div> </div> </div> <el-button type="primary" download="Invoice" class="fc-blue-btn" @click="print" icon="el-icon-download" id="printbtn">Download</el-button> </div> </div> </body></html>
body { padding: 25px; margin: 0; font-size: 14px; letter-spacing: 0.4px; color: #324056; line-height: 20px; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;}.margin6 { margin-bottom: 6.9%;}
.invoice-page { max-width: 1360px; margin-left: auto; margin-right: auto; overflow-x: hidden;}.margin6 { margin-bottom: 6.9%;}
.invoice-table-container.th { text-align: right;}th { color: #2b2d31; font-size: 14px; background-color: #f6f6f6 !important;}.bgColor { background-color: #f6f6f6 !important;}
.alignRight { text-align: right;}
.invoice-details { text-align: left; line-height: 30px; margin-top: 1%; margin-bottom: 14%;}.pad20 { padding-left: 20px;}
.font12 { font-size: 15px; padding-top: 4px;}
.top30 { margin-top: -6%;}
.inline { display: inline;}
.textColor { color: #2b2d31;}
.totalDisplay { display: flex; flex-direction: row; flex-wrap: nowrap; align-content: flex-end; justify-content: flex-end; margin-top: 2%; background-color: #f6f6f6 !important; padding: 12px 0px; color: #2b2d31; font-weight: 600;}
table { font-size: 14px; letter-spacing: 0.4px; text-align: center; color: #324056; line-height: 20px;}
.invoice-table-container.tr { background-color: #f2f7ff;}
.invoice-table-container.td { width: 16.33% !important; padding: 10px;}
.fc-blue-btn { background: #4d93f6; border-color: #4d93f6; left: 45%; z-index: 1000; bottom: 14px; position: fixed;}
.vendor-name { font-size: 15px !important; font-weight: bold !important; line-height: normal; letter-spacing: 0.4px; color: #2b2d31; padding-top: 7px; text-align: center;}
.pdf-header { display: flex; flex-wrap: nowrap; align-content: space-between; justify-content: space-between; align-items: flex-end; margin-top: 50px;}
.inline { display: inline-block;}
.bold { font-weight: 600 !important; color: #2b2d31;}
.pad20 { padding-left: 20px;}
.fc-blue-12 { font-size: 16px; font-weight: 600; font-family: "Aktiv-Grotesk", Helvetica, Arial, sans-serif; line-height: normal; letter-spacing: 0.77px; text-align: right; color: #2b2d31;}
.address-box { width: 300px; padding-bottom: 81px; margin-top: 2%; text-align: left; padding: 10px 0px; line-height: 30px; min-height: 140px;}
.invoice-table-container { width: 100%; line-height: 10px;}
table.invoice-table-container.tbody { background-color: #f6f6f6 !important;}
table.invoice-table-container { background-color: #f6f6f6 !important; line-height: 35px;}
@media print { #printbtn { display: none; }
.margin47 { margin-bottom: 47px; }
table { font-size: 14px; letter-spacing: 0.4px; text-align: center; color: #324056; }
.invoice-table-container.tr { background-color: #f2f7ff; }
.invoice-details { text-align: left; line-height: 30px; margin-bottom: 15%; } .margin6 { margin-bottom: 6%; }}