---
title: HelperForm con tabs — ejemplo real ecom_stickycart
section: examples
slug: helperform-real
description: Ejemplo real de HelperForm con tabs, color pickers, switches y select multiple extraido del modulo ecom_stickycart para PrestaShop.
keywords: prestashop helperform ejemplo real tabs color switch select multiple configuracion modulo
last_updated: 2024-12-01
source_url: "https://ayudaprestashop.es/examples/helperform-real"
---

# HelperForm con tabs — ejemplo real ecom_stickycart

> Ejemplo real de HelperForm con tabs, color pickers, switches y select multiple extraido del modulo ecom_stickycart para PrestaShop.

> **[TIP] Codigo real de produccion**
>
> Este ejemplo esta extraido del modulo ecom_stickycart (Sticky Add to Cart Pro), un modulo real en produccion. No es codigo de tutorial: es codigo que funciona en tiendas reales.

## Que hace este modulo

ecom_stickycart muestra una barra sticky de 'Añadir al carrito' en la pagina de producto. El admin puede configurar layout, colores, animacion, posicion y funcionalidades desde el BO usando un formulario HelperForm con tabs.

## Constructor y install

*Constructor con $this->trans() y install con hooks*

```php
<?php
class Ecom_stickycart extends Module
{
    public function __construct()
    {
        $this->name = 'ecom_stickycart';
        $this->tab = 'front_office_features';
        $this->version = '2.0.0';
        $this->author = 'Ecom Experts';
        $this->need_instance = 0;
        $this->ps_versions_compliancy = ['min' => '1.7', 'max' => _PS_VERSION_];
        $this->bootstrap = true;

        parent::__construct();

        // Usar $this->trans() con dominio para sistema moderno de traducciones
        $this->displayName = $this->trans(
            'Sticky Add to Cart Pro', [], 'Modules.Ecomstickycart.Admin'
        );
        $this->description = $this->trans(
            'Professional sticky add to cart bar.', [], 'Modules.Ecomstickycart.Admin'
        );
    }

    // Necesario para que PS use archivos .xlf en lugar de legacy
    public function isUsingNewTranslationSystem()
    {
        return true;
    }

    public function install()
    {
        return parent::install()
            && $this->registerHook('displayHeader')
            && $this->registerHook('displayFooter')
            && $this->registerHook('displayBackOfficeHeader')
            && $this->registerHook('actionFrontControllerSetMedia')
            && $this->setConfigDefaults();
    }

    // Valores por defecto separados en metodo propio (buena practica)
    protected function setConfigDefaults()
    {
        $defaults = [
            'ECOM_STICKY_LAYOUT'        => 'classic',
            'ECOM_STICKY_BG_COLOR'      => '#ffffff',
            'ECOM_STICKY_TXT_COLOR'     => '#333333',
            'ECOM_STICKY_BTN_COLOR'     => '#2fb5d2',
            'ECOM_STICKY_POSITION'      => 'bottom',
            'ECOM_STICKY_SCROLL_TRIGGER' => '300',
            'ECOM_STICKY_ANIMATION'     => 'fade',
            'ECOM_STICKY_SHOW_QTY'      => '1',
            'ECOM_STICKY_MOBILE_OPTIMIZED' => '1',
            'ECOM_STICKY_CUSTOM_CSS'    => '',
        ];
        foreach ($defaults as $key => $value) {
            Configuration::updateValue($key, $value);
        }
        return true;
    }
}
```

## getContent — procesar formulario

*Patron clasico: isSubmit → process → display*

```php
<?php
public function getContent()
{
    $output = '';

    // Guardar configuracion
    if (Tools::isSubmit('submitEcomStickyCart')) {
        $this->processConfiguration();
        $output .= $this->displayConfirmation(
            $this->trans('Settings updated successfully.', [], 'Admin.Global')
        );
    }

    // Boton de reset a valores por defecto
    if (Tools::isSubmit('submitEcomStickyCartReset')) {
        $this->setConfigDefaults();
        $output .= $this->displayConfirmation(
            $this->trans('Settings reset to defaults.', [], 'Admin.Global')
        );
    }

    return $output . $this->renderForm();
}

protected function processConfiguration()
{
    $configs = [
        'ECOM_STICKY_LAYOUT', 'ECOM_STICKY_BG_COLOR',
        'ECOM_STICKY_TXT_COLOR', 'ECOM_STICKY_BTN_COLOR',
        'ECOM_STICKY_POSITION', 'ECOM_STICKY_SCROLL_TRIGGER',
        'ECOM_STICKY_ANIMATION', 'ECOM_STICKY_SHOW_QTY',
        'ECOM_STICKY_MOBILE_OPTIMIZED', 'ECOM_STICKY_CUSTOM_CSS',
    ];

    foreach ($configs as $config) {
        $value = Tools::getValue($config);
        // Castear valores numericos
        if ($config === 'ECOM_STICKY_SCROLL_TRIGGER') {
            $value = (int) $value;
        }
        Configuration::updateValue($config, $value);
    }

    // Caso especial: select multiple devuelve array
    $excludeCategories = Tools::getValue('ECOM_STICKY_EXCLUDE_CATEGORIES');
    if (is_array($excludeCategories)) {
        Configuration::updateValue(
            'ECOM_STICKY_EXCLUDE_CATEGORIES',
            implode(',', array_map('intval', $excludeCategories))
        );
    } else {
        Configuration::updateValue('ECOM_STICKY_EXCLUDE_CATEGORIES', '');
    }
}
```

## renderForm — HelperForm completo

*HelperForm con tabs, color, select, switch y multiple*

```php
<?php
protected function renderForm()
{
    // Preparar opciones de categorias para el select multiple
    $categories = Category::getSimpleCategories($this->context->language->id);
    $categoryOptions = [];
    foreach ($categories as $cat) {
        $categoryOptions[] = ['id' => $cat['id_category'], 'name' => $cat['name']];
    }

    $fields_form = [
        'form' => [
            'legend' => [
                'title' => $this->trans('Sticky Cart Configuration', [], 'Modules.Ecomstickycart.Admin'),
                'icon' => 'icon-cogs',
            ],
            // ══ TABS: Agrupan campos visualmente ══
            'tabs' => [
                'general'  => 'General Settings',
                'visual'   => 'Visual Settings',
                'features' => 'Feature Settings',
            ],
            'input' => [
                // ── TAB GENERAL: select, text ──
                [
                    'type' => 'select',
                    'label' => 'Layout',
                    'name' => 'ECOM_STICKY_LAYOUT',
                    'tab' => 'general',       // ← Asigna al tab
                    'options' => [
                        'query' => [
                            ['id' => 'classic', 'name' => 'Classic Bar'],
                            ['id' => 'minimal', 'name' => 'Minimal (Floating)'],
                            ['id' => 'modern',  'name' => 'Modern (Glassmorphism)'],
                        ],
                        'id' => 'id', 'name' => 'name',
                    ],
                ],
                [
                    'type' => 'text',
                    'label' => 'Scroll Trigger (px)',
                    'name' => 'ECOM_STICKY_SCROLL_TRIGGER',
                    'tab' => 'general',
                    'desc' => 'How far to scroll before showing the sticky cart.',
                    'col' => 2,               // ← Ancho de columna
                ],

                // ── TAB VISUAL: color, textarea ──
                [
                    'type' => 'color',         // ← Color picker nativo
                    'label' => 'Background Color',
                    'name' => 'ECOM_STICKY_BG_COLOR',
                    'tab' => 'visual',
                ],
                [
                    'type' => 'color',
                    'label' => 'Button Color',
                    'name' => 'ECOM_STICKY_BTN_COLOR',
                    'tab' => 'visual',
                ],
                [
                    'type' => 'textarea',
                    'label' => 'Custom CSS',
                    'name' => 'ECOM_STICKY_CUSTOM_CSS',
                    'tab' => 'visual',
                    'col' => 9, 'rows' => 5,
                ],

                // ── TAB FEATURES: switch, select multiple ──
                [
                    'type' => 'switch',        // ← Toggle on/off
                    'label' => 'Show Quantity Selector',
                    'name' => 'ECOM_STICKY_SHOW_QTY',
                    'tab' => 'features',
                    'is_bool' => true,
                    'values' => [
                        ['id' => 'active_on',  'value' => 1, 'label' => 'Yes'],
                        ['id' => 'active_off', 'value' => 0, 'label' => 'No'],
                    ],
                ],
                [
                    'type' => 'select',
                    'label' => 'Exclude Categories',
                    'name' => 'ECOM_STICKY_EXCLUDE_CATEGORIES[]', // ← [] para multiple
                    'tab' => 'features',
                    'class' => 'chosen',       // ← Plugin chosen.js
                    'multiple' => true,        // ← Select multiple
                    'options' => [
                        'query' => $categoryOptions,
                        'id' => 'id', 'name' => 'name',
                    ],
                ],
            ],
            'submit' => ['title' => 'Save'],
        ],
    ];

    // ── Configurar el HelperForm ──
    $helper = new HelperForm();
    $helper->show_toolbar = false;
    $helper->table = $this->table;
    $helper->module = $this;
    $helper->default_form_language = $this->context->language->id;
    $helper->identifier = $this->identifier;
    $helper->submit_action = 'submitEcomStickyCart';
    $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
        . '&configure=' . $this->name
        . '&tab_module=' . $this->tab
        . '&module_name=' . $this->name;
    $helper->token = Tools::getAdminTokenLite('AdminModules');
    $helper->tpl_vars = [
        'fields_value' => $this->getConfigFieldsValues(),
    ];

    return $helper->generateForm([$fields_form]);
}
```

## getConfigFieldsValues

*Devolver valores actuales para los campos*

```php
<?php
protected function getConfigFieldsValues()
{
    // Caso especial: categorias excluidas guardadas como string "1,2,3"
    // Necesita convertirse a array para el select multiple
    $excludeStr = Configuration::get('ECOM_STICKY_EXCLUDE_CATEGORIES');
    $excludeArr = !empty($excludeStr) ? explode(',', $excludeStr) : [];

    return [
        'ECOM_STICKY_LAYOUT'        => Configuration::get('ECOM_STICKY_LAYOUT'),
        'ECOM_STICKY_BG_COLOR'      => Configuration::get('ECOM_STICKY_BG_COLOR'),
        'ECOM_STICKY_TXT_COLOR'     => Configuration::get('ECOM_STICKY_TXT_COLOR'),
        'ECOM_STICKY_BTN_COLOR'     => Configuration::get('ECOM_STICKY_BTN_COLOR'),
        'ECOM_STICKY_POSITION'      => Configuration::get('ECOM_STICKY_POSITION'),
        'ECOM_STICKY_SCROLL_TRIGGER' => Configuration::get('ECOM_STICKY_SCROLL_TRIGGER'),
        'ECOM_STICKY_ANIMATION'     => Configuration::get('ECOM_STICKY_ANIMATION'),
        'ECOM_STICKY_SHOW_QTY'      => Configuration::get('ECOM_STICKY_SHOW_QTY'),
        'ECOM_STICKY_MOBILE_OPTIMIZED' => Configuration::get('ECOM_STICKY_MOBILE_OPTIMIZED'),
        'ECOM_STICKY_CUSTOM_CSS'    => Configuration::get('ECOM_STICKY_CUSTOM_CSS'),
        // ¡OJO! El nombre incluye [] para select multiple
        'ECOM_STICKY_EXCLUDE_CATEGORIES[]' => $excludeArr,
    ];
}
```

## Patrones a destacar

| Patron | Donde se usa | Por que es buena practica |
| --- | --- | --- |
| Tabs en HelperForm | 'tabs' => ['general' => ..., 'visual' => ...] | Agrupa opciones, mejor UX cuando hay muchos campos |
| setConfigDefaults() | install() y boton reset | Metodo separado reutilizable, no repite codigo |
| Color picker | 'type' => 'color' | Nativo de PS, no necesita JS extra |
| Select multiple + chosen | 'multiple' => true, 'class' => 'chosen' | UX de busqueda en select con muchas opciones |
| Cast (int) en process | $value = (int) $value | Sanitizar valores numericos antes de guardar |
| isUsingNewTranslationSystem() | return true | Activa sistema .xlf moderno (PS 1.7.6+) |
| Array a string para Configuration | implode(',', array_map('intval', ...)) | Configuration::updateValue solo guarda strings |


---

*Fuente: [https://ayudaprestashop.es/examples/helperform-real](https://ayudaprestashop.es/examples/helperform-real). Version Markdown generada automaticamente para consumo por LLMs.*
