What is the mechanism behind the functionality of the input type=number spinner in browsers?

I want to recreate the spinner feature found in input type=number.

<input type=number step=0.3/>

When clicking on the up arrow of the spinner, the value increases by 0.3 (0.3, 0.6 , 0.9 , 1.2 , 1.5 ...etc).

However, if the current value is 1.4 and I click increase, it jumps to 1.5 which is a 0.1 increment, while at 1.3 it's a 0.2 increment.
My question is how can I determine the closest step increment when increasing the current value?!

Below is my solution:

export class Spinner { 
        increase(currentValue, step) {
           const step = step || 1;
           const decimalSize = getDecimalSize(step);
           const current = normalize(currentValue, decimalSize);
           const ratio = Math.ceil(normalize(current / step, decimalSize));
           let increment = normalize(ratio * step, decimalSize);
         
        if (
            normalize(current % step, decimalSize) === 0 ||
            current === increment ||
            normalize(current % step, decimalSize) === 1
        ) {
            increment = normalize(current + step, decimalSize);
        }
    }
}

export function getDecimalSize(value: number) {
    if (Math.floor(value) === value) return 0;
    return value.toString().split(".")[1]?.length || 0;
}

export function normalize(value: number, decimalSize: number): number {
    decimalSize = decimalSize || 1;
   const n = Math.pow(10, decimalSize + 1);
   return Math.round(value * n) / n;
}


This logic works well for positive numbers but not as expected with negative values.

For example, when the current value is -2 with a step of 0.3, it results in -1.8 instead of -1.7

Answer №1

According to the HTML Standard

When an element is experiencing a step mismatch, the browser may decide to round the value to the nearest number that avoids this issue. In cases where there are two possible options, browsers are advised to select the one closest to positive infinity.

Your web browser is most likely adjusting the step value to prevent any mismatch. For example, it rounds 1.4 to 1.5 because 1.5 is exactly 5 steps away from 0, whereas 1.7 would be 5.666 steps away. The same logic applies to negative numbers, with 1.8 being divisible by 0.3 while 1.7 is not.

It's important to note that in some scenarios, like the case of rounding to 1.8 instead of 1.5, the actual behavior deviates from the specification. These discrepancies can occur and may potentially change in future updates.

I haven't tested this myself, but it's conceivable that different browsers could yield dissimilar results.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

BottomNavigation wrapping React Router is failing to load the updated component

I'm struggling to understand why I can't seem to load the DMO page from a BottomNavigation component. Navigating to "/dom" works fine, but clicking the buttons doesn't do anything. The initial "/" loads perfectly. Any ide ...

What could be causing the issue with my validation for alphabetical input?

I am currently working on a registration form that only accepts alphabetical input. However, I am facing an issue where my error message appears regardless of whether I input an alphabetical or special character. According to my understanding, the code sho ...

Find the item in the pop-up window

When removing a user from my list, a JavaScript popup pops up prompting to confirm the action with two buttons "OK" / "Annuler" : Is there a way to use Selenium to find and interact with these buttons? ...

The code to trigger the button with the ID 'Button' using Document.getElementById() is not executing the associated code-behind

Having just started coding in javascript/VB.NET, I am struggling to get my Button2 onClick event to work properly. The Code-Behind Click Event for Button1 in Page.aspx.vb: Protected Sub _lnbComments_Click(ByVal sender As Object, ByVal e As System.EventAr ...

Tips for utilizing the onload attribute alongside the ng-controller directive to run a function that has been established within the controller

When trying to call the submit() function as soon as the page loads, I keep encountering a submit() method not found error. The positioning of ng-controller and onload is confusing to me. If there is an alternate method in Angular to achieve this, please ...

NodeJs Importing a File

Currently working with NodeJS, I have encountered a challenge. Is it possible to require a JavaScript file in Node similar to how we do in browsers? When using the require() method, I noticed that the JavaScript file called does not have access to global v ...

ContainerView: challenges encountered when dynamically inserting views

ContainerView.pushObject() does not automatically connect dynamically added views with a Container object. The absence of an auto-wired container leads to a rendering error when a view renders a template containing a handlebars render helper. SIMPLE SCENA ...

Looking to retrieve a cookie within Vue Router in Vue 3? Utilize the following approach within your router's `index.js

Scenario: Developing a Vue3 app with express as the API backend. Express utilizes express-sessions to create a server-side session that is transmitted to the browser and received in subsequent requests. I am in the process of implementing a route guard to ...

Title remains consistent | Angular 4

Struggling to change the document title on a specific route. The route is initially set with a default title. { path: 'artikel/:id/:slug', component: ArticleComponent, data: {title: 'Article', routeType: RouteType.ARTICLE, des ...

Upon hitting submit, the form remains unresponsive

I have been developing a permissions system for my NodeJS project (Using the SailsJS MVC) and encountered an issue. After resolving my initial error as detailed here, I am now facing a problem where the form is unresponsive. It neither shows an error in th ...

Error in Prisma: Unable to retrieve data due to undefined properties (attempting to access 'findMany')

Recently, I've been working on a dashboard app using Prisma, Next.js, and supabase. Encountering an issue with the EventChart model in schema.prisma, I decided to create a new model called EventAreaChart. However, after migrating and attempting to ex ...

Utilizing jQuery for AJAX-Based Deletion of Records

Hey, I stumbled upon a code snippet that allows me to delete a row from my database using Ajax. However, there seems to be an issue where the table that should disappear when deleted is not working properly. Here is the JavaScript code: <script type=" ...

The most efficient method for documenting $.trigger in JavaScript/jQuery is through the use of JSD

When it comes to documenting in jsDuck, what is the optimal method for capturing the following event trigger: $(document).trigger('myCustomEvent'); ...

What is the best method for eliminating the initial character in every line of a textarea?

The desired output should display as LUNG,KIDNEY,SKELETON>J169>U and E, CREATININE:no instead of >LUNG,KIDNEY,SKELETON>J169>U and E, CREATININE:no. Is there a way to achieve this using JavaScript? Specifically, the ">" character at the beginnin ...

What is the process to access array elements in AngularJS?

When coding in HTML, <select class="element-margin-top" ng-model="vm.selectedRole" ng-options="(roleName,enabled) in vm.roleNames"> <option value="">All Roles</option>{{vm.roles[0]}} </select> I am tryin ...

Indication of a blank tab being displayed

I'm struggling to get my Angular directives working in my project. I've tried implementing a basic one, but for some reason it's not showing anything on the screen. Can anyone help me troubleshoot this issue? Here is my JS code: angular ...

When I toggle the div to close on mobile, I want it to show on desktop

My attempt at creating a toggle button to hide and show content was not successful. I struggle with coding in Javascript/Jquery. In the desktop view, the description displays perfectly (see image here), but in mobile view, there is a button to toggle hidi ...

What is the Best Way to Enable Tooltips to Function from External Elements?

I am currently designing a map that features points with tooltips. When hovered over, the tooltips function correctly. I am interested in exploring the possibility of making the tooltips interact with an external navigation bar. My goal is to have specifi ...

Uncovering hidden links in a menu with Python Selenium and JavaScript

Can someone provide guidance on how to activate the JavaScript submenu associated with this button, "x-auto-54"? <table id="x-auto-54" class=" x-btn avtar-x-btn x-component x-btn-noicon x-unselectable " cellspacing="0" role="prese ...

Using the spread operator in the console.log function is successful, but encountering issues when attempting to assign or return it in a

Currently facing an issue with a spread operator that's really getting on my nerves. Despite searching extensively, I haven't found a solution yet. Whenever I utilize console.log(...val), it displays the data flawlessly without any errors. Howev ...