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.