Menü schliessen
Created: June 9th 2021
Last updated: December 10th 2021
Categories: Common Web Development,  IT Development,  JavaScript Development
Author: Tim Fürer

JavaScript & jQuery: Custom Number-Spinner Buttons

Tags:  custom,  Javascript,  jQuery,  script
Donation Section: Background
Monero Badge: QR-Code
Monero Badge: Logo Icon Donate with Monero Badge: Logo Text
82uymVXLkvVbB4c4JpTd1tYm1yj1cKPKR2wqmw3XF8YXKTmY7JrTriP4pVwp2EJYBnCFdXhLq4zfFA6ic7VAWCFX5wfQbCC

Do you need custom spinner buttons for your number input fields?

These custom buttons come with the following features:

  • Incrementing/Decrementing an input (of course).
  • Full control over their look.
  • Continuous incrementing/decrementing when holding button, speeding up the interval at which this is done the longer the button is held.
  • Basic Mobile support.

You may modify and use the following code however you like. Enjoy!


Demonstration

Take a look at this interactive demonstration:

 


Source Code

Additional information:

  • Use the 'input-inc' class to define an incrementation button and the 'input-dec' class to define a decrementation button.
  • On default, the script will automatically target the first input that has a type of 'number' (input[type=number]), inside the container of the pressed button. If you require this to be more specific, change the selectors.
  • Buttons which are being held, will automatically be given the 'beingHeld' class until they're let go of. This class is to be utilized for styling purposes.

Now, on to the code:

/* [Custom Number Spinner - BEGIN] */

let spinnerButtonHold = 0,
	spinnerButtonWasHeld = false,
	spinnerPreventClick = false;

// Increment/Decrement

jQuery('.input-inc, .input-dec').click(function() {
	let numberInput = jQuery(this).parent().find('input[type=number]')[0],
		inputValue = parseInt(jQuery(numberInput).val()),
		inputMin = jQuery(numberInput).attr('min'),
		inputMax = jQuery(numberInput).attr('max'),
		isInc = jQuery(this).hasClass('input-inc');

	if (spinnerPreventClick)
	{
		spinnerButtonWasHeld = false;
		spinnerPreventClick = false;
		jQuery(this).removeClass('beingHeld');
		return;
	}

	if (spinnerButtonWasHeld)
	{
		spinnerPreventClick = true;
	}
	
	/* Safari fix - BEGIN */
	if (isNaN(inputValue) && !isNaN(inputMin) || !isNaN(inputMin) && isInc && inputValue < inputMin)
	{
		jQuery(numberInput).val(inputMin);
		return;
	}
	
	if (isNaN(inputValue) && isInc)
	{
		jQuery(numberInput).val(1);
		return;
	}
	
	if (isNaN(inputValue))
	{
		jQuery(numberInput).val(-1);
		return;
	}
	
	if (isNaN(inputValue) && !isNaN(inputMin) || !isNaN(inputMin) && isInc && inputValue < inputMin)
	{
		jQuery(numberInput).val(inputMin);
		return;
	}
	
	if (!isNaN(inputMax) && !isInc && inputMax < inputValue)
	{
		jQuery(numberInput).val(inputMax);
		return;
	}
	/* Safari fix - END */
	
	if (isInc)
	{
		numberInput.stepUp();
		return;
	}
	
	numberInput.stepDown();
});

// Hold button

jQuery('.input-inc, .input-dec').on('mousedown touchstart', function() {
	counterHold(jQuery(this), 0);
}).on('mouseup mouseleave touchend', function() {
	clearTimeout(spinnerButtonHold);
	jQuery(this).removeClass('beingHeld');
});

// Hold function

function counterHold(counterButton, intervalLevel)
{
	let holdInterval = 250;

	if (intervalLevel > 0)
	{
		holdInterval = 125;
	}

	if (intervalLevel > 3)
	{
		holdInterval = 75;
	}

	if (intervalLevel > 13)
	{
		holdInterval = 50;
	}

	if (intervalLevel > 33)
	{
		holdInterval = 25;
	}

	if (intervalLevel > 48)
	{
		holdInterval = 10;
	}

	spinnerButtonHold = setTimeout(function() {		
		spinnerButtonWasHeld = true;
		spinnerPreventClick = false;

		jQuery(counterButton).trigger('click').addClass('beingHeld');
		counterHold(counterButton, intervalLevel + 1);
	}, holdInterval);
}

/* [Custom Number Spinner - END] */

Download file | Download minified file


browser built-in buttons

As you've just added your own spinner buttons, you may want to disable the built-in ones.

Custom buttons - Disable browser built-in buttons

Firefox

Apply this CSS property to your input field:

 -moz-appearance: textfield;

Webkit (Safari, Chrome, etc.)

Use the following CSS rule (remember to change the selector to match your input field):

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button
{
    -webkit-appearance: none;
}