Support basic arithmetic in your numeric inputs.
Try it yourself (Press enter or leave the input to evaluate):
QwickMaffs has two functions, `bind` to , `exec`. This takes the text in the input and a set of configuration options.
The bind
function is the easy way to use QwickMaffs. It take an input and makes it so it automatically processes the
any math term when the user presses enter or the input looses focus.
It also adds an undo feature, where pressing ESC during editing reverts all changes since the input gained focus.
import { bind } `qwick-maffs/input.js`;
const qmInput = bind(input, {
// See `exec` below for more options.
// Set to `true` to remove the undo feature of the ESC key
noUndo: false,
onValueChanged(val: number) {
// Called when an expression is executed successfully
}
onError(err: QMError /* -> see Error handling */) {
// Called when an invalid expression was entered
},
onUndo(prev: string) {
// Called when the user pressed ESC and the value was reset. `prev` contains the text value
// before the undo was executed.
}
});
// qmInput here is the same object as input, but with addition type info for TypeScript, so it
// can type-check the custom html events
qmInput.addEventListener('qmvaluechange', (e) => {
// Same as the `onValueChanged` callback in `bind`. The value can be accessed through
// `e.details`
});
qmInput.addEventListener('qmerror', (e) => {
// Same as the `onError` callback in `bind`. The error can be accessed through `e.details`
});
qmInput.addEventListener('qmundo', (e) => {
// Same as the `onUndo` callback in `bind`. The previous value can be accessed through
// `e.details`
});
The exec
function can be used to execute a math expression.
const result = QuickMaffs.exec('4 + 5 * 6', {
// Every property here is optional. I'm showing the default values here. If
// all options remain default, the object can be omited entirely.
decimalSep: /[,.]/, // The allowed decimal separator. This must always be a
// single character in length.
// Makes it exec will not return these errors. The parser will instead try to take a best guess
// at what the user tried to accomplish.
// E.g. MultipleNumbers will multiply the numbers, and UnbalancedParenthesis will be balanced
// automatically
ignoreErrors: QwickMaffs.Errors.MultipleNumbers | QwickMaffs.Errors.UnbalancedParenthesis,
// Sets the operators supported in the expression. Here, we take all default operators and add
// "%", which divides a number by 100
operators: [
...QwickMaffs.DefaultOptions.operators,
{
op: '%',
assoc: 'suffix',
precedence: 3,
apply: (x) => x / 100,
},
],
// Constant values available. Here, we add a constant "e".
constants: {
...QwickMaffs.DefaultOptions.constants,
e: Math.E,
},
// Functions available. Functions are called by their name followed by
// parenthesis with the parameters.
// Here, we add `min` and `max` function.
functions: {
...QwickMaffs.DefaultOptions.functions,
min: Math.min,
max: Math.max,
}
});
The return value can either be a number value if the execution was successful, or an error object. The function will not throw exceptions.
The errors returned will have the shape { pos: number, error: number }
, where pos
is the string position at which the error occurred and error
is an error code.
QwickMaffs.Errors
contains an enum of all possible error codes. Error codes passed to the
ignoreErrors
will never be returned. Instead, QwickMaffs will attempt to silently fix the
issue.
A closing parenthesis without a preceding opening, or an opening parenthesis that is never closed.
If ignored: An unexpected closing parenthesis will insert a new opening parenthesis at the very start. An unclosed parenthesis will insert a new closing parenthesis at the end.
A symbol was used that the parser could not interpret.
If ignored: The symbol will be ignored.
An operator is missing it's left or right parameter.
The computation resulted in more than one number. (E.g. the user entered `8 4`).
If ignored: The values will be multiplied, allowing syntax like (`8(4)`, but operator ordering my not be as expected)
The returned no numbers (Like an empty input)
If ignored: 0 is returned.
Available under MIT licence