Con la interfaz JavaScript conecta el configurador con su propia lógica en la página: mostrar el precio en su barra de compra, trasladar la selección a un formulario propio, establecer valores desde fuera o guardar una configuración y volver a abrirla más tarde. Para ello, el motor de frontend V3 pone a disposición el objeto window.Configento, tanto si llega a la página mediante el fragmento HTML como mediante un plugin de tienda. Esta guía muestra con ejemplos listos para usar cómo resolver tareas habituales y cómo adaptar a V3 el código escrito para el motor Legacy. Cada método con su firma, todos los eventos, tipos de datos y ajustes figuran en la Referencia de la API JavaScript (V3).
Dónde está disponible la interfaz
window.Configento existe en todas las páginas que cargan el motor V3:
| Integración | Interfaz JavaScript |
|---|---|
| Fragmento HTML (tarjeta HTML5 (V3 Beta)) | Siempre |
| Shopify | Siempre |
| PrestaShop | Siempre |
| Magento 2 | Si el componente está en V3 (Beta) o necesita V3; consulte Motor de frontend: Legacy o V3 |
| Shopware 6 y el fragmento HTML5 clásico | No: ambos cargan Legacy |
Los plugins usan la interfaz ellos mismos, por ejemplo para llevar el precio y la configuración al carrito. Su propio código funciona en paralelo: no tiene que desactivar nada.
Primeros pasos
<script>
window.addEventListener('DOMContentLoaded', function () {
Configento.ready.then(function () {
var configurador = Configento.first();
configurador.on('price', function (p) {
document.querySelector('#mi-precio').textContent = p.total.toFixed(2) + ' ' + p.currency;
});
configurador.on('change', function () {
console.log('Anchura:', configurador.getValue('anchura'));
});
});
});
</script>
Tres reglas que evitan casi todos los problemas:
- Espere a
Configento.ready. Solo entonces se han cargado todos los configuradores de la página. Si llama a un método antes, este indica que el configurador aún no está listo. window.Configentosolo existe cuando se ha ejecutado el scriptconfigento.js. Se carga condefer, es decir, después de construir la página. Por eso, inicie su código enDOMContentLoadedo más tarde, no directamente en un script del<head>.- El configurador busca sus lugares una sola vez, al cargar: cada elemento con
data-configento. Los elementos que su código inserte más tarde no se reconocen.
A las características se dirige por su nombre interno (ID) y a los valores por el campo Valor. Los ID numéricos también funcionan.
Cargar más rápido y reservar espacio
Tres ajustes en el elemento con data-configento ayudan mientras se construye la página:
| Atributo | Efecto |
|---|---|
data-configento-min-height="640px" |
Reserva la altura mientras se carga el configurador; la página de debajo no salta cuando aparece el primer paso. Después, la altura vuelve a ajustarse. |
data-configento-min-height-keep |
Mantiene la altura también después de la carga |
data-configento-component-json='{…}' |
El componente directamente en la página, tal como lo devuelve GET /api/v3/components/{id}. Así se omite la petición al cargar. Solo tiene sentido si su página mantiene actualizada en el servidor la versión publicada: tras publicar, la página debe entregar la nueva versión. |
En el atributo JSON data-configento-config se llaman minHeight, minHeightKeep y component.
Además, conviene añadir en el <head> una indicación para que el navegador establezca pronto la conexión con la nube:
<link rel="preconnect" href="https://cloud.configento.app" crossorigin>
El configurador carga el componente nada más iniciarse el script. Los visitantes que vuelven no lo cargan de nuevo: si no ha cambiado desde su última visita, el servidor solo lo confirma brevemente.
Mostrar el precio en su barra de compra
window.addEventListener('DOMContentLoaded', function () {
Configento.ready.then(function () {
var k = Configento.first();
var campo = document.querySelector('#precio-barra-compra');
k.on('price', function (p) {
campo.textContent = p.total.toLocaleString('es-ES', { style: 'currency', currency: p.currency });
});
});
});
price llega una vez justo después de cargar y luego con cada cambio de precio. Sin código propio también funciona data-configento-price-mount="#precio-barra-compra": el configurador dibuja entonces el precio él mismo en su elemento.
Trasladar la selección a un formulario propio
Para una solicitud mediante su propio formulario, compruebe la configuración con finalize() y escriba el resultado en campos ocultos:
<form id="solicitud" action="/solicitud" method="post">
<input type="hidden" name="configuracion">
<input type="hidden" name="resumen">
<input type="hidden" name="referencia">
<input type="hidden" name="precio">
<button type="submit">Solicitar presupuesto</button>
</form>
<script>
document.querySelector('#solicitud').addEventListener('submit', function (e) {
e.preventDefault();
var formulario = e.target;
var k = Configento.first();
k.finalize().then(function (resultado) {
if (!resultado.ok) return; // los errores se muestran ahora en la característica
formulario.configuracion.value = JSON.stringify(resultado.payload);
formulario.resumen.value = k.getSummary({ format: 'text', separator: '\n' });
formulario.referencia.value = k.getCombinedSku();
formulario.precio.value = resultado.priceTotal;
formulario.submit();
});
});
</script>
finalize() muestra en la característica los campos obligatorios que faltan y los errores de las reglas, igual que el botón de acción, pero no envía nada por sí mismo. getCombinedSku() devuelve la referencia combinada a partir de los valores elegidos, p. ej. CL-W-GR; también figura como _combined_sku en resultado.payload.
Preseleccionar valores
A las características se dirige por su nombre interno y a los valores por el campo Valor:
Configento.ready.then(function () {
var k = Configento.first();
k.selectValue('color', 'antracita'); // selección, botones de radio, lista con imágenes
k.toggleValue('accesorios', 'manivela'); // casilla de verificación, selección múltiple
k.setText('anchura', '120'); // campo de entrada
k.setQuantity('tornillos', 'm6', 4); // selección múltiple con cantidades
});
Cada llamada actúa como un clic de su cliente: reglas, fórmulas y precio se recalculan. Con resetSelection('color') restablece una característica.
Desde la dirección: así recoge ?color=antracita&anchura=120:
var parametros = new URLSearchParams(location.search);
if (parametros.has('anchura')) k.setText('anchura', parametros.get('anchura'));
if (parametros.has('color')) k.selectValue('color', parametros.get('color'));
Variante cambiada en la tienda: si hay fórmulas que dependen de atributos de producto como la anchura o el peso, pase los nuevos valores con k.setProductAttributes({ anchura: '140' }). La selección se mantiene y todo se recalcula. Los valores iniciales se indican al integrar el configurador en el atributo JSON como "productAttributes".
Cambiar de idioma
Si la selección de idioma está activada, showLanguageSelect() vuelve a mostrar las banderas, por ejemplo para un botón «Cambiar idioma»:
<button type="button" onclick="Configento.first().showLanguageSelect()">Cambiar idioma</button>
La selección actual del configurador se conserva; tras la nueva elección continúa en el nuevo idioma. Sin la selección de idioma activada, o con un componente de un solo idioma, no ocurre nada. También puede llamar al método antes de que el configurador se haya cargado.
Controlar el asistente y los grupos
Con el diseño Pestañas y en el Asistente, el configurador muestra siempre un grupo. Con estos métodos construye su propia indicación de pasos:
<ol id="pasos"></ol>
<script>
Configento.ready.then(function () {
var k = Configento.first();
var lista = document.querySelector('#pasos');
function dibujar() {
var activo = k.getActiveGroup();
lista.innerHTML = '';
k.getGroups().forEach(function (grupo) {
var punto = document.createElement('li');
punto.textContent = grupo.title;
if (activo && grupo.id === activo.id) punto.className = 'activo';
punto.onclick = function () { k.setActiveGroup(grupo.id); };
lista.appendChild(punto);
});
}
dibujar();
k.on('group', dibujar); // tras cada cambio de paso
k.on('change', dibujar); // las reglas pueden mostrar y ocultar grupos
});
</script>
getGroups() devuelve los grupos mostrados con id, key, index y title, y getActiveGroup(), el actual. setActiveGroup() cambia por ID o nombre interno y, hacia delante, comprueba cada paso del camino como Siguiente; nextGroup() y prevGroup() equivalen a Siguiente y Atrás.
key es el nombre interno del grupo. Lo asigna en el editor, en los ajustes del grupo, en Nombre interno (ID), p. ej. vehiculo. A diferencia de la posición, no cambia cuando reordena los grupos o una regla oculta un grupo, y en el código se lee mejor que un número. El elemento del grupo mostrado lo lleva además como data-configento-group-key.
Comprobación propia antes del cambio de paso
Con setStepGuard() hace usted mismo una comprobación antes de que su cliente avance, por ejemplo de una fecha de nacimiento o de un número de identificación del vehículo. La comprobación se ejecuta después de la comprobación integrada de campos obligatorios, y solo hacia delante:
k.setStepGuard(function (paso) {
if (paso.from.key !== 'titular') return true;
if (esMayorDeEdad(k.getValue('fecha_nacimiento'))) return true;
return [{ characteristic: 'fecha_nacimiento', message: 'El titular debe ser mayor de edad.' }];
});
true deja avanzar al cliente, false lo retiene sin mensaje y una lista lo retiene y muestra cada mensaje en la característica indicada. La función también puede devolver una promesa, por ejemplo para una comprobación a través de la red; hasta la respuesta, Siguiente y Atrás quedan bloqueados. Si lanza un error, el paso cambia de todos modos: su cliente no debe quedarse atascado.
Desactivar la navegación integrada
Si construye usted mismo la indicación de pasos, oculte la integrada:
data-configento-wizard-nav |
Efecto |
|---|---|
full (predeterminado) |
Pestañas, barra de progreso, Atrás y Siguiente |
buttons |
Solo Atrás y Siguiente |
none |
Nada de eso; su código controla los pasos |
El mismo ajuste existe en el editor en Ajustes → General → Diseño de grupo → Navegación del asistente (V3); el atributo del elemento tiene prioridad.
Guardar y volver a abrir una configuración
storeAsset() guarda la configuración actual y devuelve { id, url }. Con el id construye un enlace profundo: la dirección de la página de producto con ?dl= y el id. Si alguien abre esa dirección, V3 restaura por sí mismo la configuración en el primer configurador de la página.
k.storeAsset().then(function (guardado) {
var enlace = new URL(location.href);
enlace.searchParams.set('dl', guardado.id);
navigator.clipboard.writeText(enlace.toString());
}).catch(function (error) {
if (error instanceof Configento.CloudError && error.code === 'NO_SELECTIONS') {
alert('Seleccione primero alguna opción.');
}
});
Restaurarla usted mismo, por ejemplo en uno concreto de varios configuradores:
Configento.loadAsset(id, { instance: k }).then(function (datos) {
k.restoreFromAssetJson(datos);
});
En la vista previa del admin no se puede guardar nada (CONFIG_MISSING); pruebe en su sitio web o en la tienda. Todos los códigos de error figuran en la referencia.
Ventana propia para la selección de imágenes
Algunas características abren una ventana, por ejemplo una lista con imágenes en vista ampliada. De forma predeterminada, V3 dibuja esta ventana él mismo. Si debe parecerse a las ventanas de su tienda, pase un adaptador:
Configento.setModalAdapter({
openOverlay: function (args) {
// args.title, args.container (lo rellena el configurador), args.onClose
var ventana = miTienda.abrirVentana(args.title, args.container, args.onClose);
return { close: function () { ventana.cerrar(); } };
}
});
Inserte args.container en su ventana y llame a args.onClose() cuando su cliente la cierre. El configurador llama a close() cuando quiere cerrar la ventana por sí mismo. Establezca el adaptador en cuanto exista window.Configento y antes de que su cliente abra una ventana. El plugin de Magento ya incluye un adaptador para las ventanas de Magento.
Migrar desde Legacy
Para el motor Legacy existía una interfaz propia y más antigua: ajustes en el objeto _configentoSettings, el objeto CONFIGENTO_PRODUCT, objetos globales como Justselling_Configento_App_Api y eventos jQuery como configentoUpdateOptionsInDomAfter. Si cambia a V3, cambian tres cosas:
- Integración: en lugar de
_configentoSettingsyhtml5.js, use el fragmento V3 con atributosdata-configento-*. Cómo hacerlo se explica en Integración fragmento HTML. El token es otro; procede de la tarjeta HTML5 (V3 Beta). - Su propio código: a partir de ahora se dirige a
window.Configento, o sigue funcionando mediante el script de compatibilidad. - Funciones: lo que solo puede hacer Legacy se explica en Motor de frontend: Legacy o V3.
Ajustes
Legacy (_configentoSettings) |
V3 |
|---|---|
_template |
data-component-id |
_customer |
data-configento-customer |
_token |
data-configento-token: token nuevo de la tarjeta HTML5 (V3 Beta) |
_cloudbase |
data-configento-cloud-base-url |
_taxrate |
data-configento-tax-rate |
_currencyCode |
data-configento-currency |
_cssPathCombinedImage o .configento-combinedImage |
data-configento-combined-image-mount |
Elemento #configento-price |
data-configento-price-mount |
Elemento #configurator1 |
Un elemento con data-configento |
_loadjQuery, _loadChart, _loadDropzone |
Desaparecen: V3 lo trae todo y no necesita jQuery |
Ya no necesita _debug, _development, _cloudport ni _productOptionId.
Opción 1: script de compatibilidad
Sobre todo los temas de tienda han acumulado durante años código que accede a los objetos antiguos. Para que siga funcionando con V3, cargue además configento-compat.js antes de configento.js:
<script src="https://cloud.configento.app/configento-v3/configento-compat.js" defer></script>
<script src="https://cloud.configento.app/configento-v3/configento.js" defer></script>
El plugin de Magento lo carga por sí mismo con V3. El script asume:
| Legacy | Qué hace el script con ello |
|---|---|
Eventos configentoUpdateOptionsInDomBefore/…After y configentoUpdateHeaderInDomBefore/…After |
Se disparan en document con cada cambio; accesibles con jQuery .on() y con addEventListener |
CONFIGENTO_PRODUCT.setPrice(precio) |
Se llama con el precio total en cada cambio de precio, siempre que su página defina CONFIGENTO_PRODUCT |
Elemento #configurator1 |
Se convierte en el lugar del configurador; el ID del componente procede de CONFIGENTO_PRODUCT.getTemplateId() |
Justselling_Configento_App_Helper.getConfigurator(), getBackendUrl() |
Devuelven el configurador V3 o la dirección de la nube, respectivamente |
Justselling_Configento_App_Webshop.finalizeAction(listo) |
Comprueba con finalize(), escribe la configuración en los campos ocultos del formulario del carrito y después llama a listo |
Justselling_Configento_App_CloudAsset.storeCloudAsset(…) |
Guarda con storeAsset(). La devolución de llamada solo recibe el ID, no la carpeta ni el nombre de archivo. |
Justselling_Configento_App_Wizard.validateForm() y las demás funciones de comprobación |
Devuelven siempre true: la comprobación se hace al finalizar |
Justselling_Configento_App_Wizard.setActivateGroup(numero) |
Cambia al grupo situado en esa posición, sin comprobación |
setDisableGroup, setEnableGroup, updateWizard |
No hacen nada |
Si su código ya ha definido uno de estos objetos, se conserva su versión.
Lo que el script no asume: no lee _configentoSettings ni crea CONFIGENTO_PRODUCT; en una página HTML sencilla, hasta ahora eso lo hacía html5.js. Por tanto, allí necesita en cualquier caso los atributos data-configento-*. Tampoco se asumen Justselling_Configento_App_Api, Justselling_Configento_App_Summary ni los demás eventos. Para ellos están los equivalentes de abajo.
Opción 2: reescribir para la nueva interfaz
A la larga, el código con window.Configento es más claro: recibe los contenidos con los eventos, lanza errores comprensibles y no depende de los ID de los elementos. Así se corresponden las llamadas antiguas y las nuevas; todo lo nuevo va dentro de Configento.ready.then(…), sobre un configurador k = Configento.first():
| Legacy | V3 |
|---|---|
Justselling_Configento_App_Helper.getConfigurator() |
Configento.first() o Configento.forElement(…) |
Justselling_Configento_App_Api.getOptionValue(caracteristica) |
k.getValue('caracteristica') |
Justselling_Configento_App_Api.setOptionValue(caracteristica, valor), setOptionValues([…]) |
Según el tipo de dato, k.selectValue(), k.toggleValue(), k.setText() o k.setQuantity() |
Justselling_Configento_App_Api.setEventHook(…) |
k.on('change', …); igualmente price, finalize, error y group |
setEventHook('configentoValidateGroupBefore', fn) (impedir el cambio de paso) |
k.setStepGuard(fn) |
getConfigurator().getActiveGroup() |
k.getActiveGroup() |
Justselling_Configento_App_Wizard.setActivateGroup(numero) |
k.setActiveGroup(id o nombre interno) |
Evento configentoSetActiveGroupAfter |
k.on('group', …) |
CONFIGENTO_PRODUCT.setPrice(precio) |
k.on('price', function (p) { … p.total … }), o data-configento-price-mount |
Justselling_Configento_App_Summary.getSummaryAsText() |
k.getSummary() |
Justselling_Configento_App_Wizard.validateForm() |
k.finalize() → ok |
Justselling_Configento_App_Webshop.finalizeAction(listo) |
k.finalize().then(…) |
Justselling_Configento_App_CloudAsset.storeCloudAsset(…) |
k.storeAsset() → { id, url } |
Campo #configurator1-header o generateHeaderValue() |
k.getHeaderValue() (Base64, como hasta ahora) o k.getAssetPayload() (JSON) |
Eventos configentoUpdateOptionsInDomAfter, configentoUpdateHeaderInDomAfter, configentoApiSetOptionValueAfter |
k.on('change', …) |
Evento configentoRenderSummaryAfter |
k.on('change', …) y, dentro, k.getSummary() |
Evento configentoFinalizeActionAfter |
k.on('finalize', …) |
Eventos configentoRenderAfter, configentoLoadTemplateAfter |
Configento.ready |
| Eventos de gráficos, imágenes de vista previa y subidas de archivos | Sin equivalente |
?dl=… y ?tb=1 en la dirección |
Sin cambios |
Preseleccionar características mediante la dirección, p. ej. ?anchura=120 |
No integrado: unas pocas líneas, véase Preseleccionar valores |
Cómo preseleccionar características mediante la dirección se muestra en Preseleccionar valores.
Diferencia en los eventos: los eventos de Legacy solo disparaban manejadores jQuery y casi nunca entregaban datos. Los eventos de V3 pasan directamente la nueva selección o el nuevo precio: ya no tiene que leer nada del DOM.
Solución de problemas
Configento is not defined: su código se ejecuta antes de queconfigento.jsse haya cargado. Inícielo enDOMContentLoadedy espere aConfigento.ready. Compruebe también si la página carga V3 (véase arriba).Configento instance not readyal llamar a un método: el configurador todavía se está cargando. Llame a los métodos solo dentro deConfigento.ready.then(…).Configento.first()devuelvenull: en la página no hay ningún elemento condata-configento, o se insertó después de la carga.- Una llamada como
selectValue()provoca un error: el nombre interno o el valor no es correcto, o el tipo de dato no encaja con el método. Se distingue entre mayúsculas y minúsculas; el nombre lo encuentra en el editor en Nombre interno (ID). storeAsset()indicaCONFIG_MISSING: en la vista previa del admin no se puede guardar nada. Pruebe en su sitio web o en la tienda.- El código antiguo del tema provoca errores como
Justselling_Configento_App_Wizard is not defined: falta el script de compatibilidad o está después deconfigento.js.