Skip to content

Conversation

@barryhughes
Copy link
Member

@barryhughes barryhughes commented Jan 17, 2023

The product quantity selector has gone through a number of changes. To understand this latest PR, I want to start by summarizing its recent history:

  • Prior to 7.2.0, if the product quantity selector's min and max values were the same (ie, it could not be modified), it would render as a hidden input. Otherwise, it rendered as a regular number input.
  • In 7.2.0 we merged a change making it so the selector would render even when the min and max values are the same (but in readonly mode). The idea was to make the UI consistent across products, and make the purchase quantity obvious to customers.
  • This met with resistance, with many users reporting they preferred the previous behaviour.
  • CSS based attempts at a compromise [1] [2] in which we would hide the input if the product was sold individually were attempted, but also proved to be problematic.

So, in this change, we essentially restore the behavior we had before the 7.2.0 release. However, we are also tweaking an existing filter hook and adding one more, making it possible to achieve the objectives of the original PR without implementing a template override.

Updates #36007.

  • This PR is a very minor change/addition and does not require testing instructions (if checked you can ignore/remove the next section).

How to test the changes in this Pull Request:

  1. Ensure you have one product that is sold individually, and another regular product.
  2. Visit the single product page of each:
    • For the sold individually product, the quantity input should be hidden.
    • For the regular product, the quantity input should be visible.
  3. Add each item to the cart. Within the cart page:
    • The sold individually product quantity selector should be hidden.
    • The regular product should have a visible quantity selector.

restored-pre-720-behavior

Let's now test that we can achieve the goals of PR#34282 by adding the following code to an appropriate location (such as wp-content/mu-plugins/test-quantity-selectors.php):

<?php
/**
 * This snippet can be used to force the quantity input to display in cases where
 * the input value cannot be changed (which is when the product is set to be sold
 * individually, or when the min and max values are identical).
 */
add_filter( 'woocommerce_quantity_input_args', function ( array $args ) {
	// Only modify inputs where the max value is set and is equal to the min value.
	if ( $args['max_value'] < 1 || $args['min_value'] !== $args['max_value'] ) {
		return $args;
	}

	// Convert into a text input.
	add_filter( 'woocommerce_quantity_input_type', function () {
		return 'text';
	} );

	// Set to readonly.
	$args['readonly'] = true;
	return $args;
} );

Now, if you repeat the above tests, you should find the quantity selector always displays, even for products that are sold individually. However, in these cases it will be a readonly text input.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you created a changelog file for each project being changed, ie pnpm --filter=<project> changelog add?

FOR PR REVIEWER ONLY:

  • I have reviewed that everything is sanitized/escaped appropriately for any SQL or XSS injection possibilities. I made sure Linting is not ignored or disabled.

Prior to 7.2.0 the quantity input was hidden if input min and max were identical (either because the product was sold individually, or because of min/max products config). This change restores that behavior, but makes it possible to render the input in readonly mode if desired (via filters).
@github-actions github-actions bot added the plugin: woocommerce Issues related to the WooCommerce Core plugin. label Jan 17, 2023
@barryhughes barryhughes requested review from a team and Konamiman and removed request for a team January 17, 2023 00:18
@github-actions
Copy link
Contributor

github-actions bot commented Jan 17, 2023

Test Results Summary

Commit SHA: 01b420b

Test 🧪Passed ✅Failed 🚨Broken 🚧Skipped ⏭️Unknown ❔Total 📊Duration ⏱️
API Tests25900202610m 56s
E2E Tests189006019514m 48s

To view the full API test report, click here.
To view the full E2E test report, click here.
To view all test reports, visit the WooCommerce Test Reports Dashboard.

@Konamiman Konamiman merged commit 2bf9f57 into trunk Jan 17, 2023
@Konamiman Konamiman deleted the fix/36007-quantity-selector branch January 17, 2023 16:06
@github-actions github-actions bot added this to the 7.4.0 milestone Jan 17, 2023
adrianduffell pushed a commit that referenced this pull request Jan 20, 2023
Prior to 7.2.0 the quantity input was hidden if input min and max were identical (either because the product was sold individually, or because of min/max products config). This change restores that behavior, but makes it possible to render the input in readonly mode if desired (via filters).
vedanshujain pushed a commit that referenced this pull request Jan 25, 2023
Prior to 7.2.0 the quantity input was hidden if input min and max were identical (either because the product was sold individually, or because of min/max products config). This change restores that behavior, but makes it possible to render the input in readonly mode if desired (via filters).
@pe-pe80
Copy link

pe-pe80 commented May 25, 2023

@barryhughes I have a problem with the snippet of code you provided. I have products in the basket that can be purchased individually (quantity input type="text") and those that can be purchased in any quantity (quantity input type="number"). Unfortunately, adding the filter below makes all inputs change to "text" type:

// Convert into a text input.
add_filter( 'woocommerce_quantity_input_type', function () {
return 'text';
} );

@barryhughes
Copy link
Member Author

Hi @pe-pe80,

Unfortunately, adding the filter below makes all inputs change to "text" type:

// Convert into a text input.
add_filter( 'woocommerce_quantity_input_type', function () {
    return 'text';
} );

If you only copied those 4 lines from the code I shared in the testing instructions, and not the larger snippet in its entirety, then it will indeed change all inputs to be of type 'text'.

However, the testing instructions were chiefly created for the purposes of testing the PR—and not for any other reason. If I'm misunderstanding, though, and you are trying to describe a bug of some kind that might have been introduced via this PR, please do create a bug report and we'll definitely look into it 👍

@pe-pe80
Copy link

pe-pe80 commented May 26, 2023

Hi @barryhughes! Sorry I wasn't very precise. I used all the code. I just wanted to point out the problematic part here. From the moment you use the "woocommerce_quantity_input_type filter," all subsequent products will have a "text" quantitative input.

Suppose I have such products in the shopping cart:

  1. regular [quantity input: number]
  2. sold individually [quantity input: hidden]
  3. regular [quantity input: number]
  4. regular [quantity input: number]

I want to get this effect:

  1. regular [quantity input: number]
  2. sold individually [quantity input: text]
  3. regular [quantity input: number]
  4. regular [quantity input: number]

Unfortunately, after applying the code you proposed (the whole code), the cart looks like this:

  1. regular [quantity input: number]
  2. sold individually [quantity input: text] <-- from now on, all subsequent ones will be of type "text"
  3. regular [quantity input: text]
  4. regular [quantity input: text]

@barryhughes
Copy link
Member Author

Gotcha. Yes, you're right. So, in your case, you would probably want the filter to unhook itself ... but again, just to be clear, the snippet in the testing instructions was a simple snippet that worked for the purposes of testing this change—it wasn't intended for general use—so it's not too surprising there are real world cases where it starts breaking down.

@pe-pe80
Copy link

pe-pe80 commented May 26, 2023

I modified the code like this and it works fine now :)

add_filter('woocommerce_quantity_input_args', function (array $args) {

	if ($args['max_value'] < 1 || $args['min_value'] !== $args['max_value']) {
		remove_filter('woocommerce_quantity_input_type', 'change_quantity_input_type');
		return $args;
	}
	add_filter('woocommerce_quantity_input_type', 'change_quantity_input_type');
	$args['readonly'] = true;
	return $args;
});

function change_quantity_input_type() {
	return 'text';
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants