Magento 2: Enhancing numerical input with Spinner Widget

We begin with a simple example to enhance numeric entering by allowing the customer to adjust values using spinner – i.e. small up and down arrows that makes a value increment or decrement.

Article 4 - 01Figure 1. Spinner widget

This widget is created on top of the regular input text element with some additional scripting.




require([
     'jquery',
     'jquery/ui',
     ],
     function($, spinner) {
          $(".spintest").spinner();
     }
);

Listing 1. Creating simple spinner

The javascript code above will create a Spinner widget with zero as the initial value. The customer can increment or decrement its value just by pressing the up and down arrows.

Spinner can be set with certain minimum and maximum limits, as well as increment steps. It can be done by entering additional options to the spinner function. Let's make the example above a little more complex: set the lower and upper limits as 0 and 100 and make each incremental step equal to 5.


require([
     'jquery',
     'jquery/ui',
     ],
     function($, spinner) {
          $(".spintest").spinner({
               max: 100,
               min: 0,
               step: 5,
          });
     }
);

Listing 2. Spinner with limits and step

These are not the only parameters available for this widget. Here are some interesting options that can turn Spinner into a powerful numeric value entering tool:

  • incremental. By default, this option equals to false, and the increment size comes from the step property. It can be bound to the callback function with an integer parameter that is the number of subsequent clicks on the spin arrows, which returns the increment step size. This allows us to change the speed of value spinning, which is very useful for big numbers.
  • spin. This is a callback event-handling function, which has two parameters – event and ui. It can be used to set the value of the spinner field each time a customer clicks on spinner arrows.
  • numberFormat. By default, it is equal to ‘n’, which stands for numeric value. If the store has a Globalize library available, this parameter can be set to ‘C’ and used to spin currency values. This parameter is used along with the culture format, which sets the location, and which currency is used for spins.

Let's create a spinner with a dynamic increment rate. If the customer holds an arrow and the spin rolled 10 times, we increase step size to 10. If they continue holding the button and value increase exceeds 100, then we adjust the step to 100.


require([
     'jquery',
     'jquery/ui',
     ],
     function($, spinner) {
          $(".spintest").spinner({
               max: 10000,
               min: 0,
               incremental: function (spins) {
                    if(spins > 10 && spins < 20) {
                         return 10;
                    }
                    if(spins >= 20) {
                         return 100;
                    }
                    return 1;
               }
          });
     }
);

Listing 3. Controlling spin speed

Consider the code on this listing. Notice the block and check whether the spin count is above 20. We can not check the spinner value here, so we do it indirectly. When the customer holds an arrow for 10 spins, we make the step 10. But to detect an increase in value over 100, we just need to check for 20 spins passed (as 10 times 10 gives you 100).

But by using the spin callback, we can control the spinner value as well. For example, let’s make a cycle spinner: we'll forcibly set its value to the minimum, when it’s spinned to the upper limit, and vice versa. Here is the code:


require([
     'jquery',
     'jquery/ui',
     ],
     function($, spinner) {
          $(".spintest").spinner({
               max: 10000,
               min: -1,
               spin: function (event, ui) {
                    if (ui.value > 9999) {
                         $(this).spinner( "value", 0);
                         return false;
                    } else if (ui.value == -1) {
                         $(this).spinner( "value", 10000);
                    return false;
               }
          }
     });
}
);

Listing 4. Cycling value spinning

The function spin is fired every time the spin button is clicked and given a new value set, but before it’s displayed. So we can just assign value equity to the limits, and forcibly set a new value. Notice, that the min property should be one unit lesser than actually is in place -it allows the customer to still spin value down even when lower limit reached.

Using the numberFormat and culture properties allows us to create a complex currency spin widget. But to make it work, the store should have Globalize installed locally. This Javascript library is very complex unto itself, and is used to create clean Javascript code, separated from locale-dependent customizations, which exceeds the topic of this article. Information on Globalize can be found at here, and the example of a custom currency spinner is located here.

The Spinner is not the only widget available to enhance numeric input. In the next article, Slider will be considered, which also allows for some very interesting approaches to data input visualization.

A Ready-to-deploy project with this example is available from our Github.

Loading...