Using Fieldsets for Repeating Sets of Fields

Fieldsets are an advanced technique for use with custom item types. They allow you to define a group of fields, and to then repeat that group of fields as many times as you need for each item. The number of instances of a fieldset in a given record is not fixed, but can vary from one record to another.

Fieldsets are similar, in some ways, to related items, but they differ in that they are not used independently of a parent item and can be added as part of the same form when creating items.

Why Fieldsets are Useful

An example helps to visualize this. Suppose you have a database of school classes, and for each class there may be one or more sessions.

You could define a session fieldset with the following fields:

  • Session Name
  • Time
  • Location

Then, in the custom item type for a class, you would add the session fieldset as one of the custom fields. Then, when creating a new class (via the automatically provided admin form for classes), you can add any number of sessions.

If you knew that each class had only one session, then you would just include the session name, time, and location fields directly as part of the class item type definition. But by making them a fieldset, each class can have as many sessions as it needs.

Defining a Fieldset

To define a fieldset, choose Database > Item Types, click the Add Custom Item Type button, and check the Fieldset box in the form that appears. Fill in the name and label fields; the others don't matter.

Then create fields for each of the fields you want as part of the fieldset, and save the fieldset definition.

Note: taxonomies, related items, and related assets don't work as field types within a fieldset.

Including a Fieldset in a Custom Item Type

Now edit or create the custom item type that includes the fieldset, and make the connection to the fieldset as follows:

  • Add a custom field, and choose Fieldset as the field type.
  • Enter the exact name of the fieldset as the fieldname, and also enter it in the Type Options field. (In a future release, we'll allow you to use any fieldname, and then the Type Options field will make the connection.)

Entering Fieldset Information

Once you've created your custom item type definition, choose the item type from the Content tab and click Add button to create a new item.

You'll then see an outlined area for the fieldset on the new/edit item form, with an "Add Another" button. Click this button to to add a set of fields. Click it again to add another.

To delete a set, click the delete icon to its right.

Accessing Fieldset Contents with WebvantaScript

To access the fieldset contents in a page, you need to use an iterator, since there can be any number of instances of the fieldset. Here's an example that assumes you are using this on an item page, for a fieldset named "session", which has fields "session_name", "time", and "location":

<w:kb:item> <h1>Class name: <w:name /></h1> <table> <w:for_each in="session"> <tr> <td>Session name: <w:get name="in.session_name" /></td> <td>Time: <w:get name="in.time" /></td> <td>Location: <w:get name="in.location" /></td> </tr> </w:for_each> </table> </w:kb:item>

The <w:kb:item> tag sets the context, selecting the item according the ID in the page's URL. (You could set this context in many other ways, such as an iterator that displays a series of items.)

The name of the class is displayed as the headline. Then the sessions are displayed in a table, with one row for each entry in the fieldset.

Note the use of the keyword "in". The w:for_each tag specifies the name of the fieldset. Then the code inside the block that this begins is repeated for each entry in the fieldset. To access the values, you need to use the <w:get name="in.fieldname" /> syntax as shown.

Displaying or Testing the Number of Items

You can get the number of items in the fieldset as follows:

<w:get name="fieldsetname.count" />

You can also use this value in a condition, so you can test to see how many items there are. This is especially useful when you want to inhibit the generation of some markup if there are no items in the fieldset.

For example, here is an enhancement of the example above that shows how many sessions there are, and doesn't generate the sessions table at all if there are no sessions:

<w:kb:item> <h1><w:name /></h1> <p>Number of sessions: <w:get name="session.count" /></p> <w:if condition="session.count > 0"> <table> <w:for_each in="session"> <tr> <td>Session name: <w:get name="in.session_name" /></td> <td>Time: <w:get name="in.time" /></td> <td>Location: <w:get name="in.location" /></td> </tr> </w:for_each> </table> </w:if> </w:kb:item>