# Write your own parsing logic for the Calculations field

The ﻿Calculations field is a read-only field that takes content from other fields' content. There's loads you can do, from arithmetic, comparing values and even logic. Keep reading on the [docs](https://verbb.io/craft-plugins/formie/docs/feature-tour/fields#calculations).

You might like to include your own logic for how values in the Calculations field are treated. Under the hood, we use a JavaScript implementation of the [Symfony Expression Syntax](https://symfony.com/doc/current/components/expression_language/syntax.html) for handling parsing of the formula you provide for the Calculations field. You can even write your own, via JavaScript — which is what we're covering in this guide, along with how to use events to modify data.

Let's look at some practical examples.

### Currency
You might be referencing two Number fields in your Calculations field. Something like:

```twig
{fieldA} + {fieldB}

{# Given `fieldA` = 10 and `fieldB` = 5, outputs 15 #}
```
But what if we wanted to format this as a currency value, say as USD? We can do this with the fields' `afterEvaluate` JS event. This event is fired every time a referenced field's value changes — so in this case whenever `fieldA` or `fieldB` changes values.

So firstly, let's create 3 fields:
- Number (handle `fieldA`)
- Number (handle `fieldB`)
- Calculations (handle `result`)

Ensure that the `result` field has the formula `{fieldA} + {fieldB}` by picking the other two Number fields with the variable picker.

Insert the following JavaScript on the page where your form is rendered.

```js
// Fetch the Calculations field we want to format values for
const $field = document.querySelector('[data-field-handle="result"]');

// Listen to every time the formula is evaluated
$field.addEventListener('afterEvaluate', function(e) {
    const formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
    });
    
    e.detail.result = formatter.format(e.detail.result);
});
```

Here, we bind the `afterEvaluate` event to the `result` field. This will fire after the evaluation has run, and we have the result. In this case, we just want to format it, so we take the result (`e.detail.result`) and run it through our formatter, then set that value.

Rendering the field, we'll now see `$0.00` as soon as it loads (rather than `0`), and the value will be shown as a currency!

### Rounding
In almost an identical method to the above, we might also like to round numbers.

```js
// Fetch the Calculations field we want to format values for
const $field = document.querySelector('[data-field-handle="result"]');

// Listen to every time the formula is evaluated
$field.addEventListener('afterEvaluate', function(e) {
    e.detail.result = Math.round(e.detail.result);
});
```

Given the values `1.276` and `7.682` for `fieldA` and `fieldB`, respectively — the result will be `9`.

### Modifying data
So far, we've covered modifying the result generated by the evaluation, but we can also modify the content used in the formula, and the formula itself using the `beforeEvaluate` JS event.

Let's say the `fieldA` in our example has some validation logic you want to enforce. If the value entered is over 20, then you want that to be the maximum value. You could of course enforce this on the `fieldA` Number field itself, but this is just an example after all 😉

Insert the following JavaScript on the page where your form is rendered.

```js
// Fetch the Calculations field we want to format values for
const $field = document.querySelector('[data-field-handle="result"]');

// Listen to every time the formula is evaluated
$field.addEventListener('beforeEvaluate', function(e) {
    const formula = e.detail.formula;
    const variables = e.detail.variables;
    
    if (e.detail.variables.field_fieldA > 20) {
        e.detail.variables.field_fieldA = 20;
    }
});
```

You can see we're modifying the `variables` object to enforce our logic. Every value in the variables object is prefixed by `field_`, then the field handle. These are the **source** fields content, used in our formula.

Now, when setting values, `fieldA` values can still be entered over 20 (which might be valid for your use case), but the calculations will max out at `20`.

### Advanced usage
Where the `variables` in the previous example were simple numbers, you can also supply these as functions — because JavaScript! We also might like to modify the formula, to get real tricky. 😎

```js
// Fetch the Calculations field we want to format values for
const $field = document.querySelector('[data-field-handle="result"]');

// Listen to every time the formula is evaluated
$field.addEventListener('beforeEvaluate', function(e) {
    // Modify the formula (or you could supply this in the field settings)
    e.detail.formula = 'field_fieldA + field_fieldB + suffix.myMethod("🔥")';

    // Add a new variable `suffix` with a method
    e.detail.variables.suffix = {
        myMethod: function(string) {
            return ' is ' + string;
        },
    };
});
```

Given the values `1` and `5` for `fieldA` and `fieldB`, respectively — the result will be `6 is 🔥`.
