Table of Contents

Related Form Component

Lets the operator edit mediatype records that are related to the page's main mediatype — displayed as one form per related record rather than as a list. Use it when each related record has many fields the operator needs to see at once (audio tracks with codec / bitrate / language / file ref; pricing offers with start / end / amount / currency). Use the Simple Related List when many records with few columns each fits the UX better, or the Related Auto Complete when only the related record's identity matters.

Example Related Form section on a user edit page — one related record with many fields, rendered as a single row

The example above is from a user edit page where a Related Form component holds the user's "video service info" record — a single related record with many fields (Geographic Area, Blackout Area, Time Zone, DVR, SD Media Streams, HD Media Streams, DVBT Tuners, Service Group, …). With CREATE_ONLY_ONE_RELATED_REGISTRY the component enforces a single child record and hides the Add Related / Delete affordances.

Related Form is distinct from Related List. They share neither the React widget nor the schema shape on the wire. This doc covers Related Form only — see Related List for that component and for the Header Action / Item Action extension points (those features live on the Related List widget, not here).

Related docs.
Form Component — the parent on the same page; shares the field-rendering pipeline.
Simple Related List — list-style alternative for the same relationship.
Related Auto Complete — minimal alternative when only the related record's identity matters.
System Overview — RenderV2 — the request that returns {schema, data} to the React shell.

The four components below are interchangeable from the data-model side — they all describe the same relationship between the page's mediatype and another. Pick by the UX you want:

Component When to use
Simple Related List Many records, few columns. Table view.
Ordered Related List Same as above, with drag-and-drop reordering. ≤15 rows.
Related Form (this doc) Few records, many fields each. Form-per-record view.
Related Auto Complete Only the related record's identity matters. Autocomplete-style picker.

Backend features (C# — MibServer3)

The C# class is MediaiBox.Cms.FrontEnd.Server.Component.RelatedFormComponent, with its typed configuration at RelatedFormComponentConfiguration and its view data at MediaiBox.Cms.FrontEnd.Model.UI.Form.RelatedFormViewData. The component:

  • Loads the related records into a List<RelatedChildFormViewData> at render time.
  • Honours the parent form's permissions (you only see records the user has read on the related mediatype).
  • Drives the same field-render pipeline as the main Form Component — every admField variant supported by Form is supported here.

Bulk modes — PersistenceBulkMode

When the parent page is in bulk-edit (the user arrived from a list with multiple ids), Related Form supports four explicit operation modes via the PersistenceBulkMode enum (MediaiBox.Cms.FrontEnd.Model.Dao.Persistence.PersistenceBulkMode):

Mode Effect on each selected parent record
None Default — apply field changes as edited.
Add Append the related record to each parent's relation set.
Remove Remove the related record from each parent's relation set.
Clear Clear all related records on each parent.
Replace Replace the existing relation set with the edited one.

The mode is selected at save time via a JSON option sent by the client: data.Options = { type: "bulk", mode: "..." }. If the operator triggers a bulk save but the component has AllowBulkEdit = false, the C# layer throws BulkEditDeniedException and the save is rejected with a clear error.

This is one of the highest-value backend features for the Related Form — it lets editors mutate hundreds of parents in a single save without the client having to issue N independent updates.

Remove-button behaviour — RemoveButtonBehaviorType

What clicking the per-record trash button actually does depends on the relation type and the RemoveButtonBehaviorType set on the view data:

Behaviour Meaning
SetNull (default for nullable foreign-key relations) Set the foreign key to null on the parent; do not delete the child record itself.
DontAllowRemoval The trash button is hidden. Removal isn't possible.
DeleteChildObject Delete the related record from its mediatype entirely.

SetNull is the safe default for relations that point at shared catalog records (e.g. a Distributor — un-relating a movie from a distributor must not delete the distributor). DeleteChildObject is for owned-child relationships only (e.g. audio tracks that uniquely belong to one movie).

When the parent record is cloned, Related Form's children are copied according to RelatedCopyType:

Value Effect
Undefined Inherit the platform default.
DoNotCopy Skip — the clone has no related records.
ShallowCopy Copy the links — both parents share the same related records.
DeepCopy Duplicate each related record and link the new copies to the clone.

AllowAddNew interacts with this — see the note on ALLOW_ADD_NEW below.

Implements

The C# class implements the following framework interfaces:

public class RelatedFormComponent :
    ICloneableComponent<RelatedFormComponentConfiguration, RelatedFormViewData>,
    IRenderableComponent <RelatedFormComponentConfiguration, RelatedFormViewData>,
    IPersistableComponent<RelatedFormComponentConfiguration>,
    IRefreshableComponent<RelatedFormComponentConfiguration, RelatedFormViewData>,
    ISecondaryRequestComponent

The set of interfaces tells you the supported operations:

  • Renderable — emits view data on read.
  • Persistable — handles save / delete on its own (including the bulk modes above).
  • Refreshable — supports the post-save refresh roundtrip triggered by sibling components changing state.
  • Cloneable — participates in copy-with-related when the parent is cloned (see RelatedCopyType).
  • SecondaryRequest — can serve its own AJAX requests outside the normal render flow (used by the legacy MVC pipeline for lazy-loading child forms).

Frontend support (React shell, MibFrontEnd)

Current status: the React shell's core component dispatch (packages/core-components/src/components/index.ts) maps the component type relatedform to null — Related Form is not implemented as a built-in React widget. This means pages that include a Related Form component currently fall into one of these buckets:

  1. Legacy MVC rendering via the /Display/<pageKey> route — the C# component renders its own Razor view and the page works as it has since pre-React times. Most surviving Related Form usages are here.
  2. A customer-supplied federated remote that registers a relatedform React widget — same plug-in pattern any custom component uses (see Component Creation). The customer remote consumes the schema the C# component emits and renders it however the customer chooses.

If you are starting a new component today that needs form-per-record UX, you have two ergonomic options:

  • Use the Related Form C# component on a legacy MVC page (~/Display/<pageKey>) — works out of the box, no React work.
  • Use the Simple Related List — list-style but fully supported in the React shell; the operator can click into each row to edit a single record at a time. For cases where the form would have fit in a single horizontal row, this is usually a clean substitute.

If you specifically need a Related-Form React shell experience, you'll need to ship a custom relatedform widget through your federated remote. The widget consumes the same { schema, data } shape the C# RelatedFormViewData emits, so the contract is stable; only the rendering is your responsibility.

Header Action / Item Action

The shell's Header Action and Item Action decorator pattern (see Simple Related List — Header Actions and Item Actions) is scoped to the 'related-list' decorator namespace and is consumed by the core React RelatedList widget. It does not apply to Related Form out of the box because Related Form has no core React widget.

A custom relatedform widget shipped in a federated remote can choose to:

  1. Define its own decorator namespace (e.g. 'related-form') — the cleanest approach if the actions are conceptually form-specific.
  2. Re-use the 'related-list' decorator namespace — if the widget's UX is close enough to the list widget that actions should share the same registration. The Related List section linked above documents the exact contract (props, visibility gating via schema.configuration[key] for header and data.items[i].permissions[key] for item).

Either approach is implementer-defined; the framework imposes no constraint here today.

Configuration Keys (C# side)

These are stored in MIB3UX_PAGE_COMPONENT_CONFIGURATIONS and projected onto RelatedFormComponentConfiguration at render time.

TITLE

The title rendered in the component header.

ALLOW_ADD_EXISTING

Boolean. True (default): the Add Existing action is enabled. False: hidden.

ALLOW_ADD_NEW

Boolean. True: the Add New action is enabled. False: hidden.

Note

Pairs with RelatedCopyType for the copy-with-relateds flow:

  • DoNotCopy / ShallowCopy — if AllowAddNew=true and the user lacks write permission on the MediaType, related data is not copied.
  • DeepCopy — if AllowAddNew=false or the user lacks write permission, related data is not copied.

ALLOW_BULK_EDIT

Boolean. True (default): the page can be bulk-edited (when reached via multi-select on a list). False: bulk-edit on this component specifically is disabled. When false and the parent is in bulk-edit, save throws BulkEditDeniedException.

ALLOW_EDIT

Boolean. True (default): per-record fields are editable. False: the component is read-only regardless of user permissions.

ALLOW_REMOVE

Boolean. True (default): the per-record trash button is visible. Its actual behaviour depends on RemoveButtonBehaviorType. False: the trash button is hidden regardless of permissions.

ALLOW_CLEAR_ALL

Boolean. True: a "Clear All" button appears in the component header, removing all related records at once (subject to the same RemoveButtonBehavior). False (default): the button is hidden.

BATCH_REFERENCE_IDENTIFIER

Sets the batch reference to something other than the component's default TemplateComponentKey. Used when several components share a save batch.

Boolean. True: the component enforces a single related record — Add New, Add Existing, and Delete are hidden once one record is present. False (default): normal multi-record behaviour.

Use for one-to-one relationships modeled as a related table (e.g. a movie's single preview clip).

DENY_ON_READONLY

Boolean. True: deny save if the user lacks permission on any related component or field on the page. False (default): allow save even when some related components are read-only for this user.

EXCLUDE_FIELDS

A comma-separated list of admField column names to exclude from the rendered fields.

CONFIGURATION_KEY:   EXCLUDEFIELDS
CONFIGURATION_VALUE: name,timezone,genres

INCLUDE_FIELDS

A comma-separated list of admField column names. When set, restricts the rendered fields to this list.

CONFIGURATION_KEY:   INCLUDE_FIELDS
CONFIGURATION_VALUE: name,timezone,genres

HIDE_BULK_EDIT

Boolean. True: the bulk-edit affordance is disabled even when the parent page allows it. False (default): enabled.

IS_CHILD_REQUIRED

Boolean. True: at least one related record must exist for the parent save to succeed. False (default): no requirement.

MEDIATYPE

The mediatype loaded in the component. Required.

PARENT_BATCH_REFERENCE_IDENTIFIER

Override for the parent batch reference (defaults to the parent component's TemplateComponentKey).

PARENT_MEDIATYPE

Links the parent page's mediatype to the related mediatype rendered here:

CONFIGURATION_KEY:   PARENT_MEDIA_TYPE
CONFIGURATION_VALUE: ARTICLES

READONLY

Boolean. True: forces the component read-only regardless of permissions. False (default): honour user permissions.

READONLY_FIELDS

Comma-separated list of fields rendered as read-only regardless of permissions.

ASIDE_FIELDS / ASIDE_FILTERS

Control the columns and filters shown in the Add Existing side panel. Same shape as on the Simple Related List — see that doc for the value syntax (including dynamic [templateComponentKey.field] references).

REDIRECT_TO_EDIT_PAGE_BY_FIELD

Dictionary<string, Uri>. Click on a value of the named field in the rendered form navigates to the edit page of the related mediatype:

CONFIGURATION_KEY:   REDIRECT_TO_EDIT_PAGE_BY_FIELD[ID]
CONFIGURATION_VALUE: react_audio_tracks_edit

Source reference

React type-key (effective) relatedList — set via COMPONENT_VIEW_TYPE. The raw class name resolves to relatedform, which is not directly mapped in the React shell's registry today
BFF assembly MibServer3.Web
BFF class MibServer3.Web.Component.RelatedFormComponent
MIB3UX_COMPONENTS.COMPONENT_KEY mib_default_relatedformcomponent
React widget source packages/core-components/src/components/related-list/RelatedList.tsx — the form-per-record variant is driven by schema flags (Aside, RowExpansion); the React side does not have a separate relatedform widget
Schema / data contract Default List Schema plus per-row form schema; see 6.0/React Components

Custom backend, core React. Emit the Default List shape with the form-style flags set in the schema's configuration, and set COMPONENT_VIEW_TYPE = 'relatedList'. The single RelatedList.tsx widget covers all four related-list variants — see Simple Related List source reference.

See also