From c5a04225526941059a15dc7e7af362882a07942c Mon Sep 17 00:00:00 2001 From: Roger Rehnelt Date: Sat, 3 Oct 2026 17:56:56 +0200 Subject: Produktfilter: filtert die Produktkacheln über alle Seiten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sortiment und Kategorieseiten zeigen den Filter als Leiste über den Kacheln, am Handy zugeklappt; Seitenzahlen und Trefferzahl beziehen sich auf das gefilterte Ergebnis. Co-Authored-By: Claude Opus 5.5 --- views/mods/mod_productview/productview.js | 22 ++++++++++++++++------ .../mods/mod_productview/productview_filter.phtml | 12 ++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) (limited to 'views/mods') diff --git a/views/mods/mod_productview/productview.js b/views/mods/mod_productview/productview.js index 34c0df9..fc58ec8 100644 --- a/views/mods/mod_productview/productview.js +++ b/views/mods/mod_productview/productview.js @@ -4,8 +4,9 @@ * Ohne JavaScript funktionieren Links und Formulare über die Adresse. Mit JavaScript holt das Skript die Ansicht per * Ajax (wpsg_mod=wpsg_mod_productview, wpsg_action=refresh) und schreibt den Zustand in die Adresse. Die Attribute des * Shortcodes kommen signiert aus dem Feld wpsg_atts; der Server übernimmt nur Seite, Sortierung, Ansicht und Filter. - * Produktlisten mit data-wpsg-filter (Block Produktliste) holt es mit der neuen Adresse als ganze Seite, wie ohne - * JavaScript, und tauscht ihren Inhalt; die Statuszeile bleibt stehen und sagt die neue Anzahl an. + * Produktlisten mit data-wpsg-filter (Block Produktliste, Produktkacheln) holt es mit der neuen Adresse als ganze Seite, + * wie ohne JavaScript, und tauscht ihren Inhalt; die Statuszeile und ein Filter darin bleiben stehen, damit Ansage und + * Fokus erhalten bleiben. */ ( function() { @@ -156,12 +157,13 @@ lists.forEach( function( list, i ) { - const status = list.querySelector( '.wpsg-product-list__count' ); + const status = list.querySelector( ':scope > .wpsg-product-list__count' ); + const keep = function( child ) { return child.classList.contains( 'wpsg-product-list__count' ) || child.classList.contains( 'wpsg-block-product-filter' ); }; - Array.prototype.slice.call( list.children ).forEach( function( child ) { if ( child !== status ) child.remove(); } ); - Array.prototype.slice.call( fresh[ i ].children ).forEach( function( child ) { if ( !child.classList.contains( 'wpsg-product-list__count' ) ) list.appendChild( document.importNode( child, true ) ); } ); + Array.prototype.slice.call( list.children ).forEach( function( child ) { if ( !keep( child ) ) child.remove(); } ); + Array.prototype.slice.call( fresh[ i ].children ).forEach( function( child ) { if ( !keep( child ) ) list.appendChild( document.importNode( child, true ) ); } ); - const freshStatus = fresh[ i ].querySelector( '.wpsg-product-list__count' ); + const freshStatus = fresh[ i ].querySelector( ':scope > .wpsg-product-list__count' ); if ( status && freshStatus ) status.textContent = freshStatus.textContent; list.removeAttribute( 'aria-busy' ); @@ -204,4 +206,12 @@ // Mit JavaScript sortiert die Auswahl sofort document.querySelectorAll( '.wpsg-pv__order-submit' ).forEach( function( b ) { b.hidden = true; } ); + // Filterleiste der Produktkacheln: am Handy zugeklappt, breit immer offen (Grenze wie WordPress, 782 px) + const narrow = window.matchMedia( '(max-width: 781px)' ); + + function toggleBar() { document.querySelectorAll( '.wpsg-pvf__toggle' ).forEach( function( d ) { d.open = !narrow.matches; } ); } + + toggleBar(); + narrow.addEventListener( 'change', toggleBar ); + } )(); diff --git a/views/mods/mod_productview/productview_filter.phtml b/views/mods/mod_productview/productview_filter.phtml index 121159a..1cf98da 100644 --- a/views/mods/mod_productview/productview_filter.phtml +++ b/views/mods/mod_productview/productview_filter.phtml @@ -25,6 +25,13 @@ + view['wpsg_mod_productview_filter']['bar']??false) === true); ?> + +
+ +
+ + view['showFilter'] as $filter) { ?> @@ -81,4 +88,9 @@
+ + +
+ + -- cgit v1.2.3