Skip to main content
In this guide, we will show you the easiest way to upgrade your custom calculator to manage loads and automatically calculate factored results based on ASCE 7 load combinations. What you will need: To build a robust load calculator, you need four specific components working together:
  1. The Settings: A toggle for Live Load Reduction rules.
  2. The Input: A table where you (or the user) define the loads.
  3. The Solver: A โ€œblack boxโ€ engine that processes the physics and load factors.
  4. The Output: A table that summarizes the results per load combination (e.g., 1.2D + 1.6L).

Download the Complete Templates

If you prefer to skip the manual setup, you can download the complete file to import into your calculator. We provide templates for both Load and Resistance Factor Design (LRFD) and Allowable Stress Design (ASD).

Download LRFD Template

LRFD: Click here to get the complete factored load template.

Download ASD Template

ASD: Click here to get the complete allowable stress template.
If you want to understand how the code works or add this to an existing tool manually, follow the steps below. While editing JSON code isnโ€™t always ideal, copy-pasting these blocks is the fastest way to get this powerful functionality running.
The explanations below apply to LRFD since that is the code demonstrated in the steps. For ASD, the difference lies only in the mathematical factors used in the โ€œSolverโ€ and โ€œOutputโ€ steps. For that, you can use the ASD template.

Step 1: Live Load Reduction Setting

Before defining specific loads, we need a global setting to handle Live Load Reduction (LLR). Why do we need this? ASCE 7 allows a reduction (typically 0.5) for live loads when they act as a โ€œcompanionโ€ load (not the primary load) in a combination. However, this is conditional, it applies to loads under 100 psf that are not in garages or places of public assembly. By adding this widget, you allow the user to toggle this code provision on or off, ensuring the solver applies the correct factor (0.5L0.5L vs 1.0L1.0L) during calculation.
1

Open the JSON Editor

Open your calculatorโ€™s JSON editor.
2

Paste the LLR Code

Copy the llr_widget.json code block and paste it into your calculator.
llr_widget.json
{
    "type": "sheetTemplateWidgets",
    "attributes": {
        "type": "lookup",
        "label": "Use Reduced Companion Live Load?",
        "symbol": "\\text{LLR}",
        "description": "For live loads under 100 psf which are not in a garage or a place of public assembly, a 50% reduction in the live load is allowed when it is used as a companion load.",
        "references": "ASCE 7-16, Cl 2.3.1.1",
        "referencesJson": null,
        "authorNotes": null,
        "referenceImage": null,
        "defaultValue": "No",
        "defaultValueMks": null,
        "defaultValueFps": null,
        "export": null,
        "hidden": null,
        "visibleIf": null,
        "showInSuperSummary": false,
        "enableAutosize": null,
        "radioListDisplay": true,
        "dataFilter": null,
        "valueColumnIndex": 0,
        "enableSelectorChecks": null,
        "checks": [],
        "dataColumns": [
            {
                "label": "Live Load Reduction Flag",
                "symbol": "\\text{LLR}",
                "units2": null
            },
            {
                "label": "Live Load Factor",
                "symbol": "f_1",
                "units2": null
            }
        ],
        "dataTable": [
            [
                "Yes",
                0.5
            ],
            [
                "No",
                1
            ]
        ],
        "selector": null,
        "referenceId": "LLR",
        "equation": []
    }
},

Step 2: The Input Table

Next, you need a place to input your loads. We will create a table called โ€œPoint & Moment Loadsโ€ that allows for vertical loads (PyP_y) and moment loads (MM). What is happening in this table? The code for this table defines the structure of your input:
  • Label: A text field to name the load (e.g., โ€œColumn Aโ€).
  • Location: A coordinate defining where the load applies.
  • Load Magnitudes: This is an object that groups the Type (Dead, Live, Snow, etc.), the Vertical Force (PyP_y), and the Moment (MM) together.
  • Link Row: This is the most powerful feature. It allows users to โ€œchainโ€ reactions from other calculators. When a user clicks the link icon, the table automatically imports the reactions from a beam or column calculation elsewhere in the project.
1

Locate Insertion Point

Find the end of the LLR widget you just pasted.
2

Paste the Input Table Code

Copy the input_table.json code block and paste it immediately after the LLR widget.
input_table.json
{
    "type": "sheetTemplateWidgets",
    "attributes": {
        "type": "table",
        "label": "Point & Moment Loads",
        "symbol": "P,M",
        "description": "A **point load** acts over a relatively small area. For example, a weight that has been hung from a ceiling or a column that is supported by a beam. This load may be of any magnitude, and may be located at any point along the beam. Note that all point loads entered in this table are applied perpendicular to the beam. \n\nA **moment load** causes the rotation of a member about an axis. There are few examples of pure moment loads applied in a typical structure, though the most common occurs if there is a fixed connection between a beam and column. Moment loads are also often used to idealize the effect of horizontal loads on cantilevered attachments on a beam (e.g. a satellite antenna attached to a roof rafter subjected to wind loads).\n\n**Another individual beam or column** bearing on or connected to this one may be linked into this table by clicking on the chain link icon on the right side of the table. Note that if you wish to connect a repeating joist or rafter, it may be easier to link these as a Line Load using the table above instead.\n\nEach row of this table represents a single location, but as many rows as desired may be created. Usually, an **'Alternative Minimum Live Load'** will appear here by default. This Alternative Minimum Live Load, with load type 'L2', is NOT applied at the same time as the normal live load. For some types of surfaces, the building codes require that beams be able to support at least a minimum concentrated live load, regardless of the normal live load, and that is this value. If it is blank (zero), then the default surface type you have selected in your Project Defaults does not require an alternative minimum live load.",
        "references": " ",
        "referencesJson": null,
        "authorNotes": null,
        "referenceImage": null,
        "visibleIf": null,
        "showInSummary": true,
        "showInSuperSummary": false,
        "apiOutput": null,
        "dataColumns": [
            {
                "type": "input",
                "label": "Label",
                "units2": "",
                "inputType": "string",
                "referenceId": "Label"
            },
            {
                "type": "computed",
                "label": "Location",
                "symbol": "x",
                "units2": "ft",
                "equation": [
                    {
                        "result": "0 ft",
                        "condition": "@default"
                    }
                ],
                "unitsMks": "mm",
                "cellChecks": [
                    {
                        "result": "Location is outside member",
                        "condition": "self() >= 0 ft"
                    }
                ],
                "referenceId": "x"
            },
            {
                "type": "object",
                "label": "Load Magnitudes",
                "symbol": "P,M",
                "dataColumns": [
                    {
                        "type": "lookup",
                        "label": "Load Type",
                        "dataTable": [
                            [
                                "(D) Dead Load",
                                "D"
                            ],
                            [
                                "(L) Live Load",
                                "L"
                            ],
                            [
                                "(L2) Alt. Live Load",
                                "L2"
                            ],
                            [
                                "(Lr) Roof Live Load",
                                "Lr"
                            ],
                            [
                                "(S) Snow Load",
                                "S"
                            ],
                            [
                                "(R) Rain Load",
                                "R"
                            ],
                            [
                                "(W,dn) Ult. Wind Down or Lateral",
                                "W,dn"
                            ],
                            [
                                "(W,dn2) Ult. Wind Down 2",
                                "W,dn2"
                            ],
                            [
                                "(W,up) Ult. Wind Up",
                                "W,up"
                            ],
                            [
                                "(W,up2) Ult. Wind Up 2",
                                "W,up2"
                            ],
                            [
                                "(Ev) Vertical Earthquake",
                                "Ev"
                            ],
                            [
                                "(Eh) Horizontal Earthquake",
                                "Eh"
                            ],
                            [
                                "(Eh) Horizontal Earthquake 2",
                                "Eh2"
                            ]
                        ],
                        "referenceId": "load_type",
                        "valueColumnIndex": 1
                    },
                    {
                        "type": "input",
                        "label": "Vertical Load",
                        "symbol": "P_y",
                        "units2": "kip",
                        "unitsFps": "lb",
                        "unitsMks": "kN",
                        "allowEmpty": true,
                        "referenceId": "P_y"
                    },
                    {
                        "type": "input",
                        "label": "Moment Load",
                        "symbol": "M",
                        "units2": "kip*ft",
                        "unitsFps": "lb*ft",
                        "unitsMks": "kN m",
                        "allowEmpty": true,
                        "referenceId": "M"
                    }
                ],
                "referenceId": "P_M",
                "defaultValue": {
                    "D": [
                        0,
                        0
                    ],
                    "L": [
                        0,
                        0
                    ],
                    "Lr": [
                        0,
                        0
                    ]
                }
            },
            {
                "type": "linkRow",
                "mappings": [
                    {
                        "sourceColumn": 0,
                        "targetColumn": 0,
                        "prependSheetName": true
                    },
                    {
                        "sourceColumn": 4,
                        "targetColumn": 2
                    }
                ],
                "description": "Link to reaction",
                "referenceId": "linkMembersY",
                "sourceDataColumns": [
                    {
                        "label": "Support"
                    },
                    {
                        "label": "Location",
                        "sorted": true,
                        "units2": "ft",
                        "unitsMks": "mm"
                    },
                    {
                        "label": "Ult. Vertical Reaction",
                        "units2": "kip",
                        "unitsFps": "lb",
                        "unitsMks": "kN"
                    },
                    {
                        "label": "Ult. Moment Reaction",
                        "units2": "kip*ft",
                        "unitsFps": "lb*ft",
                        "unitsMks": "kN m"
                    },
                    {
                        "label": "Load Types to Be Linked"
                    }
                ]
            }
        ],
        "defaultValue": [],
        "defaultValueMks": null,
        "defaultValueFps": null,
        "expand": true,
        "export": null,
        "hidden": null,
        "tableLength": null,
        "checks": [],
        "referenceId": "loadsConc"
    }
},

Step 3: The Solver (The Engine)

Next, you need a program that manages those loads. We call this the Solver. You donโ€™t need to write the complex math code for this, but it is important to understand the logic the solver uses. How the Solver Works:
  1. Separation of Types: The solver separates every load by type (D, L, S, W, etc.). It calculates the forces for only dead loads, then only live loads, etc. It does not combine them yet.
  2. The โ€œVirtual Beamโ€ Logic: Even though we are just calculating factored loads, we use a โ€œVirtual Beamโ€ in the background. We set this beam to be 20 ft long with fixed supports.
  3. Why use a Beam? This creates a stable mathematical environment for the solver to run without errors. Crucially, by using โ€œBeam Logicโ€ instead of โ€œColumn Logic,โ€ the solver respects the direct Moment inputs you entered in the table. If we used simple column logic, it might ignore the moments or look only for eccentricity.
1

Scroll to the End

Scroll to the bottom of your included array.
2

Paste the Solver Code

Copy the solver_logic.json code block and paste it at the end of the array.
solver_logic.json
{
    "type": "sheetTemplateWidgets",
    "attributes": {
        "type": "remote",
        "symbol": "FEM_{LRFD}",
        "equation": [
            {
                "result": "{zeroTol:1e-6, L:20, r: [[\"Fixed\", 0]], EI:1000, EA:1000, SW:0, loadsConc:loadsConc, displaylc:1, \"len_convert\":1, \"dl_convert\":1/1000, \"ldl_convert\":1/1000, loadTypesBase:[\"D\",\"L\",\"Lr\",\"S\",\"R\",\"W,dn\",\"W,up\",\"Ev\",\"Eh\"], linkExclude:[\"L2\"], includeZeroNonConc: false, combNonConc:[[\"L\", 1], [\"W,dn\", 1], [\"W,up\", 1], [\"Eh\",1]], liveLoadConc: \"L\", \"LCs_str\": [ [\"1.4D\", 1.4, 0, 0, 0, 0, 0, 0, 0, 0],[\"1.2D + 1.6L + 0.5Lr\", 1.2, 1.6, 0.5, 0, 0, 0, 0, 0, 0], [\"1.2D + 1.6L + 0.5S\", 1.2, 1.6, 0, 0.5, 0, 0, 0, 0, 0], [\"1.2D + 1.6L + 0.5R\", 1.2, 1.6, 0, 0, 0.5, 0, 0, 0, 0],[\"1.2D + 1.6Lr + f_1L\", 1.2, 1.0, 1.6, 0, 0, 0, 0, 0, 0],[\"1.2D + 1.6Lr + 0.5W_dn\", 1.2, 0, 1.6, 0, 0, 0.5, 0, 0, 0], [\"1.2D + 1.6S + f_1L\", 1.2, 1.0, 0, 1.6, 0, 0, 0, 0, 0],[\"1.2D + 1.6S + 0.5W_dn\", 1.2, 0, 0, 1.6, 0, 0.5, 0, 0, 0],[\"1.2D + 1.6R + f_1L\", 1.2, 1.0, 0, 0, 1.6, 0, 0, 0, 0], [\"1.2D + 1.6R + 0.5W_dn\", 1.2, 0, 0, 0, 1.6, 0.5, 0, 0, 0], [\"1.2D + 1.0W_dn + f_1L + 0.5Lr\", 1.2, 1.0, 0.5, 0, 0, 1.0, 0, 0, 0 ],[\"1.2D + 1.0W_dn + f_1L + 0.5S\", 1.2, 1.0, 0, 0.5, 0, 1.0, 0, 0, 0 ],[\"1.2D + 1.0W_dn + f_1L + 0.5R\", 1.2, 1.0, 0, 0, 0.5, 1.0, 0, 0, 0 ],[\"1.2D + 1.0E_v + 1.0E_h + f_1L + 0.2S\", 1.2, 1.0, 0, 0.2, 0, 0, 0, 1.0, 1.0 ],[\"0.9D + 1.0W_up\", 0.9, 0, 0, 0, 0, 0, 1, 0, 0 ],[\"0.9D - 1.0E_v + 1.0E_h\", 0.9, 0, 0, 0, 0, 0, 0, -1.0, 1.0 ]], \"LCs_sserv\": [[\"L + Lr\", 0, 1, 1, 0, 0, 0, 0, 0, 0],[\"S\", 0, 0, 0, 1, 0, 0, 0, 0, 0], [\"0.42W_up\", 0, 0, 0, 0, 0, 0, 0.42, 0, 0],[\"0.42W_dn\", 0, 0, 0, 0, 0, 0.42, 0, 0, 0]], \"LCs_mserv\":[ [\"D + L + Lr\", 1, 1, 1, 0, 0, 0, 0, 0, 0] ], \"LCs_lserv\":[], \"LCFact_DB\":{L: [1, L(\"LLR\",1)], D:[1, 1.0], \"all_kcr\":[1, 1.0]}, \"LCFact_str\": {L: [0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0]}, \"LCFact_sserv\": {}, \"LCFact_lserv\": {}, zeroTol:1e-6, lengthUnit:\"ft\", forceUnit:\"kip\"}",
                "condition": "@default"
            }
        ],
        "solver": "beamGenericLCv2",
        "referenceId": "remote",
        "visibleIf": null,
        "enableTypes": true
    }
},

Step 4: The Analysis (The Output)

Finally, we need to display the results. The Solver calculated the physics for each individual load type; now we need a table that combines them. How this Table works: This table takes the raw data from the solver and applies the specific ASCE 7 load factors.
  • For LRFD: It will generate rows for combinations like 1.2D+1.6L1.2D + 1.6L or 1.2D+1.0W+0.5L1.2D + 1.0W + 0.5L.
  • For ASD: It will generate rows for combinations like D+LD + L or D+0.6WD + 0.6W.
It then scans the results and outputs the Factored Connection Shear (VV) and Factored Connection Moment (MM) for each combination, allowing you to see exactly which case governs the design.
1

Locate Insertion Point

Find the spot immediately after your Input Table.
2

Paste the Output Table Code

Copy the output_table.json code block and paste it there.
output_table.json
{
    "type": "sheetTemplateWidgets",
    "attributes": {
        "type": "table",
        "label": "Strength Load Combinations",
        "symbol": "LC_{str}",
        "description": "Relevant demands resulting from each LRFD load combination checked.",
        "references": null,
        "referencesJson": null,
        "authorNotes": null,
        "referenceImage": null,
        "visibleIf": null,
        "showInSummary": true,
        "showInSuperSummary": false,
        "apiOutput": null,
        "dataColumns": [
            {
                "type": "computed",
                "label": "Load Combination",
                "equation": [
                    {
                        "result": "vectorSubset(remote.LCTable.str.index, rowIndex()+1)",
                        "condition": "@default"
                    }
                ],
                "cellChecks": [],
                "shortLabel": "LC",
                "referenceId": "LC"
            },
            {
                "type": "computed",
                "label": "Factored Connection Shear Load",
                "symbol": "V",
                "units2": "kip",
                "equation": [
                    {
                        "result": "vectorSubset(remote.LCTable.str.Ry, rowIndex()+1)",
                        "condition": "@default"
                    }
                ],
                "unitsFps": "kip",
                "unitsMks": "kN",
                "referenceId": "V"
            },
            {
                "type": "computed",
                "label": "Factored Connection Moment",
                "symbol": "M",
                "units2": "kip*ft",
                "equation": [
                    {
                        "result": "vectorSubset(remote.LCTable.str.Rm, rowIndex()+1)",
                        "condition": "@default"
                    }
                ],
                "unitsFps": "kip*ft",
                "unitsMks": "kN*m",
                "referenceId": "M"
            }
        ],
        "defaultValue": [],
        "defaultValueMks": null,
        "defaultValueFps": null,
        "expand": false,
        "export": null,
        "hidden": null,
        "tableLength": "remote.LCTable.str.len",
        "checks": [],
        "referenceId": "LC_str_LRFD"
    }
}
Once these three parts are pasted into your JSON file, your calculator will be able to take user inputs, run them through the ASCE 7 load combinations, and display the governing factored loads!