Prestashop 1.5 ofrece la posibilidad de añadir campos personalizados a un producto, concretamente en el apartado Productos > Personalización. Estos campos sólo pueden ser cajas de texto, pero se podría aprovechar mas esta sección.
Se me ocurre p.ej si tenemos un producto muy personalizable como puede ser una camiseta donde se podría seleccionar el color de base y luego ir añadiendo un diseño y demás. Para el color de base ya tenemos el generador de combinaciones que nos ayuda a generar “subproductos” de ese producto base y cada una de esas combinaciones tiene su stock y su impacto en el precio.
Eso esta muy bien en la mayoría de casos, pero en el caso de las camisetas podemos tener un producto altamente customizable que se cree bajo demanda, es decir tenemos un color a escoger entre un montón (incluso podría utilizarse un color picker) y no queremos mantener el stock de cada uno de ellos, esto es, una vez hecho el pedido se “creara” el color de la camiseta (como cuando vamos a comprar pintura).
En una primera aproximación, vale la pena centrarse en usar código javascript para modificar un campo de texto ya existente de la forma menos intrusiva posible. Entonces partimos de por ejemplo un campo color de base que sera el selector obligatorio y otro campo de texto normal para probar que nuestro código no tenga efectos laterales con los demás campos.
Modificando product.tpl
La plantilla que hay que tocar es product.tpl. Estas modificaciones las realizamos en nuestro tema (p.ej copia del tema por defecto). Ponemos el código al principio de la sección <script>
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<script type="text/javascript"> // <![CDATA[ //En el caso de que estemos en nuestro producto con el combo que es el primero (Por eso el 0 en el array $customizationFields) {if $product->reference =='camis0001' } {assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$customizationFields[0].id_customization_field} var comboVal=''; {if isset($textFields.$key)} comboVal='{$textFields.$key}'; {/if} //Llamamos al javascript camis001_texto_to_combo(comboVal); //Sobreescribimos la función que vacia los campos de texto personalizados y comprueba los campos obligatorios emptyCustomizations=camis001_emptyCustomizations; checkCustomizations=camis001_checkCustomizations; {/if} // PrestaShop internal settings |
En este código verificamos que estamos viendo el producto que interesa modificar. Utilizamos las variables smarty $textFields
y $customizationFields
. $textFields
es un array asociativo que contiene los valores de los campos personalizables (en caso de haberlos guardado con el botón guardar)
1 2 3 4 5 |
$textFields Smarty_Variable Object (3) ->value = Array (1) textFields_8_3 => "Azul" ->nocache = false ->scope = "Smarty root" |
La clave de ese array asociativo esta compuesta por la cadena textFields_Id del producto_Id del campo personalizable. Para encontrar el id del campo personalizable necesitamos de la variable $customizationFields
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$customizationFields Smarty_Variable Object (3) ->value = Array (2) 0 => Array (5) id_customization_field => "3" type => "1" required => "1" name => "Color de base" id_lang => "1" 1 => Array (5) id_customization_field => "9" type => "1" required => "0" name => "Campo de texto" id_lang => "1" ->nocache = false ->scope = "Smarty root" |
Este array esta ordenado tal y como lo hemos definido en el back office, así que cogiendo el primer elemento encontraremos el id que interesa.
Añadiendo código javascript en product.js
El código javascript lo podemos poner al final de de product.js.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/*Funcion que convierte el texto en un combo y mueve el tab para que la personalización del producto sea la primera */ function camis001_texto_to_combo(val){ var option0='<option value=""></option>'; var option1='<option value="Blanco" '+((val=='Blanco')?"selected":"")+' >Blanco</option>'; var option2='<option value="Rojo" '+((val=='Rojo')?"selected":"")+' >Rojo</option>'; var option3='<option value="Azul" '+((val=='Azul')?"selected":"")+' >Azul</option>'; var option4='<option value="Negro" '+((val=='Negro')?"selected":"")+' >Negro</option>'; $(document).ready(function () { $("#textField0").replaceWith('<select id="textField0" name="'+$("#textField0").attr("name")+'" class="'+$("#textField0").attr("class")+' ">' + option0+ option1 + option2 + option3 + option4 + '</select>'); //Movemos las tabs $('a[href="#idTab10"]').parent().prependTo($('#more_info_tabs')); $("#more_info_tabs").idTabs("idTab10"); }); } |
Aquí hacemos el cambio de caja de texto a selector utilizando jquery. El identificador del campo de texto será textField0
porque es el primero. Aprovechamos para mover también el tab de personalización de producto para que aparezca el primero.
El problema que surge es que al añadir a la cesta el código javascript del módulo blockcart usa dos funciones que se encuentran en tools.js. Una se ocupa de vaciar el campo de texto una vez añadido el producto (emptyCustomizations
) y otra de validar los campos obligatorios (checkCustomizations
). Estas dos funciones no tienen en cuenta a nuestro recién añadido selector. Sobrescribimos estas dos funciones, copiamos íntegramente su código y añadimos una condición para que tenga en cuenta si el campo es un selector.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
// función idéntica a la original emptyCustomizations en tools.js linea 218 // pero teniendo en cuenta que en nuestro caso tenemos un input de tipo select que no necesita resetar el html function camis001_emptyCustomizations(){ if(typeof(customizationFields) == 'undefined') return; $('.customization_block .success').fadeOut(function(){ $(this).remove(); }); $('.customization_block .error').fadeOut(function(){ $(this).remove(); }); for (var i = 0; i < customizationFields.length; i++) { var el=$('#' + customizationFields[i][0]); if(!el.is('select')){//Si es un select no hay que vaciar el html el.html(''); } el.val(''); } } //función idéntica a la original checkCustomizations en tools.js linea 204 //pero teniendo en cuenta que en nuestro caso tenemos un input de tipo select function camis001_checkCustomizations() { var pattern = new RegExp(' ?filled ?'); if (typeof customizationFields != 'undefined') for (var i = 0; i < customizationFields.length; i++) { var el=$('#' + customizationFields[i][0]); /* If the field is required and empty then we abort */ if(el.is('select')){//Si es un select no hace falta mirar el html, con mirar el valor tenemos suficiente if (parseInt(customizationFields[i][1]) == 1 && (el.val().length == 0) && !pattern.test(el.attr('class'))) return false; }else{ //original if (parseInt(customizationFields[i][1]) == 1 && (el.html() == '' || el.text() != el.val()) && !pattern.test(el.attr('class'))) return false; } } return true; } |
Finalmente
Con estas modificaciones tenemos un selector además de tener la pestaña de personalización de producto en primer plano.
La validación de campo obligatorio funciona perfectamente y podemos ver como se pasa esta información a la siguiente etapa