CASE: use of required in fori

For this case, we want to make some inputs in our fori required.

Let’s say we want to build an overview of categorized assets and present an opening and closing balance.
We have a fori where users can enter a description, category, opening balance, additions, adjustments and transfers.
For the entry to be useful we want to at least get a description, category, and opening balance.
For that purpose we make those fields required inputs.

{% comment %}Fori with inputs to populate the summary{% endcomment %}
{% stripnewlines %}
<table class="usr-width-100">
  <thead>
    <tr>
      <th class="usr-line-bottom"><b>Description</b></th>
      <th class="usr-line-bottom usr-width-15 usr-align-center"><b>Category</b></th>
      <th class="usr-line-bottom usr-width-15 usr-align-center"><b>Opening balance</b></th>
      <th class="usr-line-bottom usr-width-15 usr-align-center"><b>Additions</b></th>
      <th class="usr-line-bottom usr-width-15 usr-align-center"><b>Ajustments</b></th>
      <th class="usr-line-bottom usr-width-15 usr-align-center"><b>Transfers</b></th>
      <th class="usr-line-bottom usr-width-15 usr-align-center"><b>Closing balance</b></th>
    </tr>
  </thead>
  <tbody>
    {% fori asset in custom.asset_overview %}
      {% comment %}Reset var{% endcomment %}
      {% assign closing_balance = "" %}
      <tr>
        <td>{% input asset.description placeholder:"Description" required:true %}</td>
        <td>{% input asset.category as:select options:"Land|Building|Vehicle" option_values:"land|building|vehicle" required:true %}</td>
        <td class="usr-align-right">{% input asset.opening_balance as:currency placeholder:"Opening balance" required:true %}</td>
        <td class="usr-align-right">{% input asset.addition as:currency placeholder:"Addition" %}</td>
        <td class="usr-align-right">{% input asset.adjustment as:currency placeholder:"Adjustment" %}</td>
        <td class="usr-align-right">{% input asset.transfer as:currency placeholder:"Tranfser"%}</td>
        {% comment %}Calculate closing{% endcomment %}
        {% assign closing_balance = asset.opening_balance+asset.addition+asset.adjustment+asset.transfer %}
        <td class="usr-align-right">{{ closing_balance | currency }}</td>
      </tr>
    {% endfori %}
  </tbody>
</table>
{% endstripnewlines %}

You’ll see that as soon as you enter data in a row and hit enter, the required attribute kicks in.

:brain: Good to know:
Fori-statements disregard the required attribute of inputs that are in the last iteration.
Why? :thinking:
Because as long as a required input remains blank, a template cannot reconcile. :small_red_triangle:
However, the last iteration in a fori is always just giving you blank inputs to allow you to keep adding data.
To deal with this contradiction, the required attribute in the last iteration will always be ignored.

Point of attention :writing_hand: :bulb:

Note that any other inputs inside a fori, that aren’t part of its custom collection, will be treated as if they are in the last iteration of that fori. This means that if you add a required attribute to such an input, it will never trigger. Whether you’re actually in the last iteration or not!

Example: in the same example as above I added an additional required input, which isn’t part of the custom collection of the fori: custom.asset_overview

    {% fori asset in custom.asset_overview %}
      {% comment %}Reset var{% endcomment %}
      {% assign closing_balance = "" %}
      <tr>
        <td>{% input asset.description placeholder:"Description" required:true %}</td>
        <td>{% input asset.category as:select options:"Land|Building|Vehicle" option_values:"land|building|vehicle" required:true %}</td>
        <td class="usr-align-right">{% input asset.opening_balance as:currency placeholder:"Opening balance" required:true %}</td>
        <td class="usr-align-right">{% input asset.addition as:currency placeholder:"Addition" %}</td>
        <td class="usr-align-right">{% input asset.adjustment as:currency placeholder:"Adjustment" %}</td>
        <td class="usr-align-right">{% input asset.transfer as:currency placeholder:"Tranfser"%}</td>
        {% comment %}Calculate closing{% endcomment %}
        {% assign closing_balance = asset.opening_balance+asset.addition+asset.adjustment+asset.transfer %}
        <td class="usr-align-right">{{ closing_balance | currency }}</td>
        
        {% comment %}Input not tied to the fori{% endcomment %}
        <td>{% input custom.other.info placeholder:"Other info" required:true %}</td>
        
      </tr>
    {% endfori %}

You can see that the the “other info” input is not required in any of the iterations.
For that reason we do not recommend you add inputs in fori’s that aren’t part of that fori collection.