📝 HelperForm con tabs — ejemplo real ecom_stickycart
Actualizado: 2024-12-01
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 |
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.