Accordion with current category/subcategory

  • Posts: 25
  • Thank you received: 5
  • Hikashop Business
4 months 1 week ago #362586

-- url of the page with the problem -- : ethemba.com/_Guests/AR/
-- HikaShop version -- : 5.1.0
-- Joomla version -- : 5.1.1
-- PHP version -- : 8.1

Hello
I wanted to use the HikaShop Content Module to show all categories and subcategories using UI accordion. Also I want to remark in which one you are when you are watching a product. When I select a category in the brand menu the accordion opens and select the correct category/subcategory. But I´m not able to make it work when a product is selected from the home page from the instances of the HikaShop Content Module. In that case the selection is the last category selected not the product one.

I am still really newbie to hikashop and I would appreciate some indication of how can I fix this problem.
I attach listing-list.php with my changes. The category identification is coded here:

            <ul uk-accordion="multiple: true" class="CatListAccordion" id="Accordion<?php echo $this->params->get('ul_class_name'); ?>">
<?php
        		foreach($this->rows as $k => $row) {
        		    if($only_if_products && $row->number_of_products < 1 && $row->category_id <> 560)
        				continue;
        			$found = 0;
        			$child_found = 0;										$child2_found = 0;
        			if($in_hikashop_context) {
        			    $found = $last_category_selected;
        			    if($cid == $row->category_id) {
    					    $found = (int)$row->category_id;
        					    $app->setUserState(HIKASHOP_COMPONENT.'.last_category_selected', (int)$row->category_id);
        				} else {
            			    foreach($row->childs as $child) {
            			        if($cid == $child->category_id) {
        					        $found = (int)$row->category_id;
        					        $child_found = (int)$child->category_id;
            			        } else {																		foreach($child->childs as $child2) {																		if($cid == $child2->category_id) {											$found = (int)$row->category_id;											$child_found = (int)$child->category_id;											$child2_found = (int)$child2->category_id;											}									}								}
            			    }
        				}
        			}
            		$link = $this->getLink($row);
        	    	$class = ($found == $row->category_id) ? ' current active' : '';
?>
                    <li 
                    <?php 
                        if ($found == $row->category_id) {
                            echo ('class="uk-open cat-selected"');
                        }
                    ?>
Thank you very much and sorry for the inconveniences

Attachments:
Last edit: 4 months 1 week ago by nicolas.

Please Log in or Create an account to join the conversation.

  • Posts: 83022
  • Thank you received: 13403
  • MODERATOR
4 months 1 week ago #362592

Hi,

When you are on a page listing the products of a category, the line:

$cid == $row->category_id
will match the id of the category from the URL (in $cid) and the id of the categories of the categories listing module. And if it founds a match, it will use the line:
$app->setUserState(HIKASHOP_COMPONENT.'.last_category_selected', (int)$row->category_id);
to set the current category as the "last_category_selected".
Then, when you are on a product page, the line:
$last_category_selected = (int)$app->getUserState(HIKASHOP_COMPONENT.'.last_category_selected', 0);
will get that value to automatically open the accordion.
However, if you directly access the details page of a product from a products listing module, without accessing a page listing the products, this $last_category_selected will be empty, and thus the accordion won't open. That's what you're seeing.

We choose this method so that if you have products with multiple categories, the system will be able to open the correct category from which you accessed the product. The drawback is that there is no fallback logic when the product is accessed directly.

Instead of :
$last_category_selected = (int)$app->getUserState(HIKASHOP_COMPONENT.'.last_category_selected', 0);
, you could have something like this:
$cid = hikaInput::get()->getInt('cid', 0);
$productClass = hikashop_get('class.product');
$category_ids = $productClass->getCategories($cid);
$last_category_selected = reset($category_ids);
This would use the first category of the product as the $last_category_selected so it would work even if the product page is accessed directly. However, if you have several categories linked to a product, it won't be able to pickup the correct one.

Please Log in or Create an account to join the conversation.

  • Posts: 25
  • Thank you received: 5
  • Hikashop Business
4 months 1 week ago #362604

OK
Many thanks for the explanation.
Each product has two categories. For example if a watch is G-Stock Trend, it has G-STOCK and G-STOCK TREND I n order to appear in both listings. I understand why from category listing is working.
Actually i have

if($in_hikashop_context) {
	if(hikaInput::get()->getString('ctrl','category') == 'product' && hikaInput::get()->getString('task','listing') == 'show') {
		$last_category_selected = (int)$app->getUserState(HIKASHOP_COMPONENT.'.last_category_selected', 0);
		$config =& hikashop_config();
		$pathway_sef_name = $config->get('pathway_sef_name', 'category_pathway');
		$cid = hikaInput::get()->getInt($pathway_sef_name, 0);
	} else {
		$cid = hikaInput::get()->getInt('cid', 0);
	}
}
So $cid = hikaInput::get()->getInt('cid', 0); is the same as read cid from the URL. With this code from the module no category is selected but from the category listing is selected another one.

If I use your proposal, when I open a product details (nodule and category list) nothing is selected.
So, can I delete the main category and leave only the subcategory (only G-Shock trend), configure the main category G-SHOCK to show every child, place your code and test?

Thank you very much for your patience and time
Best rewards

Last edit: 4 months 1 week ago by nicolas.

Please Log in or Create an account to join the conversation.

  • Posts: 83022
  • Thank you received: 13403
  • MODERATOR
4 months 1 week ago #362609

Hi,

For example if a watch is G-Stock Trend, it has G-STOCK and G-STOCK TREND I n order to appear in both listings. I understand why from category listing is working.

Note that if the second category is the child of the first one, you don't usually need the first one. You can have only the child category linked to the product. Then, in the settings of your menu item, under the "products options" tab, instead of "direct sub elements" you can select "all sub elements" in the "sub elements filter" setting. That way, the products listing of the main category will also contain the products linked only to the child categories of the main category.

If I use your proposal, when I open a product details (nodule and category list) nothing is selected.

Then, either you didn't add the code as you should have, or the first category of the product is not in the list of categories of the module.

So, can I delete the main category and leave only the subcategory (only G-Shock trend), configure the main category G-SHOCK to show every child, place your code and test?

yes, I suppose this will work better.

Please Log in or Create an account to join the conversation.

  • Posts: 25
  • Thank you received: 5
  • Hikashop Business
4 months 1 week ago #362622

I have already change all products to have only one category.
I have also replace the code with the one you send me but in the products there is nothing selected.

I´m going to test and make changes to try to find the error. As soon I discover it I will publish the final code just in case it could help another.

Thank you very much

The following user(s) said Thank You: nicolas

Please Log in or Create an account to join the conversation.

Time to create page: 0.066 seconds
Powered by Kunena Forum