Since it's unfair to users not being able to save a partially completed form, what you can do is to have a list of warning messages at the top of the form for uncompleted fields. That way the user can save and keep working on reducing the error messages until the warning messages are cleared.
At the end of this post i will give an example of a crazy long on.
Then what you can have as a status field which has among other choices say the value is submitted. And then you have a form rule to prevent the record from being saved with a status of Submitted if there are error messages..
So the idea would be for the user to work away at the form until there are no more error messages.
I'm not sure if you have been brave yet to try the new forms but they do have a presentation setting on the form which is stepwise like you are looking for. There are still some bugs to be worked out a new form so it's a decision you have to make whether you want to try using the new forms to get the look and feel of the 1234 stepwise progression through the tabs. It is likely that the most serious of bugs will be fixed on the next release but that is just my guess. Some of what we users consider bugs are in fact features that are just not available on the new form.
Here is an example of a crazy long warning message from from one of my apps.
var text AllClaimsExceptions =
List("<br>",
//If([Short Form Claim under $250 & no GR?]="", "missing Short Form only Yes/ no"),
If(Trim([Invoice # (with the problem)])="","Missing Invoice #"),
If(Nz([Product Selection])=0,"Missing Product"),
If(Trim([Item #])="", "Missing Item #"),
If(Nz([Defect #])=0,"Missing Defect"),
If([$ Claim Dealer Total]=0,"Missing Claim $ Requested"),
If([$ Claim Dealer Total]>250 and [Short Form Claim under $250 & no GR]="Yes",
"Short form under $250 indicated, but you are requesting a dollar amount more than $250"),
If(Trim([Territory Rep Code])<>"" and Trim([National Account Rep Code])<>"",
"Please only select either the Territory Rep code, or the national Account Rep code, not both." &
"\n" & "To deselect a rep, click on the dashed lines ------- in the drop down list."
//If([Customer has Deducted]=""
// and (IsNull([Date Created]) or ToDate([Date Created])>=Date(2018,6,16))
//, "Please say if you know if the Customer has already Deducted")
)
);
var text LongFormOnlyExceptions =
List("\n",
If([Do you need a GR?]="","Missing \"Do you need a GR?\""),
If(Nz([Problem Area])=0,"Missing Problem Area"),
If([Problem Area / Total Order UM]="","Missing Problem Area U/M"),
If([Product Category Selection (Cost Centre)]="IHC"
and IsNull([xDate Installed])
and [Not Installed] = false,
"Amorim (Cork) Supplier Requires Date Installed"),
If(
Nz([GR Qty Expected to be returned])=0
and [Select Qty to be Returned]<>"Don't know"
and [Do you need a GR?]="Yes",
"Missing GR qty expected to be returned"),
If(ToDate([Date Created]) > Date(2019,6,18)
and IsNull([xDate Reported])
and [Not Installed] = false,
"All Suppliers are now asking for the Date Reported, unless the Product was Not Installed"
& "\n Please use the Rep form to locate this field in the \"Dates\" section."
),
If([Not Installed]=false
and IsNull([xDate Installed]),"Either needs the date Installed or else say Not Installed")
)
;
var text Exceptions =
List("<br>",
$AllClaimsExceptions,
If([Short Form Claim under $250 & no GR]<>"Yes", $LongFormOnlyExceptions ));
//if just an inspection, then no Exception details
If(Nz([Acct #])=0 and [Record ID#]>0,"",
If(Trim($Exceptions) <>"",
"<font color=red>The submit button will appear in View mode when the Exceptions are cleared<font color=blue><br>" & $Exceptions ))
------------------------------
Mark Shnier (Your Quickbase Coach)
mark.shnier@gmail.com
------------------------------