
# SetupRepeatingFields.md

## How to Enable Repeatable Table Fields in NGauge DocumentDesigner

This guide explains how to make your Yii2 model provide data for a "Lines Repeatable Table" element in the document designer. This is achieved by implementing a trigger/event, which allows maximum flexibility and custom logic for data sources.

---

## Overview

The designer expects models to emit a `documentdesigner-lines-source` event. This event must provide:
- **fields**: An array of available columns (field names and optionally labels/types)
- **data**: An array of rows (each row is an associative array of field values)

The designer UI will only show the repeatable table option for models that emit this event.

---

## Step-by-Step Implementation

### 1. Register the Event Handler

In your model (e.g., Order, Invoice), register an event handler for `documentdesigner-lines-source`. This can be done in a module bootstrap, model init, or a behavior.

```php
use yii\base\Event;

Event::on(Order::class, 'documentdesigner-lines-source', function($event) {
    // Provide available fields (columns)
    $event->fields = [
        ['name' => 'product_name', 'label' => 'Product', 'type' => 'string'],
        ['name' => 'quantity', 'label' => 'Qty', 'type' => 'number'],
        ['name' => 'price', 'label' => 'Unit Price', 'type' => 'currency'],
        ['name' => 'total', 'label' => 'Total', 'type' => 'currency'],
    ];
    // Provide the data rows
    $event->data = OrderLine::find()
        ->where(['order_id' => $event->sender->id])
        ->asArray()
        ->all();
});
```

### 2. Provide Field Metadata

For best results, provide not just field names, but also labels and types. This allows the designer to:
- Show user-friendly column names
- Format cells (e.g., currency, date)
- Enable validation and conditional logic

Example:
```php
$event->fields = [
    ['name' => 'item', 'label' => 'Item', 'type' => 'string'],
    ['name' => 'amount', 'label' => 'Amount', 'type' => 'currency'],
    ['name' => 'vat', 'label' => 'VAT', 'type' => 'number'],
];
```

### 3. Custom Data Logic

You can filter, transform, or aggregate data as needed. For example, you might:
- Join with other tables
- Format values (e.g., round numbers, format dates)
- Add calculated fields

Example:
```php
$event->data = array_map(function($row) {
    $row['total'] = $row['quantity'] * $row['price'];
    return $row;
}, OrderLine::find()->where(['order_id' => $event->sender->id])->asArray()->all());
```

### 4. External APIs and Advanced Sources

If your data comes from an API or external service, fetch and format it in the event handler:
```php
$apiData = fetchOrderLinesFromApi($event->sender->id);
$event->fields = [...];
$event->data = $apiData;
```

### 5. Security Best Practices

- **Validate and sanitize** all data before sending to the designer.
- Only expose fields that are safe for display (no sensitive info).
- Use strict field types and labels to prevent confusion.
- Limit the number of rows if needed to prevent performance issues.

### 6. Designer UI Integration

- The designer will automatically detect models with the event and show the repeatable table option.
- Users can select which fields/columns to display and configure formatting.
- The designer will use the provided metadata for column headers and cell formatting.

### 7. Advanced: Dynamic Field Selection

You can allow users to select which fields to include in the table. Provide all available fields, and let the designer UI filter them.

### 8. Troubleshooting

- If the table does not appear, check that the event is registered and emits both `fields` and `data`.
- Use Yii debug tools to inspect event handling.
- Ensure your data arrays are associative and match the field names.

---

## Example: Invoice Model

```php
Event::on(Invoice::class, 'documentdesigner-lines-source', function($event) {
    $event->fields = [
        ['name' => 'item', 'label' => 'Item', 'type' => 'string'],
        ['name' => 'description', 'label' => 'Description', 'type' => 'string'],
        ['name' => 'amount', 'label' => 'Amount', 'type' => 'currency'],
        ['name' => 'vat', 'label' => 'VAT', 'type' => 'number'],
    ];
    $event->data = InvoiceLine::find()->where(['invoice_id' => $event->sender->id])->asArray()->all();
});
```

---

## Best Practices

- Keep event handler logic fast and efficient.
- Document available fields for each model.
- Use consistent field naming and types across models.
- Test with sample data to ensure correct rendering.

---

## Summary
- Implement the `documentdesigner-lines-source` event in your model.
- Provide both available fields (with metadata) and data rows.
- The designer will automatically detect and enable repeatable tables for your model.
- Use advanced logic and security practices for robust integration.
