Skip to main content

Custom Button Widget

Custom Buttons let you invoke actions when a user clicks a button on a record page. The button opens a dialog containing your Connected App widget — ideal for generating documents, running bulk operations, or displaying confirmation dialogs with custom logic.


customButton


customButton

Availability#

AppsMobile
Maintenance, Vendor, Requester, Client, TenantYes

When to use#

  • Generating invoices, reports, or other documents from record data
  • Running custom actions that require user input or confirmation
  • Triggering external API calls with a review step before execution
  • Building multi-step action dialogs

Triggers#

FunctionDescriptionExample
hideHides the custom button dialogwindow.facilioApp.interface.trigger('hide');
resizeResizes the custom button dialog (web only; uses preset sizes, not fixed px)See example below
reloadDataReloads the summary page (useful after updating the record)window.facilioApp.interface.trigger('reloadData');
setCloseEventRegisters a hook for when the user closes the modal (close icon on web, back on mobile). Use when the widget runs timed activity or loading — users may close before it completes; run cleanup, cancel requests, or show confirmation. Works on web and mobile.window.facilioApp.interface.trigger('setCloseEvent', { key: 'onModelClose' });
clearCloseEventRemoves the registered close event handler. Call when the operation completes or the user explicitly cancels.window.facilioApp.interface.trigger('clearCloseEvent');
Web only

resize is supported on web only.

Resize example — Pass size with one of: XS, S, M, L, XL

window.facilioApp.interface.trigger('resize', { size: 'L' });

Close event — The Custom Button opens as a modal with a close icon. If the widget runs timed activity or loading, users may click close before it completes. Use setCloseEvent to hook into the close action (web: close icon; mobile: back) and run cleanup, cancel requests, or show confirmation:

// Register the close eventwindow.facilioApp.interface.trigger('setCloseEvent', { key: 'onModelClose' });
window.facilioApp.on('onModelClose', () => {  // Cleanup, cancel requests, show confirmation, etc.});
// When the operation completes or user explicitly cancels, clear the handlerwindow.facilioApp.interface.trigger('clearCloseEvent');

Context#

When a custom button dialog opens, app.getContext() returns the current record data. Use this to access the record's fields for your action.

app.on('app.loaded', (data) => {  const record = data.context;  console.log('Record ID:', record.id);  console.log('Record Name:', record.name);});

Example — Invoice PDF generation#

const app = FacilioAppSDK.init();
app.on('app.loaded', async (data) => {  window.facilioApp.interface.trigger('resize', { size: 'XL' });
  const invoiceData = data.context;  const vendorData = invoiceData.vendor_custom_vendorinvoices_1;
  // Convert vendor logo to base64 for PDF rendering  let logoBase64 = null;  const logoUrl = vendorData?.logo_vendorsUrl;  if (logoUrl) {    const cleanUrl = logoUrl.replace('/api', '');    const base64 = await app.common.toBase64({ url: cleanUrl });    logoBase64 = `data:image/png;base64,${base64}`;  }
  // Fetch invoice line items  const { list } = await app.api.fetchAll('custom_vendorinvoicelineitems', {    viewName: 'all',    filters: JSON.stringify({      invoice_custom_vendorinvoicelineitems_1: {        operatorId: 36,        value: [String(invoiceData.id)]      }    }),    includeParentFilter: true  });
  renderInvoice(invoiceData, vendorData, list, logoBase64);});
function renderInvoice(invoice, vendor, lineItems, logo) {  // Render your invoice HTML with the data  document.getElementById('vendor-name').textContent = vendor?.name || '';  document.getElementById('invoice-id').textContent = invoice.id;  document.getElementById('invoice-name').textContent = invoice.name;
  if (logo) {    document.getElementById('vendor-logo').src = logo;  }
  const tbody = document.getElementById('line-items');  lineItems.forEach((item, index) => {    const row = document.createElement('tr');    row.innerHTML = `      <td>${index + 1}</td>      <td>${item?.job_title_custom_vendorinvoicelineitems?.subject || '—'}</td>      <td>${item?.execution_date_custom_vendorinvoicelineitems        ? new Date(item.execution_date_custom_vendorinvoicelineitems).toDateString()        : '—'}</td>      <td>${item?.quantity_custom_vendorinvoicelineitems || '—'}</td>      <td>$${item?.rate_custom_vendorinvoicelineitems || '—'}</td>      <td>$${item?.sub_total_custom_vendorinvoicelineitems || '—'}</td>    `;    tbody.appendChild(row);  });}
function downloadPDF() {  window.print();}