io.input.number

A number, within the limits you set.

io.input.number asks a person for a number and hands it to your code. Set the smallest and largest value it accepts. Whole numbers only unless you allow decimal places. The server checks every answer again.

The simplest one

The whole action file, and roughly what your team sees when it runs.

src/actions/orders/refundOrderAction.ts
import { app } from '../../app';
export const refundOrderAction = app.defineAction({
name: 'Refund order',
handler: async ({ io }) => {
const amount = await io.input.number('Refund amount', {
max: 500,
decimals: 2,
helpText: 'In euros, up to 500',
});
},
});
The code. One call in an action, the whole file.
tools.example.com/actions/orders/refund_order

Refund order

Refund amount
120▲▼
In euros, up to 500
Continue
In the browser. Roughly what your team sees. Your theme decides the details.

What you can set

The settings you will reach for most, each with the line of code that turns it on.

min: 0, max: 500

Limits. The smallest and largest number accepted. Anything outside gets a message under the field.

decimals: 2

Decimal places. Whole numbers by default. Allow as many decimal places as you need; typing 49.90 gives 49.9.

helpText: 'In euros, up to 500'

Help text. A line under the field says what the number means, such as the currency.

io.input.number('Discount').optional()

Optional. The field is required by default. With .optional() it can stay empty and the handler gets undefined.

.validate((amount) => checkTotal(amount))

Your own check. .validate() runs on the server and can ask your database. It returns a message to show, or nothing when the number is fine.

amount: io.input.number('Amount'),

Next to other fields. Inside io.group the number shares one form with other fields. The handler gets all the values together.

Write your first tool today.

An async function, a few await calls, and the form is in the browser.

AwaitIO is free for small teams, made possible by companies and people who sponsor it.