afipc Posted March 16, 2013 Share Posted March 16, 2013 (edited) Bonjour, Je souhaite rajouter une petite fonction au module de navigation à facettes, mais je bloque un peu. Tous mes produits ont une "supplier_reference" Je souhaite pouvoir filtrer en front office avec 3 cases radio : "Tout" (par défaut) "Produits individuels" -> supplier_reference ne contient pas "B" "Produits groupés" -> supplier_reference contient "B" J'arrive a faire le filtre "à la main" en modifiant blocklayered.php : function getProductByFilters, En testant successivement les 3 valeurs de $filtre_ref, ça fonctionne ligne ~2475, pour calculer le bon nombre de produits après filtre if (version_compare(_PS_VERSION_,'1.5','>')) $query_filters_from .= Shop::addSqlAssociation('product', 'p'); $filtre_ref = 'LIKE "%"'; // SI TOUT //$filtre_ref = 'NOT LIKE "%B%"'; // SI INDIVIDUEL //$filtre_ref = 'LIKE "%B%"'; // SI GROUPE $all_products_out = self::query(' SELECT p.`id_product` id_product FROM `'._DB_PREFIX_.'product` p '.$price_filter_query_out.' '.$query_filters_from.' WHERE 1 '.$query_filters_where.' GROUP BY id_product'); $all_products_in = self::query(' SELECT p.`id_product` id_product FROM `'._DB_PREFIX_.'product` p '.$price_filter_query_in.' '.$query_filters_from.' WHERE 1 '.$query_filters_where.' AND p.supplier_reference '.$filtre_ref.' GROUP BY id_product'); Puis un peu plus bas, modification de la query pour inclure le même filtre : SELECT p.*, '.($alias_where == 'p' ? '' : 'product_shop.*,' ).' '.$alias_where.'.id_category_default, pl.*, i.id_image, il.legend, m.name manufacturer_name, DATEDIFF('.$alias_where.'.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new FROM `'._DB_PREFIX_.'category_product` cp LEFT JOIN '._DB_PREFIX_.'category c ON (c.id_category = cp.id_category) LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = cp.`id_product` '.$join.' LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product) LEFT JOIN '._DB_PREFIX_.'image i ON (i.id_product = p.id_product AND i.cover = 1) LEFT JOIN '._DB_PREFIX_.'image_lang il ON (i.id_image = il.id_image AND il.id_lang = '.(int)($cookie->id_lang).') LEFT JOIN '._DB_PREFIX_.'manufacturer m ON (m.id_manufacturer = p.id_manufacturer) WHERE '.$alias_where.'.`active` = 1 AND '.(Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= '.(int)$parent->nleft.' AND c.nright <= '.(int)$parent->nright : 'c.id_category = '.(int)$id_parent).' AND c.active = 1 AND p.supplier_reference '.$filtre_ref.' AND pl.id_lang = '.(int)$cookie->id_lang.' AND p.id_product IN ('.implode(',', $product_id_list).')' .' GROUP BY p.id_product ORDER BY '.Tools::getProductsOrder('by', Tools::getValue('orderby'), true).' '.Tools::getProductsOrder('way', Tools::getValue('orderway')). ' LIMIT '.(((int)$this->page - 1) * $n.','.$n)); Je modifie blocklayered.tpl et j'ajoute au formulaire : <input type="radio" name="filtre_ref_radio" value="tout">Tous produits<br /> <input type="radio" name="filtre_ref_radio" value="indiv">Produits individuels<br /> <input type="radio" name="filtre_ref_radio" value="pack">Produits en PACK </form> Maintenant mon problème est de récupérer la valeur de "filtre_ref_radio" pour la manipuler dans le fichier blocklayered.php, et ainsi faire un test du genre : if (filtre_ref_radio == 'tout') $filtre_ref = 'LIKE "%"'; if (filtre_ref_radio == 'indiv') $filtre_ref = 'NOT LIKE "%B%"'; if (filtre_ref_radio == 'pack') $filtre_ref = 'LIKE "%B%"'; Mais je ne trouve pas comment passer cette valeur... Je regarde actuellement dans blocklayered.js, mais c'est un peu confus. Merci d'avance à ceux qui voudront m'aider, les modifications que je fais actuellement sont sur un serveur local, au besoin je peux donner l'accès si vous voulez regarder, dites-moi. Edited March 16, 2013 by afipc (see edit history) Link to comment Share on other sites More sharing options...
afipc Posted March 18, 2013 Author Share Posted March 18, 2013 Dans blocklayered.js on trouve 2 sections relatives aux boutons radio : // Click on checkbox $('#layered_form input[type=checkbox], #layered_form input[type=radio], #layered_form select').live('change', function() { reloadContent(); }); $('#layered_block_left .radio').live('click', function() { var name = $(this).attr('name'); $.each($(this).parent().parent().find('input[type=button]'), function (it, item) { if ($(item).hasClass('on') && $(item).attr('name') != name) { $(item).click(); } }); return true; }); Dans la 2ème fonction il est question du "name" de l'élément, mais j'ai du mal à comprendre ce qu'elle fait. Ensuite, comme le montre la 1ère fonction, il faut regarder dans la "function reloadContent(params_plus)" qui forme une query ajax pour adapter l'affichage, là encore c'est assez abstrait... Link to comment Share on other sites More sharing options...
afipc Posted March 18, 2013 Author Share Posted March 18, 2013 (edited) J'y suis presque... Pour récupérer la valeur de mon bouton radio dans blocklayerred.php : if ($_GET['filtre_ref_radio'] == 'tout' OR $_GET['filtre_ref_radio'] == '') $filtre_ref = 'LIKE "%"'; if ($_GET['filtre_ref_radio'] == 'indiv') $filtre_ref = 'NOT LIKE "%B%"'; if ($_GET['filtre_ref_radio'] == 'pack') $filtre_ref = 'LIKE "%B%"'; Le test si le radio est vide à la première ligne sert à forcer l'affichage de "tout" par défaut. Je souhaite que la coche soit sélectionnée pour le filtre en cours, j'envoie une variable au tpl via smarty, dans la function generateFiltersBlock($selected_filters) : if ($_GET['filtre_ref_radio'] == '') $smarty->assign('filtre_ref_coche', 'tout'); else $smarty->assign('filtre_ref_coche', $_GET['filtre_ref_radio']); return $this->display(__FILE__, 'blocklayered.tpl'); Et mon formulaire devient : <input type="radio" name="filtre_ref_radio" value="tout" {if $filtre_ref_coche == 'tout'}checked{/if}>Tous produits<br /> <input type="radio" name="filtre_ref_radio" value="indiv" {if $filtre_ref_coche == 'indiv'}checked{/if}>Produits individuels<br /> <input type="radio" name="filtre_ref_radio" value="pack" {if $filtre_ref_coche == 'pack'}checked{/if}>Produits en PACK Comme j'ai le filtre fabricant dans le module, il me reste à trouver comment mettre à jour le nombre de produits par fabricant, ainsi que le nom des fabricants, quand le filtre référence est activé (pour l'instant dans les 3 cas, c'est toujours le nombre de produits total qui apparaît, et tous les noms de fabricants) Edited March 18, 2013 by afipc (see edit history) Link to comment Share on other sites More sharing options...
afipc Posted March 18, 2013 Author Share Posted March 18, 2013 Voilà j'ai trouvé, dans la function getFilterBlock($selected_filters = array()) Je définis la valeur de ma variable $filtre_ref comme auparavant if ($_GET['filtre_ref_radio'] == 'tout' OR $_GET['filtre_ref_radio'] == '') $filtre_ref = 'LIKE "%"'; if ($_GET['filtre_ref_radio'] == 'indiv') $filtre_ref = 'NOT LIKE "%B%"'; if ($_GET['filtre_ref_radio'] == 'pack') $filtre_ref = 'LIKE "%B%"'; $filter_blocks = array(); foreach ($filters as $filter) Puis plus bas je modifie la query qui va chercher les fabricants et les quantités case 'manufacturer': $sql_query['select'] = 'SELECT m.name, COUNT(DISTINCT p.id_product) nbr, m.id_manufacturer '; $sql_query['from'] = ' FROM `'._DB_PREFIX_.'category_product` cp INNER JOIN `'._DB_PREFIX_.'category` c ON (c.id_category = cp.id_category) INNER JOIN '._DB_PREFIX_.'product p ON (p.id_product = cp.id_product) INNER JOIN '._DB_PREFIX_.'manufacturer m ON (m.id_manufacturer = p.id_manufacturer) '; $sql_query['where'] = 'WHERE '.(Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= '.(int)$parent->nleft.' AND c.nright <= '.(int)$parent->nright : 'c.id_category = '.(int)$id_parent).' AND c.active = 1 AND p.supplier_reference '.$filtre_ref.' AND '.$alias.'.active = 1'; $sql_query['group'] = ' GROUP BY p.id_manufacturer '; Je crois que c'est tout bon comme ça Link to comment Share on other sites More sharing options...
afipc Posted March 18, 2013 Author Share Posted March 18, 2013 (edited) Dans le formulaire, mettre le texte des boutons radios entre : <label for="...">...</label> Permet de cliquer aussi sur ce texte pour valider le choix, en plus du bouton rond. Il faut aussi donner un ID pour chaque radio, que l'on renseigne dans for="..." Edited March 18, 2013 by afipc (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now