Fork me on GitHub

Slikcalc

Slikcalc is a small javascript framework that makes it easy to add dynamic and static mathematical calculations to your html pages. Slikcalc is built to work in conjunction with any of the big javascript libraries out there. The current libraries supported are:

* if a framework you use is not currently supported, its easy to create an adapter to add support, just look at the provided adapters and follow their patterns)

How do I use Slikcalc?

Setup

Setting up Slikcalc is super simple, just download the latest release, and then include your javascript library of choice, slikcalc.js, along with the library-specific adapter. After that, you're ready to begin with either a ColumnCalc or FormulaCalc, or if you're feeling really smart, a Custom calculator.

Column Calculations

Column calculators are for when you have a collection of values that you want to apply a mathematical computation to, such as summing them, or multiplying them together. Usage includes creating a new ColumnCalc object, which can take configuration options, and then call the addRow() method for each value you want to add, which can also take configuration options. The total of the calculation is inserted into the field identified by one of the options passed into the constructors configuration.

Constructor options

var columnCalc1 = slikcalc.create('column', {
            total: {
                id: 'totalElementId', //Optional.  Id of the element where the total calculation of a collection of rows will go.
                operator: '+', //Optional, defaults to '+'. Valid values = ( +, -, *, x, / ).  Mathematical operator used to calculate the total of a collection of rows.
            },
            registerListeners: true/false, //Optional, defaults to false.  If true, keyup event listeners will be attached to inputs that will trigger the calculate method.
            calcOnLoad: true/false //Optional, defaults to false. Causes calculator to perform its calculate function on the page load event
        });

addRow() options

columnCalc.addRow({
            id: 'elementId', //Element id that holds the value to calculate
            checkbox: {
                id: 'checkboxId' //Optional.  The id of the checkbox associated with this row.  This controls whether this rows total is included in the calculators total.
                invert: true/false //Optional, default value is false.  If true, row will NOT be included in the total calculation if checkbox is selected, and will be include if the checkbox is not selected.
            }
        });

Addition Column Calc

        var columnCalc1 = slikcalc.create('column', {
            total: { id: 'cc-1-total' },
            registerListeners: true,
            calcOnLoad: true
        });
        columnCalc1.addRow({ id: 'cc-1-1' });
        columnCalc1.addRow({ id: 'cc-1-2' });
        columnCalc1.addRow({
            id: 'cc-1-3',
            checkbox: { id: 'cc-1-3-c' }
        });
Amount One:
Amount Two: 7.29
Amount Three:
  Total:  
This calculator adds up each row in the column. The second row shows that you can include non-editable fields that contain plain text. The third row uses a checkbox that controls if the row is included in the total calculation.

Multipy Column Calc

        var columnCalc2 = slikcalc.create('column', {
            total: { id: 'cc-2-total' },
            registerListeners: true,
            calcOnLoad: true,
            totalOperator: '*'
        });
        columnCalc2.addRow({ id: 'cc-2-1' });
        columnCalc2.addRow({ id: 'cc-2-2' });
        columnCalc2.addRow({
            id: 'cc-2-3',
            checkbox: {
                id: 'cc-2-3-c',
                invert: true
            }
        });
Amount One:
Amount Two:
Amount Three:
  Total:  
This calculator multiplies the rows together. The third row uses a checkbox that has the invert flag set to true, which means that if it is checked, the row is NOT included, and if it is not checked, it IS included in the calculation.

Formula Calculations

Formula calcs are more flexible than the Column calcs, and can be used in a few different ways. The concept behind them is that you define a formula as a string, and then plug in different input fields to match up to the variables in your formula.

For example, at the top of this page are two formula calcs, where one is a formula of '( a / b ) + c = d'. Each of the inputs is mapped to one of the variables through configuration. One slight variation when passing in the formula strings in the constructor, is you have to wrap your variables in curly braces {}. So the previous formula would look like:

'( {a} / {b} ) + {c} = {d}'.

Formula calcs can be configured as one set of inputs mapped to the formula, or as a collection of inputs each mapped to the same formula. This is useful if you have a table with multiple rows that each need to calculate the same formula. In this case you can simply pass the configuration for each row, and optionally, an input to store the total of each row of formulas into. This total can be a sum of the formula calculations, or any of the other supported operators (+, -, x, *, /). Note that x and * both multiply the values, but are both included for convenience.

Constructor options:

var formulaCalc = slikcalc.create('formula', {
            formula: '{a} + {b} = {c}', //Required formula string
            calcOnLoad: true/false, //Optional, defaults to false. Causes calculator to perform its calculate function on the page load event
            total: {
                id: 'totalElementId', //Optional.  Id of the element where the total calculation of a collection of rows will go.
                operator: '+', //Optional, defaults to '+'. Valid values = ( +, -, *, x, / ).  Mathematical operator used to calculate the total of a collection of rows.
            },
            registerListeners: true/false, //Optional, defaults to false.  If true, keyup event listeners will be attached to inputs that will trigger the calculate method.
            vars: {
                a: {
                    id: 'first-value', //This would map the input 'header-2-1' to the variable {a} in the formula string
                    defaultValue: 0 //Optional, default is 0. This value is used if there is no value in the mapped input
                 },
                b: { id: 'second-value' }, //This would map the input 'header-2-2' to the variable {b} in the formula string
                c: { id: 'row-total'} //This would map the input 'header-2-3' to the variable {c} in the formula string
            }  //Optional.  If a 'vars' configuration is passed in the constructor, it is treated as if you called addRow and passed it in.  This is for convenience when you have only one set of inputs for you calculation.
        });

addRow() Options

formulaCalc.addRow({
            vars: {
                a: {
                    id: 'first-value', //This would map the input 'header-2-1' to the variable {a} in the formula string
                    defaultValue: 0 //Optional, default is 0. This value is used if there is no value in the mapped input
                 },
                b: { id: 'second-value' }, //This would map the input 'header-2-2' to the variable {b} in the formula string
                c: { id: 'row-total'} //This would map the input 'header-2-3' to the variable {c} in the formula string
            }, //Required
            checkbox: {
                id: 'checkboxId' //Optional.  The id of the checkbox associated with this row.  This controls whether this rows total is included in the calculators total.
                invert: true/false //Optional, default value is false.  If true, row will NOT be included in the total calculation if checkbox is selected, and will be include if the checkbox is not selected.
            },
            registerListeners: true/false //Optional, defaults to false.  If true, keyup event listeners will be attached to inputs that will trigger the calculate method.  This overrides the flag passed in on the constructor.
        });

Simple Formula Calc

        var formulaCalc1 = slikcalc.create('formula', {
            formula: '( {a} / {b} ) + {c} = {d}',
            registerListeners: true,
            calcOnLoad: true,
            vars: {
                a: { id: 'formula-1-1' },
                b: { id: 'formula-1-2', defaultValue: 1 },
                c: { id: 'formula-1-3' },
                d: { id: 'formula-1-total' }
            }
        });
( / ) + =
This is a basic Formula calculator that calculates a / b + c and updates the value into a field. Since there is only one set of fields for calculation, that vars object is passed in the constructor.

Multi-row Formula Calc

        var formulaCalc2 = slikcalc.create('formula', {
            formula: '{a} * {b} = {c}',
            registerListeners: true,
            calcOnLoad: true,
            total: { id: 'formula-2-total' }
        });
        formulaCalc2.addRow({
            vars: {
                a: { id: 'formula-2-1a'},
                b: { id: 'formula-2-1b'},
                c: { id: 'formula-2-1c'}
            }
        });
        formulaCalc2.addRow({
            vars: {
                a: { id: 'formula-2-2a'},
                b: { id: 'formula-2-2b'},
                c: { id: 'formula-2-2c'}
            },
            checkbox: { id: 'formula-2-2-c' }
        });
x
x
Total:  
This Formula calculator demonstrates using the ability to combine multiple rows of the same formula into one calculator, and have the total of each row summed up into another total. It also shows how you can add a checkbox to control if that row is included in the total.

Chaining Calculators

Sometimes you may have a collection of calculators that must fire in a particular order for everything to calculate correctly. Slikcalc takes this into consideration and provides a very simple interface for controlling this. This is handled with two methods, triggers() and dependsOn(). If we have a "calculateOne" calc object that should trigger the calculation of "calculatorTwo" object, we can set this up as follows:
calculatorOne.triggers(calculatorTwo);

This same behavior can be created by describing it in reverse using the dependsOn() method:
calculatorTwo.dependsOn(calculatorOne);

This allows you to write your calculator objects in small, contained objects, and then chain them together as needed. A helpful feature with these methods is that they each return the calculator object passed in to the method, which makes chaining multiple calculators together easier to read. For example, if we have three calculator objects, calc1, calc2, an calc3, and they need to fire eachother in that order, we can accomplish this as follows:
calc1.triggers(calc2).triggers(calc3);

Custom Calculations

Custom calculators are exactly what they sound like, completely custom, and they can do anything you want them to. All that is required is that you create your own class, extend slikcalc.BaseCalc using slikcalc.extend(), and then implement a calculate method in your class. The rest is up to you! I'll post some examples of custom calculators soon.