Prestashop : classer les déclinaisons par leur prix

L’une des fonctionnalités plutôt sympa de Prestashop est de pouvoir afficher la liste des déclinaisons d’un produit. Cela permet d’avoir un visibilité globale des coûts en fonction de la taille ou de la couleur du produit. Ce n’est pas contre par une fonctionnalité qui existe de base. Il faudra systématiquement passer par une solution payante pour l’instant. Personnellement, je suis parti sur cette solution. Elle permet non seulement un affichage de la liste dans les catégories mais aussi sur la fiche produit. C’est plus particulièrement à la fiche produit que je vais m’attaquer car c’est en générale par elle que vous allez générer la vente.

Le soucis est que ce module (et surement d’autres) ne permet pas de classer la liste en fonction du prix de la déclinaison. Plutôt que de modifier le module qui empêcherait de le mettre à jour ou qui serait une solution qui ne fonctionne qu’avec lui, j’ai préféré mettre en place une solution en Javascript.

tableau-prestashop

Ouvrez le fichier footer.tpl de votre thème, puis, avant la balise </body>, collez le code ci-dessous :

{literal}
<script type="text/javascript">
    var tableHead = [];
    var columnPriceTitles = ['price', 'prix', 'preis'];
    var columnPrice = 0;
    var tableSelector = '.table_d_c'; // a compléter

    $(document).ready(function () {
        $(tableSelector).addClass('sort');

        if ($(tableSelector).find('thead').length === 0) {
            $(tableSelector).prepend(
                $('<thead></thead>').append($(tableSelector + ' tr:first').remove())
            );
        }

        // recherche des titres des colonnes de la table
        $(tableSelector + ' thead tr').find('td').each(function (rowIndex) {
            tableHead.push($.trim($(this).text()));
        });

        // recherche de la colonne prix
        $.each(tableHead, function (index, value) {
            $.each(columnPriceTitles, function (indexBis, valueBis) {
                if (value.toLowerCase().indexOf(valueBis) !== -1) {
                    columnPrice = index;
                }
            });
        });

        var sort_case_sensitive = false;
        var initial_sort_id = columnPrice;

        function _sort(a, b) {
            var a = a[0];
            var b = b[0];
            var _a = (a + '').replace(/,/, '.');
            var _b = (b + '').replace(/,/, '.');
            if (parseFloat(_a) && parseFloat(_b)) return sort_numbers(parseFloat(_a), parseFloat(_b));
            else if (!sort_case_sensitive) return sort_insensitive(a, b);
            else return sort_sensitive(a, b);
        }

        function sort_numbers(a, b) {
            return a - b;
        }

        function sort_insensitive(a, b) {
            var anew = a.toLowerCase();
            var bnew = b.toLowerCase();
            if (anew < bnew) return -1;
            if (anew > bnew) return 1;
            return 0;
        }

        function sort_sensitive(a, b) {
            if (a < b) return -1;
            if (a > b) return 1;
            return 0;
        }

        function getConcatenedTextContent(node) {
            var _result = "";
            if (node == null) {
                return _result;
            }
            var childrens = node.childNodes;
            var i = 0;
            while (i < childrens.length) {
                var child = childrens.item(i);
                switch (child.nodeType) {
                    case 1: // ELEMENT_NODE
                    case 5: // ENTITY_REFERENCE_NODE
                        _result += getConcatenedTextContent(child);
                        break;
                    case 3: // TEXT_NODE
                    case 2: // ATTRIBUTE_NODE
                    case 4: // CDATA_SECTION_NODE
                        _result += child.nodeValue;
                        break;
                    case 6: // ENTITY_NODE
                    case 7: // PROCESSING_INSTRUCTION_NODE
                    case 8: // COMMENT_NODE
                    case 9: // DOCUMENT_NODE
                    case 10: // DOCUMENT_TYPE_NODE
                    case 11: // DOCUMENT_FRAGMENT_NODE
                    case 12: // NOTATION_NODE
                        // skip
                        break;
                }
                i++;
            }
            return _result;
        }

        function sort(e) {
            var el = window.event ? window.event.srcElement : e.currentTarget;
            while (el.tagName.toLowerCase() != "td") el = el.parentNode;
            var a = new Array();
            var name = el.lastChild.nodeValue;
            var dad = el.parentNode;
            var table = dad.parentNode.parentNode;
            var up = table.up;
            var node, curcol;
            for (var i = 0; (node = dad.getElementsByTagName("td").item(i)); i++) {
                if (node.lastChild.nodeValue == name) {
                    curcol = i;
                    if (node.className == "curcol") {
                        table.up = Number(!up);
                    } else {
                        node.className = "curcol";
                        table.up = 0;
                    }
                } else {
                    if (node.className == "curcol") {
                        node.className = "";
                        if (node.firstChild) node.removeChild(node.firstChild);
                    }
                }
            }
            var tbody = table.getElementsByTagName("tbody").item(0);
            for (var i = 0; (node = tbody.getElementsByTagName("tr").item(i)); i++) {
                a[i] = new Array();
                a[i][0] = getConcatenedTextContent(node.getElementsByTagName("td").item(curcol));
                a[i][1] = getConcatenedTextContent(node.getElementsByTagName("td").item(1));
                a[i][2] = getConcatenedTextContent(node.getElementsByTagName("td").item(0));
                a[i][3] = node;
            }
            a.sort(_sort);
            if (table.up) a.reverse();
            for (var i = 0; i < a.length; i++) {
                tbody.appendChild(a[i][3]);
            }
        }

        function init(e) {
            if (!document.getElementsByTagName) return;

            for (var j = 0; (thead = document.getElementsByTagName("thead").item(j)); j++) {
                var node;
                for (var i = 0; (node = thead.getElementsByTagName("td").item(i)); i++) {
                    if (node.addEventListener) node.addEventListener("click", sort, false);
                    else if (node.attachEvent) node.attachEvent("onclick", sort);
                }
                thead.parentNode.up = 0;

                if (typeof (initial_sort_id) != "undefined") {
                    td_for_event = thead.getElementsByTagName("td").item(initial_sort_id);
                    if (document.createEvent) {
                        var evt = document.createEvent("MouseEvents");
                        evt.initMouseEvent("click", false, false, window, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, td_for_event);
                        td_for_event.dispatchEvent(evt);
                    } else if (td_for_event.fireEvent) td_for_event.fireEvent("onclick");
                    if (typeof (initial_sort_up) != "undefined" && initial_sort_up) {
                        if (td_for_event.dispatchEvent) td_for_event.dispatchEvent(evt);
                        else if (td_for_event.fireEvent) td_for_event.fireEvent("onclick");
                    }
                }
            }
        }

        var root = window.addEventListener || window.attachEvent ? window : document.addEventListener ? document : null;
        if (root) {
            if (root.addEventListener) root.addEventListener("load", init, false);
            else if (root.attachEvent) root.attachEvent("onload", init);
        }
    });
</script>{/literal}

Il est assez grand et indigeste mais vous n’avez qu’une seule chose à faire. Il faut adapter la ligne 6. Avec ce module, la table générée a une classe spécifique. La votre peut très bien avoir un id (utilisez #nom_id à la place). Utilisez l’inspecteur de code pour vous en assurer :

classe-table

Après le chargement de la page, le tableau devrait être classé correctement en fonction du prix des déclinaisons.

table-classé

Pour y arriver, nous avons défini en ligne 4 les chaines contenues dans le titre de la colonne que nous souhaitons classer. Si le titre de votre colonne contient « tarif », « coût » ou tout autre chaîne, il faudra adapter le tableau défini en ligne 4.

Attention, pensez bien à vider le cache après la modification du thème.

Prestashop : améliorer le tunnel de commande
Prestashop : accepter les numéros de téléphone internationaux

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *