Commit 2f15e913189 for woocommerce

commit 2f15e9131898cce2b7d8119800c9de735effcd20
Author: Cvetan Cvetanov <cvetan.cvetanov@automattic.com>
Date:   Fri Jul 31 14:09:32 2026 +0300

    Exclude already selected products from product search results (#67063)

    * fix(admin): exclude selected products from enhanced search results

    The wc-product-search selectWoo fields sent only the static data-exclude
    attribute with each AJAX search, so products already added to a
    multi-select (Linked Products, coupons, and similar) kept appearing in
    the results. Clicking such a product again triggered selectWoo's default
    toggle behavior and silently removed it from the selection.

    Merge the control's current selections into the exclude parameter for
    multi-selects, hiding them from the results, in line with how Gutenberg
    token selectors behave. WC_AJAX::json_search_products() already accepts
    an array of IDs, so no server change is needed, and the result list
    stays filled with products that can actually be added. Single selects
    keep their current behavior. Comma-separated data-exclude values are now
    split client-side, so every listed ID is excluded instead of only the
    first.

    Refs #32085

    * Update plugins/woocommerce/client/legacy/js/admin/wc-enhanced-select.js

    Co-authored-by: Albert Juhé Lluveras <contact@albertjuhe.com>

    * fix(admin): skip the exclude parameter when there is nothing to exclude

    Fields without a data-exclude attribute, like the coupon product
    restrictions, sent exclude[]=undefined with every search because
    String( undefined ) stringifies to "undefined". Harmless server-side,
    absint() turns it into 0, but noise in every request. Only split the
    attribute when it has a value, so such fields send no exclude parameter
    until a product is actually selected, matching the previous behavior.

    Refs #32085

    ---------

    Co-authored-by: Albert Juhé Lluveras <contact@albertjuhe.com>

diff --git a/plugins/woocommerce/changelog/32085-prevent-product-search-deselect b/plugins/woocommerce/changelog/32085-prevent-product-search-deselect
new file mode 100644
index 00000000000..e4154e17a36
--- /dev/null
+++ b/plugins/woocommerce/changelog/32085-prevent-product-search-deselect
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Enhanced product search multi-selects (e.g. Linked Products) no longer list products that are already selected, so re-clicking a product in the results can no longer silently remove it from the selection.
diff --git a/plugins/woocommerce/client/legacy/js/admin/wc-enhanced-select.js b/plugins/woocommerce/client/legacy/js/admin/wc-enhanced-select.js
index 4cf2793315b..c8376660196 100644
--- a/plugins/woocommerce/client/legacy/js/admin/wc-enhanced-select.js
+++ b/plugins/woocommerce/client/legacy/js/admin/wc-enhanced-select.js
@@ -268,6 +268,23 @@ jQuery( function ( $ ) {
 								dataType: 'json',
 								delay: 250,
 								data: function ( params ) {
+									let exclude = $( this ).data( 'exclude' );
+									const currentValue = $( this ).val();
+
+									// Hide already selected options from the results in multiple selects.
+									if (
+										Array.isArray( currentValue ) &&
+										$( this ).prop( 'multiple' )
+									) {
+										const defaultExcluded = exclude
+											? String( exclude ).split( ',' )
+											: [];
+										exclude = [
+											...defaultExcluded,
+											...currentValue,
+										];
+									}
+
 									return {
 										term: params.term,
 										action:
@@ -275,7 +292,7 @@ jQuery( function ( $ ) {
 											'woocommerce_json_search_products_and_variations',
 										security:
 											wc_enhanced_select_params.search_products_nonce,
-										exclude: $( this ).data( 'exclude' ),
+										exclude: exclude,
 										exclude_type:
 											$( this ).data( 'exclude_type' ),
 										include: $( this ).data( 'include' ),