Building Better SharePoint List Forms with JSON Sections, Static Read-Only Fields, and Conditional Visibility
A SharePoint list form becomes much easier to use when it is organized into clear sections instead of one long stream of fields. Native form configuration supports a custom header, body, and footer, and the body can be split into one or more named sections that contain selected fields. This is the foundation for building a cleaner business form without moving immediately to Power Apps or SPFx. (Microsoft Learn)
The important architectural point is that SharePoint form customization is split across different capabilities. The body is strong for structure and field grouping, fieldsettings can make fields statically read-only, and the conditional formula experience can show or hide fields based on values or the current user. These are related features, but they are not the same thing, and understanding that boundary helps avoid unsupported designs. (Microsoft Learn)
In this article, I will keep every example anonymized. Instead of real client field names, site names, or list names, I will use neutral placeholders such as Requester, Project Title, Reference Number, Approval Flag, and Objective Summary. That makes the pattern reusable for documentation, training, and public blog posts.
Why this approach works well
The native JSON form model is a strong fit when your goal is to improve readability and process control without leaving the out-of-the-box SharePoint experience. Microsoft documents that the body can contain one or more sections, each section can include a chosen set of fields, and fields not explicitly assigned are pushed into the last section. The same documentation also describes fieldsettings, which is where static read-only behavior is configured. (Microsoft Learn)
This means a practical design pattern emerges naturally. Use sections to group related questions, use static read-only settings for fields that should never be edited, and use conditional formulas when the requirement is really about whether a field should appear for a given user or state. That division of responsibility is the safest native approach because it follows the documented feature set instead of trying to force unsupported behavior into the form engine. (Microsoft Learn)
What native form JSON can do
The body configuration supports named sections through the sections array. Each section has a displayname and a fields array. Microsoft also documents that configuring body sections changes the form into a multi-column layout, which is one of the main reasons long forms become easier to scan after this customization is applied. (Microsoft Learn)
The same form configuration model supports fieldsettings, including readonly, which is useful for fields such as generated identifiers, requester information, or system-managed values. This is native, simple, and maintainable when the rule is absolute. In other words, if a field should always be locked, native form JSON is a good place to enforce that UI behavior. (Microsoft Learn)
What native form JSON cannot do directly
A common assumption is that if SharePoint supports readonly: true, it should also support something like readonly only when a status or submit flag changes. The current Microsoft Learn documentation for list form configuration does not describe conditional expressions for readonly; it describes static read-only settings in fieldsettings. The conditional formula experience, documented separately, is for showing or hiding columns in the form. (Microsoft Learn)
That distinction is critical. Native SharePoint supports static read-only in the form configuration and conditional visibility in the form formula experience. It does not document native conditional read-only for list form fields in the same way. When a business rule says “lock this after submit,” the closest native pattern is usually “hide the editable field after submit,” not “switch the field into a conditional read-only state.” (Microsoft Learn)
An anonymized sectioned form example
The example below shows a clean body layout using anonymized field names. This is the kind of JSON you can safely publish in a technical blog.
{ "sections": [ { "displayname": "Project Overview", "fields": [ "Requester", "Project Title", "Reference Number", "Approval Flag" ] }, { "displayname": "1 - Business Context", "fields": [ "Primary Request Purpose", "Objective Summary", "Comparison Data Available" ] }, { "displayname": "2 - Expected Results", "fields": [ "Expected Deliverable" ] }, { "displayname": "3 - Source Information", "fields": [ "Data Provider", "Data Delivery Method", "Available Supporting Documents" ] }, { "displayname": "4 - Conditions", "fields": [ "Operating Conditions" ] }, { "displayname": "5 - Timeline", "fields": [ "Required By Date", "Delivery Format" ] }, { "displayname": "6 - Notes", "fields": [ "Additional Notes" ] } ]}
This pattern follows the documented body-section model exactly: named groups, explicit field assignment, and a cleaner form structure. It is ideal when your main goal is to improve layout and business readability. (Microsoft Learn)
Adding static read-only fields
Now let us extend the same example by locking a couple of fields that should never be changed by end users. In real projects, this often includes the requester and a generated reference number. Microsoft documents fieldsettings as part of list form configuration, and readonly is one of the supported settings. (Microsoft Learn)
{ "sections": [ { "displayname": "Project Overview", "fields": [ "Requester", "Project Title", "Reference Number", "Approval Flag" ] }, { "displayname": "1 - Business Context", "fields": [ "Primary Request Purpose", "Objective Summary", "Comparison Data Available" ] } ], "fieldsettings": [ { "name": "Requester", "readonly": true }, { "name": "ReferenceNumber", "readonly": true } ]}
In production, the name value should match the internal field name, not just the visible display label. That matters both in form configuration and in conditional formulas, because SharePoint expressions reference fields by their internal names. Microsoft’s guidance for conditional formulas also points to using the internal name when formulas do not behave as expected. (Microsoft Learn)
Why conditional read-only is the wrong expectation
Suppose the requirement is: “When Approval Flag becomes true, lock Project Title and Objective Summary.” That sounds natural, but the native documentation does not define a supported formula model for readonly in fieldsettings. Because of that, the following pattern should not be treated as a supported solution:
{ "fieldsettings": [ { "name": "ProjectTitle", "readonly": "=if([$ApprovalFlag] == true, true, false)" } ]}
The safer conclusion is simple: if the business rule is conditional, native SharePoint expects you to solve it with show/hide formulas, not with conditional readonly in the form JSON. (Microsoft Learn)
The supported workaround: conditional visibility
Microsoft documents a dedicated experience for showing or hiding columns in a list or library form using a conditional formula. These formulas evaluate field values and control whether a field appears in the form. Microsoft also states that hiding a column in the form does not delete the column or its data; it only affects the form display. (Microsoft Learn)
That leads to a practical and very effective workaround for “lock after submit.” Instead of changing the field into a read-only state, keep the field editable while the item is in draft and hide it once the approval or submit flag is set. From a user-process perspective, that often achieves the same result. (Microsoft Learn)
For example, in the field’s conditional formula, you can use:
=if([$ApprovalFlag] == true, 'false', 'true')
This means the field is shown while the item is still editable and hidden once the approval flag becomes true. The formula style aligns with the SharePoint formatting syntax reference, which documents Excel-style expressions and field references such as [$ColumnName]. (Microsoft Learn)
Using @me for user-based control
Another powerful native pattern is user-aware visibility. The formatting syntax reference documents special tokens such as @me, which represents the current user in expressions. That makes it possible to show a field only to a specific reviewer, coordinator, or administrator. (Microsoft Learn)
A simple example looks like this:
=if(@me == 'reviewer@contoso.com', 'true', 'false')
This formula makes the field appear only for one specific user. It is still visibility logic, not security trimming and not dynamic read-only, but it is extremely useful in controlled business forms. (Microsoft Learn)
You can also combine user logic and process-state logic in a single formula:
=if(@me == 'reviewer@contoso.com' && [$ApprovalFlag] != true, 'true', 'false')
This version shows the field only to the designated reviewer and only while the item is still not approved. It is one of the closest native solutions to “only one user can still edit before final submission.” (Microsoft Learn)
Why anonymization matters in blog content
Anonymization is more than a privacy habit. It also improves the quality of the technical article because it highlights the reusable pattern rather than the original tenant-specific implementation. A reader learns more from a clean example like Reference Number or Approval Flag than from an internal business acronym that only makes sense inside one environment.
For SharePoint documentation specifically, anonymization also helps avoid confusion between a field’s display label and its internal name. In a public article, you can teach the concept with readable labels, then add a note that production implementations should verify the internal name before using fieldsettings or conditional formulas. That makes the article both safer and more technically accurate. (Microsoft Learn)
Recommended production pattern
For most SharePoint teams, the most maintainable native approach is straightforward. Use body sections to structure the form, use static read-only only where the rule is always true, use conditional formulas where the requirement is really about visibility, and reserve Power Apps or SPFx for cases that require richer styling or truly dynamic behavior beyond the documented native feature set. (Microsoft Learn)
This approach keeps the solution close to the platform, reduces complexity, and makes support easier over time. It also aligns cleanly with Microsoft Learn guidance instead of depending on undocumented behavior. (Microsoft Learn)
Complete publish-ready example
Here is the full anonymized example combining sections and static read-only fields in one block.
{ "sections": [ { "displayname": "Project Overview", "fields": [ "Requester", "Project Title", "Reference Number", "Approval Flag" ] }, { "displayname": "1 - Business Context", "fields": [ "Primary Request Purpose", "Objective Summary", "Comparison Data Available" ] }, { "displayname": "2 - Expected Results", "fields": [ "Expected Deliverable" ] }, { "displayname": "3 - Source Information", "fields": [ "Data Provider", "Data Delivery Method", "Available Supporting Documents" ] }, { "displayname": "4 - Conditions", "fields": [ "Operating Conditions" ] }, { "displayname": "5 - Timeline", "fields": [ "Required By Date", "Delivery Format" ] }, { "displayname": "6 - Notes", "fields": [ "Additional Notes" ] } ], "fieldsettings": [ { "name": "Requester", "readonly": true }, { "name": "ReferenceNumber", "readonly": true } ]}
Then, for any field that should disappear after submission, add a conditional formula like this in the form field configuration:
=if([$ApprovalFlag] == true, 'false', 'true')
And for any field that should appear only for a named reviewer before approval:
=if(@me == 'reviewer@contoso.com' && [$ApprovalFlag] != true, 'true', 'false')
Together, these three pieces give you a strong native form pattern: structured layout, permanent locks for system-owned data, and conditional visibility for business process control. (Microsoft Learn)
Conclusion
Native SharePoint form JSON is excellent for making long forms understandable. Sections improve layout, static read-only settings protect system-owned values, and conditional formulas add state-aware and user-aware visibility. The one thing to avoid is expecting native conditional read-only support where Microsoft only documents static readonly and conditional show/hide. Once that boundary is clear, the design becomes much more predictable. (Microsoft Learn)
For many real-world list forms, this pattern is the right middle ground. It is richer than the default form, much lighter than a full Power Apps rewrite, and fully aligned with the documented SharePoint customization model on Microsoft Learn. (Microsoft Learn)
Step-by-step table
| Step | Goal | Native feature | Example |
|---|---|---|---|
| 1 | Group related fields | sections | Project Overview, Business Context, Timeline |
| 2 | Lock always-protected fields | fieldsettings.readonly | Requester, ReferenceNumber |
| 3 | Hide a field after submit/approval | Conditional formula | =if([$ApprovalFlag] == true, 'false', 'true') |
| 4 | Show a field only for one reviewer | Conditional formula with @me | =if(@me == 'reviewer@contoso.com', 'true', 'false') |
| 5 | Combine process state and user logic | Conditional formula | =if(@me == 'reviewer@contoso.com' && [$ApprovalFlag] != true, 'true', 'false') |
| 6 | Keep the article reusable | Anonymized field names | Requester, Project Title, Approval Flag |
Technical summary table
| Capability | Native support | Notes |
|---|---|---|
| Custom header, body, and footer | Yes | Documented in list form configuration. (Microsoft Learn) |
| Body sections with grouped fields | Yes | Supports one or more sections with selected fields. (Microsoft Learn) |
| Static read-only fields | Yes | Supported through fieldsettings.readonly. (Microsoft Learn) |
| Conditional read-only | No documented native support | Use conditional visibility instead. (Microsoft Learn) |
| Conditional show/hide fields | Yes | Configured through form conditional formulas. (Microsoft Learn) |
Current-user expressions with @me | Yes | Part of SharePoint formatting syntax. (Microsoft Learn) |
| Hidden field equals hard security | No | Hiding affects display, not the underlying column or data. (Microsoft Learn) |
| Internal field name matters | Yes | Important for formulas and field settings. (Microsoft Learn) |
