NetLife Guru

Open source Go packages for fast, maintainable web systems. Built with a documentation-first approach.

Product
OverviewGolang packagesNews
Documentation
DocumentationGo LoggerGo RouterGo DB Form
Company
OverviewContactNewsGitHub
Community / Support
Supportinfo@netlife.guru
© 2026 NetLife Guru. All rights reserved.
GitHubinfo@netlife.guru
NetLife GuruNetLife GuruNetLife Guru
NetLife GuruNetLife GuruNetLife Guru
OverviewDocumentationNewsSupportContact

Golang packages

About
Conditional ValidationConditional RulesConditional When
Form ValidatorConditional Validation

Conditional When

Learn how to use conditional.When in NLG Form to run validation rules only when custom runtime predicates match.

conditional.When is the low-level primitive for conditional validation.

It allows one or more validation rules to run only when a custom predicate returns true.

Use When when predefined conditional helpers are not expressive enough.

TL;DR

HelperDescription
conditional.When(cond, rules...)Runs nested rules only when cond returns true

Basic Usage

conditional.When(
	func(r *Request) bool {
		return r.AccountType == "business"
	},
	rules.Required(Form.CompanyName),
)

If the condition is false, validation is skipped.

If the condition is true, all nested rules are executed.

Common Use Cases

  • business account validation
  • password change flows
  • billing sections
  • role-based validation
  • feature-specific fields
  • multi-step forms
  • PATCH APIs
  • advanced business rules

Complete Example

schema.go

package main

import (
	"github.com/netlifeguru/form"
	"github.com/netlifeguru/form/conditional"
	"github.com/netlifeguru/form/rules"
)

const (
	CodeCompanyRequired = form.Code("company_required")
	CodePasswordMinLen  = form.Code("password_min_len")
)

type ConditionalWhenRequest struct {
	AccountType     string `json:"account_type"`
	CompanyName    string `json:"company_name"`
	ChangePassword bool   `json:"change_password"`
	NewPassword     string `json:"new_password"`
}

func ConditionalWhenSchema() form.Schema[ConditionalWhenRequest] {
	ConditionalWhenForm := struct {
		AccountType     form.StringField[ConditionalWhenRequest]
		CompanyName    form.StringField[ConditionalWhenRequest]
		ChangePassword form.BoolField[ConditionalWhenRequest]
		NewPassword    form.StringField[ConditionalWhenRequest]
	}{
		AccountType: form.Str[ConditionalWhenRequest]("account_type", func(r *ConditionalWhenRequest) string {
			return r.AccountType
		}),
		CompanyName: form.Str[ConditionalWhenRequest]("company_name", func(r *ConditionalWhenRequest) string {
			return r.CompanyName
		}),
		ChangePassword: form.Bool[ConditionalWhenRequest]("change_password", func(r *ConditionalWhenRequest) bool {
			return r.ChangePassword
		}),
		NewPassword: form.Str[ConditionalWhenRequest]("new_password", func(r *ConditionalWhenRequest) string {
			return r.NewPassword
		}),
	}

	return form.Schema[ConditionalWhenRequest]{
		conditional.When(
			func(r *ConditionalWhenRequest) bool {
				return r.AccountType == "business"
			},
			rules.RequiredWithCode(ConditionalWhenForm.CompanyName, CodeCompanyRequired),
		),

		conditional.When(
			func(r *ConditionalWhenRequest) bool {
				return r.ChangePassword
			},
			rules.Required(ConditionalWhenForm.NewPassword),
			rules.MinLenWithCode(ConditionalWhenForm.NewPassword, 8, CodePasswordMinLen),
		),
	}
}

main.go

package main

import (
	"encoding/json"
	"fmt"
	"log/slog"
	"net/http"
	"os"

	"github.com/netlifeguru/form"
	"github.com/netlifeguru/form/httpform"
	"github.com/netlifeguru/router"
)

func main() {
	r := router.New()

	r.HandleFunc("/conditional-when", "POST", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		var in ConditionalWhenRequest

		if !httpform.BindAndValidate(w, req, &in, ConditionalWhenSchema(), 1<<20) {
			fmt.Println("conditional when validation failed")
			return
		}

		fmt.Println("conditional when validation passed:", in)

		w.Header().Set("Content-Type", "application/json")

		_ = json.NewEncoder(w).Encode(map[string]any{
			"message": "conditional when validation passed",
			"data":    in,
		})
	})

	validPayload := map[string]any{
		"account_type":    "business",
		"company_name":    "Acme s.r.o.",
		"change_password": true,
		"new_password":    "secret123",
	}

	invalidPayload := map[string]any{
		"account_type":    "business",
		"company_name":    "",
		"change_password": true,
		"new_password":    "short",
	}

	skippedPayload := map[string]any{
		"account_type":    "personal",
		"company_name":    "",
		"change_password": false,
		"new_password":    "",
	}

	fmt.Println("\n--- Valid request ---")
	form.SendTestPost(":8080/conditional-when", validPayload)

	fmt.Println("\n--- Invalid request ---")
	form.SendTestPost(":8080/conditional-when", invalidPayload)

	fmt.Println("\n--- Skipped conditional validation request ---")
	form.SendTestPost(":8080/conditional-when", skippedPayload)

	if err := r.ListenAndServe(8080); err != nil {
		slog.Error("failed to start server", "error", err)
		os.Exit(1)
	}
}

Validation Flow

condition is false
    ↓
nested validation skipped
condition is true
    ↓
nested rules executed

Notes

  • When is the most flexible conditional validation primitive.
  • Conditions receive the full request structure.
  • A single When block can contain multiple nested rules.
  • Use When for custom business logic.
  • Use convenience helpers such as RequiredIfStr for common conditional cases.
  • Conditional validation remains explicit and transport-independent.

Conditional Rules

Learn how to use NLG Form conditional rule helpers for required-if, prohibited-if, required-with, and required-without validation flows.

Project Information

Documentation links, versioning policy, contribution guidelines, licensing, and project resources for the NLG Form package.

On this page

TL;DRBasic UsageCommon Use CasesComplete Exampleschema.gomain.goValidation FlowNotes