Legacy JavaScript API (deprecated)
Warning
This is the legacy client-side JavaScript API of the pre-React MVC pipeline. New code must use the React hooks documented in React Hooks & Events. This page is preserved only as a migration reference for maintaining surviving legacy MVC components.
The legacy MVC pipeline exposed a global MIB.Template.Manager object
on window. Custom MVC components registered callbacks against its
lifecycle events. Inline <script> blocks were embedded via the
Razor @Html.DelayedScript helper. None of this is used by the
modern React shell.
A thin compatibility shim that still exposes MIB.Template.Manager
on window may ship for some deployments — do not write new code
against it. It will be removed in a future major version.
@Html.DelayedScript — inline <script> blocks in Razor views
Inline scripts inside a legacy component view must be wrapped in the
DelayedScript helper so they are moved to the end of the page,
after all component DOM nodes have rendered:
@using MibServer3.Model.Extensions
@Html.DelayedScript(
@<script type="text/javascript">
// Scripts go here
</script>
)
Without this helper, scripts run in source order — typically before their target DOM nodes exist — and break.
The helper buffers each component's script blocks during render and
flushes them into a single <script> block at the end of the body.
This is the only mechanism by which a legacy component contributes
JS to the page.
GetScripts() / GetStyles()
Legacy components also implement
IRenderableComponent.GetScripts() and GetStyles(), returning a
List<string> of URLs that the BFF injects into the page's
<head> / before </body>. These are global across the page,
not scoped to the component.
Modern replacement. Bundle the JS / CSS inside a federated React remote — see Shipping Custom JavaScript. Module Federation handles scoping and deduplication.
MIB.Template.Manager.RefreshComponentView — re-render
Refreshes a single component without a full-page reload:
MIB.Template.Manager.RefreshComponentView(
{ TemplateComponentKey: 'my_key', JsonData: {} },
function (data) { /* updated viewdata */ }
);
The data parameter must be a CollectDataResult:
function CollectDataResult() {
this.TemplateComponentKey = '';
this.JsonData = new Object();
}
The callback receives a data object containing the information returned from the server-side.
Modern replacement. Implement
IRefreshableComponentV2<TConfig, TViewData> on the C# side; the
React shell exposes a refresh() callback on the widget's props that
re-pulls the component's data:
const MyWidget = ({ refresh }: MibComponentProps<S, D>) => (
<button onClick={() => refresh?.()}>Refresh</button>
);
See Component Authoring — Refresh.
Persist workflow — OnCollectData / OnPersistDeliverResponses
The legacy save flow was a two-step round-trip:
MIB.Template.Manager.OnCollectData(callback, templateComponentKey);
MIB.Template.Manager.OnPersistDeliverResponses(callback, templateComponentKey);
OnCollectData is called when the user clicks Save, and must return
a CollectDataResult with the data to send to the server. During
this step all validation runs on the client; if a component detects
an invalid value it throws an exception, which stops the persist
process.
OnPersistDeliverResponses is called after the server-side save,
receiving a DeliverResponseResult with the data the C# side sent
via OnAfterSave plus a deliver callback:
function DeliverResponseResult() {
this.TemplateComponentKey = '';
this.JsonData = new Object();
this.Status = '';
this.ErrorMessage = '';
}
Status values:
var DeliverResponseStatus = {
"Success": 0,
"SuccessNoContent": 1,
"Error": 2,
"NoOperation": 3,
"ValidationException": 4
};
If a component threw PersistenceValidationException on the server,
its callback must invoke the deliver callback with a
DeliverResponseCollectResult:
function DeliverResponseCollectResult() {
this.TemplateComponentKey = '';
this.Operation = '';
this.Message = '';
}
var DeliverResponseOperation = {
None: 0,
ShowError: 1,
};
If the manager receives a result with ShowError, it shows a modal
popup with the error message. A typical legacy implementation:
MIB.Template.Manager.OnPersistDeliverResponses(
function (deliverResult, deliverCallback) {
if (deliverResult.Status == DeliverResponseStatus.ValidationException) {
var collectResult = new DeliverResponseCollectResult();
collectResult.TemplateComponentKey = 'my_key';
collectResult.Message = deliverResult.ErrorMessage;
collectResult.Operation = DeliverResponseOperation.ShowError;
deliverCallback(collectResult);
}
}, '<my_template_component_key>'
);
When a component on a page succeeds but another component on the
same page fails, each succeeding component receives a result with
NoOperation status.
Modern replacement. The React shell exposes
useContentEdition().onSave() from @agilecontent/mib-modules:
const { onSave } = useContentEdition();
useEffect(() => onSave(async () => {
await api.persistMyWidgetState(localState);
}), [localState]);
The shell awaits every registered onSave callback in parallel; any
thrown error / rejected promise aborts the save and surfaces an
error notification automatically. The DeliverResponseStatus enum
is not part of the React-era contract. See
React Hooks & Events — useContentEdition.
MIB.Template.Manager.OnConfirm — pre-save confirmation gate
Added in MIB v5.0.5 to allow components to insert asynchronous behaviour before save:
MIB.Template.Manager.OnConfirm(callback);
The callback receives a confirmCallback that must be invoked for
the save to proceed. Every registered OnConfirm callback must call
its confirmCallback; if any doesn't, the save stalls.
Example pattern — ask the user before continuing:
MIB.Template.Manager.OnConfirm(function (confirmCallback) {
if (MyLib.MyClass.ShouldAskForConfirmation()) {
MIB.Alerts.Confirmation("Do you really want to continue?", confirmCallback);
} else {
confirmCallback();
}
});
Modern replacement. useContentEdition().onConfirm() returns a
Promise<boolean>. If any registered callback resolves to false,
the save is aborted:
const { onConfirm } = useContentEdition();
useEffect(() => onConfirm(async () => {
if (await needsApproval()) return confirm('Submit for approval?');
return true;
}), []);
MIB.Selection.Open — aside selector
Opens the legacy aside selector:
MIB.Selection.Open(callback, mediaType, options);
| Parameter | Meaning |
|---|---|
callback |
Receives an array of { id, name } objects when the operator confirms a selection |
mediaType |
The mediatype to list |
options |
Reserved (single/multi mode etc. — implementation varies) |
The callback receives:
[
{ id: 1, name: "First Item" },
{ id: 2, name: "Second Item" }
]
Pre-open filters — MIB.Selection.OnBeforeOpen
MIB.Selection.OnBeforeOpen(function (mediaType, fieldCollectCallback) {
var fields = new Array();
fields.push({ Field: 'NAME', Operator: 'STARTSWITH', Value: 'MIB' });
fields.push({ Field: 'SOURCE[ID]', Operator: 'EQUAL',
Value: '[mib_form.SOURCE]' });
fieldCollectCallback(fields);
});
SelectionFilter shape:
function SelectionFilter() {
this.Field = '';
this.Operator = '';
this.Value = '';
}
Supported operators:
EQUAL, NOTEQUAL,
GREATERTHAN, GREATEROREQUAL,
LESSTHAN, LESSOREQUAL,
CONTAINS, STARTSWITH, ENDSWITH,
IN
Value can be a static value or a reference to a field in a default
MIB FormComponent via [<templateComponentKey>.<field>].
Modern replacement. useSelection().open(...) returns a
Promise<Selected[]>; pre-open filters are passed as
initialFilters in the same call:
const { open } = useSelection();
const picked = await open({
mediaType: 'AUTHORS',
multi: false,
initialFilters: [{ field: 'ACTIVE', operator: 'EQUAL', value: true }],
});
See React Hooks & Events — useSelection.
Form-field change — MIB.Component.Form.OnChange
Subscribe to changes on any form field:
MIB.Component.Form.OnChange(function (changeResult) {
console.log(changeResult);
});
// changeResult shape:
function ChangeResult() {
this.TemplateComponentKey = "";
this.MediaType = "";
this.Ids = "";
this.Field = "";
this.Value = "";
}
Modern replacement. The stock React form component dispatches
changes via its own callback prop / context (useFormContext from
the form widget's package). For cross-widget reactions, prefer the
shared-hook pattern documented under
React Hooks & Events — Cross-widget communication.
MIB.Alerts.* — modal alerts
MIB.Alerts.Confirmation('Continue?', callback);
MIB.Alerts.Error('Something went wrong');
Modern replacement. useNotification():
const { error, modal } = useNotification();
modal({ title: 'Continue?', onOk: () => proceed() });
error('Something went wrong');
MIB.User.Preferences.Save — user preferences
The legacy global for persisting user preferences (interface language, page-state etc.):
var preferenceList = [];
var preference = new PreferenceData();
preference.key = "interface_language";
preference.value = "pt-br";
preferenceList[0] = preference;
MIB.User.Preferences.Save(preferenceList, function () { });
Modern replacement. Send a POST /api/preferences with the same
key/value semantics. The React shell does this internally for the
user's language preference; for ad-hoc programmatic preference
changes, call the endpoint directly with an authenticated session
cookie.
MIB.Template.Manager.GetHandlerUrl — URL of a /Handler/ endpoint
Builds the URL of an IHandlerComponent endpoint:
var url = MIB.Template.Manager.GetHandlerUrl(templateComponentKey);
The returned URL is /Handler/<currentPageKey>/<templateComponentKey>.
Modern replacement. Register a standard ASP.NET Core controller
or minimal-API endpoint in the customisation. The React shell calls
it like any other HTTP endpoint via the @agilecontent/mib-api-connector
package or fetch directly.
Compatibility shim
A thin shim that exposes the MIB.Template.Manager,
MIB.Selection.*, MIB.Alerts.*, and MIB.Component.Form.*
globals on window may still ship for some deployments to support
straggler legacy components. Do not write new code against it.
The shim is best-effort and will be removed in a future major
version.
See also
- React Hooks & Events — the modern React-era API surface
- Legacy Component Model — the C# interfaces that pair with this JS API
- Legacy MVC — IIS Installation — the runtime environment these APIs target
- Shipping Custom JavaScript — the
modern replacement for
@Html.DelayedScriptandGetScripts()/GetStyles()