summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Rehnelt <noreply@maennchen1.de>2026-10-01 21:31:01 +0200
committerRoger Rehnelt <noreply@maennchen1.de>2026-10-01 21:31:01 +0200
commit1615c1c0f81b056b5017d3d637f43b75ab8de4ca (patch)
treeec30dd4f7d8f86ef09a5bf4aba85696e8e669b0d
parentf124d8990eb2042a9af25546738e4f5e64645aa8 (diff)
Produktfilter: nur die zuletzt gestellte Anfrage zählt
Zwei schnelle Änderungen am Filter konnten die Liste mit dem älteren Stand füllen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--views/mods/mod_productview/productview.js28
1 files changed, 23 insertions, 5 deletions
diff --git a/views/mods/mod_productview/productview.js b/views/mods/mod_productview/productview.js
index fc03a1f..34c0df9 100644
--- a/views/mods/mod_productview/productview.js
+++ b/views/mods/mod_productview/productview.js
@@ -53,11 +53,19 @@
}
+ // Laufende Anfragen je Ansicht (Position auf der Seite) und für die Produktlisten: Nur die zuletzt gestellte zählt
+ const pending = [];
+ let pendingLists = null;
+
function refresh( box, change, url, push ) {
const field = box.querySelector( 'input[name="wpsg_atts"]' );
if ( !field ) return false;
+ const index = Array.prototype.indexOf.call( document.querySelectorAll( '.wpsg_productview' ), box );
+ if ( pending[ index ] ) pending[ index ].abort();
+ const ctl = pending[ index ] = new AbortController();
+
const atts = JSON.parse( field.value );
Object.assign( atts, change );
@@ -66,10 +74,13 @@
box.classList.add( 'is-loading' );
box.setAttribute( 'aria-busy', 'true' );
- fetch( box.getAttribute( 'data-wpsg-pv-url' ) + ( box.getAttribute( 'data-wpsg-pv-url' ).indexOf( '?' ) === -1 ? '?' : '&' ) + params.toString(), { credentials: 'same-origin' } )
+ fetch( box.getAttribute( 'data-wpsg-pv-url' ) + ( box.getAttribute( 'data-wpsg-pv-url' ).indexOf( '?' ) === -1 ? '?' : '&' ) + params.toString(), { credentials: 'same-origin', signal: ctl.signal } )
.then( function( r ) { if ( !r.ok ) throw new Error( r.status ); return r.text(); } )
.then( function( html ) {
+ if ( pending[ index ] !== ctl ) return;
+ pending[ index ] = null;
+
const tmp = document.createElement( 'div' );
tmp.innerHTML = html;
@@ -77,11 +88,12 @@
if ( !fresh ) throw new Error( 'leer' );
fresh.querySelectorAll( '.wpsg-pv__order-submit' ).forEach( function( b ) { b.hidden = true; } );
- box.replaceWith( fresh );
+ // Eine frühere Antwort kann die Ansicht schon ersetzt haben
+ document.querySelectorAll( '.wpsg_productview' )[ index ].replaceWith( fresh );
if ( url && push !== false ) history.pushState( { wpsgPv: true }, '', url );
} )
- .catch( function() { if ( url ) location.href = url; } );
+ .catch( function() { if ( url && pending[ index ] === ctl ) location.href = url; } );
return true;
@@ -129,10 +141,16 @@
lists.forEach( function( list ) { list.setAttribute( 'aria-busy', 'true' ); } );
- fetch( url, { credentials: 'same-origin' } )
+ if ( pendingLists ) pendingLists.abort();
+ const ctl = pendingLists = new AbortController();
+
+ fetch( url, { credentials: 'same-origin', signal: ctl.signal } )
.then( function( r ) { if ( !r.ok ) throw new Error( r.status ); return r.text(); } )
.then( function( html ) {
+ if ( pendingLists !== ctl ) return;
+ pendingLists = null;
+
const fresh = new DOMParser().parseFromString( html, 'text/html' ).querySelectorAll( '[data-wpsg-filter]' );
if ( fresh.length !== lists.length ) throw new Error( 'anders' );
@@ -151,7 +169,7 @@
} );
} )
- .catch( function() { location.href = url; } );
+ .catch( function() { if ( pendingLists === ctl ) location.href = url; } );
}