Core Concepts

Modal Restart Guide

Use sp_api_modal_restart to redraw a dialog, move a wizard to its next step, or hand over to another action.

A dialog normally re-runs because the user clicked something. sp_api_modal_restart lets your script trigger that re-run — optionally with new values, and optionally as a different action.

Signature

EXEC sp_api_modal_restart
     @action_name          = N'other_action'  -- optional: start this action instead of the current one
    ,@values               = @Json            -- optional: a JSON object of values to start with
    ,@modal_clear          = 1                -- default 1: clear the current dialog first
    ,@no_raiserror_success = 0                -- default 0: see "Inside TRY...CATCH" below
    ,@refresh_all          = 0;               -- default 0: 1 also refreshes the lists and forms underneath

All parameters are optional. With none, the current action simply starts again with a clean dialog.

Restart ends the current run

sp_api_modal_restart tells the framework that this run is finished: internally it raises a special "success" signal, which the framework treats as "start the next run now". Always follow it with RETURN, so that nothing else in the current run executes after the hand-over.

Starting again with values

@values is a JSON object whose keys are control names — the same names you pass to @name — and the restarted script reads them back with sp_api_modal_get_value, exactly as if the user had typed them. Build the JSON with FOR JSON PATH, WITHOUT_ARRAY_WRAPPER, which produces a single object rather than an array:

DECLARE @Step       INT;
DECLARE @Name       NVARCHAR(MAX);
DECLARE @NextButton NVARCHAR(MAX);
DECLARE @Json       NVARCHAR(MAX);

EXEC sp_api_modal_get_value @name = N'@Step',       @value = @Step OUT;
EXEC sp_api_modal_get_value @name = N'@Name',       @value = @Name OUT;
EXEC sp_api_modal_get_value @name = N'@NextButton', @value = @NextButton OUT;

IF @Step IS NULL SET @Step = 1;

IF @Step = 1
BEGIN
    EXEC sp_api_modal_text   @text = N'Step 1 of 2 — your name', @class = N'h4';
    EXEC sp_api_modal_input  @name = N'@Name', @value = @Name OUT;
    EXEC sp_api_modal_button @name = N'@NextButton', @value = N'Next',
                             @valueout = @NextButton OUT, @class = N'btn-primary';
    IF @NextButton IS NULL RETURN;

    SET @Json = (SELECT [@Step] = 2, [@Name] = @Name FOR JSON PATH, WITHOUT_ARRAY_WRAPPER);
    EXEC sp_api_modal_restart @values = @Json;
    RETURN;
END

-- Step 2 is drawn on the restarted run, with @Name already filled in
EXEC sp_api_modal_text @text = N'Step 2 of 2', @class = N'h4';

Why restart instead of just drawing step 2 straight away? Because the Next button is still "clicked" in the current run. Restarting gives step 2 a clean slate: no stale button values, no controls from step 1 left on screen, and only the values you chose to carry forward.

Handing over to another action

Pass @action_name and the restart starts that action instead, with your @values as its starting state. That is how one button can open a search, let the user pick a record, and pass the choice to a separate edit dialog. The details are in Parameter Passing Between Actions.

Inside TRY...CATCH

Because the restart works by raising a signal, a surrounding CATCH block will catch it — and a ROLLBACK there undoes your work. If you call sp_api_modal_restart inside TRY, pass @no_raiserror_success = 1 and RETURN yourself straight after:

BEGIN TRY
    -- ... save something ...
    EXEC sp_api_modal_restart @values = @Json, @no_raiserror_success = 1;
    RETURN;
END TRY
BEGIN CATCH
    THROW;
END CATCH

Refreshing what is underneath

A dialog usually sits on top of a list or form. After saving data that the list shows, pass @refresh_all = 1 so the underlying screen reloads too. It is slower, so leave it at 0 when nothing underneath has changed.