4

I have created a plus/minus quantity button for woocommerce single product page.created a new quantity-input.php

<?php
    if ( ! defined( 'ABSPATH' ) ) 
        exit; // Exit if accessed directly
?>
<div class="quantity">
    <input class="minus" type="button" value="-">
    <input type="number" step="<?php echo esc_attr( $step ); ?>" <?php if ( is_numeric( $min_value ) ) : ?>min="<?php echo esc_attr( $min_value ); ?>"<?php endif; ?> <?php if ( is_numeric( $max_value ) ) : ?>max="<?php echo esc_attr( $max_value ); ?>"<?php endif; ?> name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $input_value ); ?>" title="<?php _ex( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) ?>" class="input-text qty text" size="4" />
    <input class="plus" type="button" value="+">
</div>
$('.plus').on('click', function(e) {
    var val = parseInt($(this).prev('input').val());
    $(this).prev('input').attr( 'value', val+1 );
});

$('.minus').on('click', function(e) {
    var val = parseInt($(this).next('input').val());
    if (val !== 0) {
        $(this).next('input').val( val-1 );
    } 
});

The above code changes the value of the text visually box but doesn't change the value in the code.As a result, woocommerce doesn't get any changes of quantity.On the other hand if I press up/down button of keyboard, changes of value is being got by woocommerce.I think it is happening because I have used .val() instead of .attr(), I changed to attr() many times but in vain.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Tanvir
  • 113
  • 3
  • 11
  • This seems to work fine in jsfiddle: https://jsfiddle.net/o2amr91n/ – DaMaGeX Jan 04 '16 at 17:20
  • Yes .attr() is working but still woocommerce doesn't get value of input.Example is here http://jollyfine.co/shop/product/12-box-of-pick-your-own/ – Tanvir Jan 04 '16 at 17:44
  • You can try looking into this plugin: https://nwordpress.org/plugins/woocommerce-quantity-increment/ – DaMaGeX Jan 04 '16 at 18:01
  • It looks like input tags with these classes `input-text qty text` register the change when u click on the quantity number. And those changes reflect on your basket as well. Maybe on clicking `.plus` and `.minus` u should update the closest input element with these classes: `input-text qty text` as well. – sandeep s Jan 04 '16 at 18:29
  • @sandeep You are right.The problem is in there.I checked it by removing `input-text qty text` .Then woocommerce doesn't get input value anymore.Can you suggest me how to fix it with my js? – Tanvir Jan 04 '16 at 19:35
  • First of all, high five for purchasing my Mix and Match plugin! The issue seems to be that Mix and Match uses some complex front-end validation stuff using jQuery before the form is submitted. What appears to be happening is that changing an input's value via jQuery does not trigger the `.change()` event that is monitoring the form and re-validating every time a quantity is modified. This is weird, but appears to be a problem with jQuery itself. See [this fiddle](https://jsfiddle.net/57deh38c/1/). – helgatheviking Jan 04 '16 at 22:47
  • That said, this is a common enough feature that I will look into how to make it work.... assuming that it won't take forever. Already seeing [this](http://stackoverflow.com/a/4672519/383847) and [this](http://stackoverflow.com/a/3179392/383847) to help work around this. – helgatheviking Jan 04 '16 at 22:49

2 Answers2

6

Following up on my above comment, this answer explains that jQuery's change event is only triggered by a manual browser event. Therefore, changing the value of an input via jQuery does not trigger the change event so we need to trigger it manually by calling .change() on the input.

Here is my updated fiddle showing the fix outside of the Mix and Match context.

Pertaining to Mix and Match specifically, we just need to chain a .change() event to the input after the value has been changed. I tweaked how the input is identified, but that's not a big difference.

Edit: Now takes into account the input's "step".

$('.quantity').on('click', '.plus', function(e) {
    $input = $(this).prev('input.qty');
    var val = parseInt($input.val());
    var step = $input.attr('step');
    step = 'undefined' !== typeof(step) ? parseInt(step) : 1;
    $input.val( val + step ).change();
});

$('.quantity').on('click', '.minus', 
    function(e) {
    $input = $(this).next('input.qty');
    var val = parseInt($input.val());
    var step = $input.attr('step');
    step = 'undefined' !== typeof(step) ? parseInt(step) : 1;
    if (val > 0) {
        $input.val( val - step ).change();
    } 
});

I'll be adding this to my FAQ soon.

helgatheviking
  • 25,596
  • 11
  • 95
  • 152
  • Hi! I have a problem in the Checkout page: the quantity variation does not update the price, and as if she did not recognize the new input value number. do you know how fix? – Marco Romano Feb 24 '17 at 10:00
  • I have move the jQuery in the php files, now work but only one time, after the first update is not passible make any variation. Cloud help me pleace? :) – Marco Romano Feb 24 '17 at 10:28
  • @MarcoRomano You should make a new question and perhaps someone can help you. – helgatheviking Feb 24 '17 at 15:56
  • Thank you! anyway in this time I have fix the problem! :) I use a part of js form one plug-in, now work... (i know is not the best solution but work and is light!) Best – Marco Romano Feb 24 '17 at 16:31
3

@helgatheviking your code doesn't work for me.But I am happy that your suggestions solved my problem.I just added .change() along with .val() and it works :)

the final code Is:

$('.plus').on('click',function(e){

var val = parseInt($(this).prev('input').val());

$(this).prev('input').val( val+1 ).change();


});
$('.minus').on('click',function(e){

var val = parseInt($(this).next('input').val());
if(val !== 0){
    $(this).next('input').val( val-1 ).change();
} });
Tanvir
  • 113
  • 3
  • 11
  • Since our code looks mostly the same, I'd guess your HTML markup is a little different and my CSS selectors don't work for you. – helgatheviking Feb 24 '17 at 15:43