Widget Events

Callbacks and events to respond to user actions and customize the booking flow.

Introduction

The widget emits events at different moments in the booking flow. You can subscribe to these events via callbacks in the initial configuration:

JavaScript
SalonBookIt.init({
    apiKey: 'hh_pub_live_...',
    container: '#widget',

    // Event callbacks
    onReady: (business) => { /* ... */ },
    onStepChange: (step, data) => { /* ... */ },
    onServiceSelect: (service) => { /* ... */ },
    onBookingComplete: (booking) => { /* ... */ },
    onError: (error) => { /* ... */ }
});

Events reference

onReady

Triggered when the widget has fully loaded and is ready to use.

Parameters

Parameter Type Description
business object Loaded business information

Example

JavaScript
onReady: (business) => {
    console.log('Business:', business.nombre);
    console.log('Available services:', business.servicios_count);

    // Update external UI
    document.querySelector('.loading').style.display = 'none';
}

Object business

JSON
{
    "id": "uuid-del-tenant",
    "nombre": "Mi Salon",
    "telefono": "+34612345678",
    "email": "info@misalon.com",
    "direccion": "Calle Principal 123",
    "logo_url": "https://...",
    "servicios_count": 12,
    "profesionales_count": 5,
    "moneda": "EUR",
    "simbolo_moneda": "€"
}

onStepChange

Triggered when the user advances or goes back in the booking flow.

Parameters

Parameter Type Description
step string Current step name
data object Data accumulated so far

Available steps

  • 'services' - Service selection
  • 'staff' - Professional selection
  • 'datetime' - Date and time selection
  • 'customer' - Customer data
  • 'payment' - Payment (if applicable)
  • 'confirmation' - Final confirmation

Example

JavaScript
onStepChange: (step, data) => {
    console.log('Current step:', step);

    // Analytics
    gtag('event', 'booking_step', {
        'step_name': step,
        'services_selected': data.services?.length || 0
    });

    // Update external breadcrumbs
    updateBreadcrumbs(step);
}

onServiceSelect

Triggered when the user selects or deselects a service.

Parameters

Parameter Type Description
service object Selected service
selected boolean Whether it was selected or deselected
allSelected array All currently selected services

Example

JavaScript
onServiceSelect: (service, selected, allSelected) => {
    console.log(selected ? 'Added:' : 'Removed:', service.nombre);

    // Update total price in external UI
    const total = allSelected.reduce((sum, s) => sum + s.precio, 0);
    document.querySelector('.total-price').textContent = `€${total}`;
}

onStaffSelect

Triggered when the user selects a professional.

Example

JavaScript
onStaffSelect: (staff) => {
    console.log('Professional:', staff.nombre);
    // staff = { id, nombre, imagen_url, especialidades }
}

onDateSelect

Triggered when the user selects a date and time.

Example

JavaScript
onDateSelect: (datetime) => {
    console.log('Date:', datetime.fecha);  // '2024-01-20'
    console.log('Time:', datetime.hora);    // '10:30'
}

onBookingComplete

Triggered when the booking has been created successfully (before payment if applicable).

Example

JavaScript
onBookingComplete: (booking) => {
    console.log('Booking created:', booking.id);

    // Analytics
    gtag('event', 'purchase', {
        'transaction_id': booking.id,
        'value': booking.total,
        'currency': 'EUR'
    });

    // Redirect to confirmation page
    window.location.href = `/reserva-confirmada/${booking.id}`;
}

Object booking

JSON
{
    "id": 12345,
    "codigo": "ABC123",
    "fecha": "2024-01-20",
    "hora_inicio": "10:30",
    "hora_fin": "11:00",
    "servicios": [
        { "id": 1, "nombre": "Classic cut", "precio": 25.00 }
    ],
    "profesional": {
        "id": 5,
        "nombre": "Carlos Garcia"
    },
    "cliente": {
        "nombre": "Juan Perez",
        "email": "juan@email.com",
        "telefono": "+34612345678"
    },
    "total": 25.00,
    "estado": "confirmed",
    "pago_pendiente": true
}

onPaymentComplete

Triggered when the payment has completed successfully.

Example

JavaScript
onPaymentComplete: (payment) => {
    console.log('Payment completed');
    console.log('ID:', payment.payment_intent_id);
    console.log('Amount:', payment.amount);

    // Show success message
    showSuccessMessage('Payment received!');
}

onError

Triggered when an error occurs at any point in the flow.

Example

JavaScript
onError: (error) => {
    console.error('Error:', error.code, error.message);

    // Report to error system
    Sentry.captureException(error);

    // Show message to user
    if (error.code === 'SLOT_UNAVAILABLE') {
        alert('Sorry, that time slot is no longer available.');
    }
}

Common error codes

Code Description
INVALID_API_KEY Invalid API Key
NETWORK_ERROR Connection error
SLOT_UNAVAILABLE Schedule no longer available
PAYMENT_FAILED Payment error
VALIDATION_ERROR Invalid form data

onClose

Triggered when the user closes the widget (modal mode only).

Example

JavaScript
onClose: () => {
    console.log('Widget closed');

    // Ask if they want to save draft
    if (hasUnsavedData()) {
        saveBookingDraft();
    }
}

Widget Methods

In addition to events, you can control the widget programmatically:

JavaScript
// Get widget reference
const widget = SalonBookIt.init({ ... });

// Open modal (modal/button mode only)
widget.open();

// Close modal
widget.close();

// Go to a specific step
widget.goToStep('services');

// Reset the widget
widget.reset();

// Destroy the widget
widget.destroy();