Skip to content
  • Recent
  • Tags
  • Popular
  • Users
  • Search
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse

Lay Theme Forum

  1. Home
  2. General Discussion
  3. Category Filter works on Desktop but not on Mobile (AJAX issue)

Category Filter works on Desktop but not on Mobile (AJAX issue)

Scheduled Pinned Locked Moved General Discussion
5 Posts 2 Posters 48 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    avarliero
    wrote last edited by
    #1

    Hi,
    I’m having an issue with the category filter when using custom JS/PHP on a Lay Theme site.

    On desktop, everything works perfectly — my custom overlay menu triggers the .lay-thumbnailgrid-filter-anchor elements correctly, and the product grid filters instantly via AJAX (as expected).

    On mobile, the exact same logic does not work:

    the URL changes correctly (e.g. /all-products/#category-chairs)

    sometimes I briefly see the correct filtered grid

    but then Lay AJAX resets the grid and goes back to All

    the click simulation on .lay-thumbnailgrid-filter-anchor is ignored

    even forcing reload doesn't persist the category state

    So the problem seems to be related to Lay’s mobile AJAX page transitions, which appear to override the filter state after the DOM gets replaced.

    My question:
    Is there a supported way to trigger category filtering on mobile via JS?

    1 Reply Last reply
    0
    • arminunruhA Offline
      arminunruhA Offline
      arminunruh
      Global Moderator
      wrote last edited by
      #2

      hello i need the link and can you provide the custom code u used?

      1 Reply Last reply
      0
      • A Offline
        A Offline
        avarliero
        wrote last edited by
        #3

        Hi Armin, thanks for your reply! Here is the link to the page where the issue happens: https://mediumspringgreen-bison-933621.hostingersite.com/all-products/

        1 Reply Last reply
        0
        • A Offline
          A Offline
          avarliero
          wrote last edited by
          #4
          add_shortcode('resina_lay_filter_accordion', function($atts){
          
            $atts = shortcode_atts([
              'title' => '',
            ], $atts);
          
            ob_start(); ?>
            
            <div class="resina-cat-accordion-wrap">
              <?php if ( !empty($atts['title']) ) : ?>
                <div class="resina-cat-accordion-title">
                  <?php echo esc_html($atts['title']); ?>
                </div>
              <?php endif; ?>
          
              <div class="resina-cat-accordion" data-resina-cat-accordion>
                <!-- JS costruisce qui tutto l'accordion -->
              </div>
            </div>
          
            <?php
            return ob_get_clean();
          });
          
          
          add_action('wp_footer', function(){
          ?>
          <script>
          (function(){
          
            const RESINA_PRODUCTS_URL = '/all-products/';
          
            const RESINA_CAT_LABELS = {
              "lamps":          "Lamps",
              "chandelier":     "Chandelier",
              "floor-lamps":    "Floor lamps",
              "table-lamps":    "Table lamps",
              "applique":       "Applique",
          
              "tables":         "Tables",
              "dining-tables":  "Dining tables",
              "side-tables":    "Side tables",
              "desk":           "Desk",
              "carts-bar-carts":"Carts and Bar carts",
          
              "sittings":       "Seatings",
              "chairs":         "Chairs",
              "sofa":           "Sofas",
              "armchairs":      "Armchairs",
              "lounge-chairs":  "Lounge Chairs",
          
              "storage":        "Storage",
              "bookcases":      "Bookcases",
              "sideboards":     "Sideboards",
              "cabinets":       "Cabinets",
              "wardrobes":      "Wardrobes",
              "hang-clothes":   "Hang clothes",
          
              "mirrors":        "Mirror",
              "floor-mirrors":  "Floor mirrors",
              "wall-mirrors":   "Wall mirrors",
              "table-mirrors":  "Table mirrors",
          
              "decor":          "Decor",
              "poster":         "Poster",
              "art":            "Art",
              "home-decor":     "Home decor"
            };
          
            const RESINA_GROUPS = [
              {
                label: "Lamps",
                slugs: ["lamps","chandelier","floor-lamps","table-lamps","applique"]
              },
              {
                label: "Tables",
                slugs: ["tables","dining-tables","side-tables","desk","carts-bar-carts"]
              },
              {
                label: "Seatings",
                slugs: ["sittings","chairs","sofa","armchairs","lounge-chairs"]
              },
              {
                label: "Storage",
                slugs: ["storage","bookcases","sideboards","cabinets","wardrobes","hang-clothes"]
              },
              {
                label: "Mirrors",
                slugs: ["mirrors","floor-mirrors","wall-mirrors","table-mirrors"]
              },
              {
                label: "Decor",
                slugs: ["decor","poster","art","home-decor"]
              }
            ];
          
            function getAnchors(){
              return Array.from(document.querySelectorAll('.lay-thumbnailgrid-filter-anchor'));
            }
          
            function findAllAnchor(anchors){
              return anchors.find(a => a.getAttribute('data-slug') === 'all')
                  || anchors.find(a => a.getAttribute('data-id') === '0');
            }
          
            function clickLay(el){
              if(!el) return;
              const opts = { bubbles:true, cancelable:true, view:window };
          
              const fire = (type) => {
                try{
                  if(type.startsWith('pointer') && window.PointerEvent){
                    el.dispatchEvent(new PointerEvent(type, opts));
                  } else {
                    el.dispatchEvent(new MouseEvent(type, opts));
                  }
                }catch(e){}
              };
          
              try{ el.focus({preventScroll:true}); }catch(e){}
              try{ el.scrollIntoView({block:'nearest', inline:'nearest'}); }catch(e){}
          
              try{ el.click(); }catch(e){}
              fire('pointerdown'); fire('mousedown');
              fire('pointerup');   fire('mouseup');
              fire('click');
          
              setTimeout(function(){
                try{ el.click(); }catch(e){}
                fire('pointerdown'); fire('mousedown');
                fire('pointerup');   fire('mouseup');
                fire('click');
              }, 120);
            }
          
            function normalizePath(urlOrPath){
              urlOrPath = urlOrPath.replace(/^https?:\/\/[^/]+/,'');
              urlOrPath = urlOrPath.split('#')[0].split('?')[0];
              return urlOrPath.replace(/\/+$/,'') || '/';
            }
          
            function isOnProductsPage(){
              const current  = normalizePath(window.location.pathname);
              const products = normalizePath(RESINA_PRODUCTS_URL);
              return current === products;
            }
          
            function closeOverlay(){
              try{
                const closeBtn = document.querySelector(
                  '.lay-overlay-close, .overlay-close, [data-overlay-close]'
                );
                if(closeBtn){
                  closeBtn.click();
                }
              }catch(e){}
          
              try{
                document.body.classList.remove('lay-overlay-open','overlay-open','open');
              }catch(e){}
            }
          
            function initAccordions(){
              document.querySelectorAll('[data-resina-cat-accordion]').forEach(function(container){
          
                if(container.dataset.resinaBuilt === '1') return;
                container.dataset.resinaBuilt = '1';
          
                const frag  = document.createDocumentFragment();
          
                const allBtn = document.createElement('button');
                allBtn.type = 'button';
                allBtn.className = 'rca-all-link';
                allBtn.textContent = 'All products';
                allBtn.dataset.slug = '';
                frag.appendChild(allBtn);
          
                RESINA_GROUPS.forEach(group=>{
                  const item  = document.createElement('div');
                  item.className = 'rca-item';
          
                  const toggle = document.createElement('button');
                  toggle.type = 'button';
                  toggle.className = 'rca-toggle';
          
                  const labelSpan = document.createElement('span');
                  labelSpan.className = 'rca-label';
                  labelSpan.textContent = group.label;
          
                  const iconSpan = document.createElement('span');
                  iconSpan.className = 'rca-icon';
                  iconSpan.textContent = '+';
          
                  toggle.appendChild(labelSpan);
                  toggle.appendChild(iconSpan);
          
                  const panel = document.createElement('div');
                  panel.className = 'rca-panel';
          
                  group.slugs.forEach(slug=>{
                    if(!(slug in RESINA_CAT_LABELS)) return;
                    const btn = document.createElement('button');
                    btn.type = 'button';
                    btn.className = 'rca-link';
                    btn.textContent = RESINA_CAT_LABELS[slug];
                    btn.dataset.slug = slug;
                    panel.appendChild(btn);
                  });
          
                  item.appendChild(toggle);
                  item.appendChild(panel);
                  frag.appendChild(item);
                });
          
                container.appendChild(frag);
              });
            }
          
            document.addEventListener('click', function(e){
              // Toggle gruppo
              const toggle = e.target.closest('.resina-cat-accordion .rca-toggle');
              if(toggle){
                const item  = toggle.closest('.rca-item');
                const panel = item.querySelector('.rca-panel');
                const isOpen = item.classList.contains('is-open');
          
                const container = toggle.closest('.resina-cat-accordion');
                container.querySelectorAll('.rca-item').forEach(other=>{
                  if(other !== item){
                    other.classList.remove('is-open');
                    const op = other.querySelector('.rca-panel');
                    if(op){ op.style.maxHeight = 0; }
                  }
                });
          
                if(isOpen){
                  item.classList.remove('is-open');
                  if(panel){ panel.style.maxHeight = 0; }
                } else {
                  item.classList.add('is-open');
                  if(panel){ panel.style.maxHeight = panel.scrollHeight + "px"; }
                }
                return;
              }
          
              // Click su All o categoria
              const linkBtn = e.target.closest('.resina-cat-accordion .rca-link, .resina-cat-accordion .rca-all-link');
              if(linkBtn){
                const slug = linkBtn.dataset.slug || '';
                let targetUrl = RESINA_PRODUCTS_URL;
                if(slug){
                  targetUrl = RESINA_PRODUCTS_URL + '#category-' + slug;
                }
          
                // chiudi overlay
                closeOverlay();
          
                if(isOnProductsPage()){
                  const anchors = getAnchors();
                  let anchor;
                  if(slug){
                    anchor = anchors.find(a => a.getAttribute('data-slug') === slug);
                  }else{
                    anchor = findAllAnchor(anchors);
                  }
          
                  const isMobile = window.matchMedia('(max-width: 768px)').matches;
          
                  if(!isMobile && anchor){
                    // DESKTOP → filtro Lay live
                    clickLay(anchor);
                    history.replaceState(null, '', targetUrl);
                  } else {
                    // MOBILE → ricarica pagina con hash
                    window.location.href = targetUrl;
                  }
                }else{
                  // Non siamo su all-products → vai normalmente
                  window.location.href = targetUrl;
                }
                return;
              }
            });
          
            document.addEventListener('DOMContentLoaded', initAccordions);
          
          })();
          </script>
          <?php
          });
          
          1 Reply Last reply
          0
          • arminunruhA Offline
            arminunruhA Offline
            arminunruh
            Global Moderator
            wrote last edited by
            #5

            wow!

            can you try this:

            <button type="button" class="rca-link" data-slug="dining-tables">Dining tables</button>

            dont use <button> elements but instead use normal <divs>
            or anything else except <button>

            really not sure if that may be it. probably that wont make a difference

            another thing is:

                if(!isMobile && anchor){
                  // DESKTOP → filtro Lay live
                  clickLay(anchor);
                  history.replaceState(null, '', targetUrl);
                } else {
                  // MOBILE → ricarica pagina con hash
                  window.location.href = targetUrl;
                }
            

            here, could you code it so it only replaces the hash:

            window.location.hash = 'section1';

            instead of using

            window.location.href =

            because the window.location.href =
            line might reload the site

            or try the way you do it in this one if statement:

            history.replaceState(null, '', targetUrl);

            instead of
            window.location.href =

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            I also code custom websites or custom Lay features.
            💿 Email me here: 💿
            info@laytheme.com

            Our Web Development company: 100k.studio

            Want to tip me? https://www.paypal.com/paypalme/arminunruh

            Before you post:
            1. When using a WordPress Cache plugin, disable it or clear your cache.
            2. Update Lay Theme and all Lay Theme Addons
            3. Disable all Plugins
            4. Go to Lay Options → Custom CSS & HTML, click "Turn Off All Custom Code", click "Save Changes"

            This often solves issues you might run into

            When you post:
            1. Post a link to where the problem is
            2. Does the problem happen on Chrome, Firefox, Safari or iPhone or Android?
            3. If the problem is difficult to explain, post screenshots / link to a video to explain it
            Online Users
            Forgot your key, lost your files, need a previous Lay Theme or Addon version? Go to www.laykeymanager.com
            laytheme.com
            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Recent
            • Tags
            • Popular
            • Users
            • Search