Umbraco Forms:能否构建下拉联动复选框的自定义字段类型?
Absolutely! You can absolutely build a dynamic custom field type in Umbraco Forms that updates checkbox options based on a dropdown selection. Let me walk you through the full implementation, from backend setup to frontend interactivity.
1. Create the Custom Field Type (Backend)
First, you'll need to define a custom field class that inherits from Umbraco Forms' FieldType. This class will handle the field's metadata, settings, and core behavior.
using Umbraco.Forms.Core; using Umbraco.Forms.Core.Attributes; using System.Collections.Generic; using System.Linq; public class DynamicDropdownCheckboxField : FieldType { public DynamicDropdownCheckboxField() { Name = "Dynamic Dropdown + Checkboxes"; Description = "Dropdown that shows conditional checkboxes based on selection"; Icon = "icon-list"; DataType = FieldDataType.String; SupportsPrevalues = true; } // Setting for dropdown options (one per line) [Setting("Dropdown Options", Description = "Enter each dropdown option on a new line", View = "textarea")] public string DropdownOptions { get; set; } // Setting for mapping dropdown values to checkbox options [Setting("Checkbox Mappings", Description = "Map dropdown values to checkboxes (format: DropdownValue|Checkbox1,Checkbox2)", View = "textarea")] public string CheckboxMappings { get; set; } // Helper to get mappings as a dictionary for frontend use public Dictionary<string, string> GetMappings() { if (string.IsNullOrEmpty(CheckboxMappings)) return new Dictionary<string, string>(); return CheckboxMappings.Split('\n') .Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains('|')) .ToDictionary( line => line.Split('|')[0].Trim(), line => line.Split('|')[1].Trim() ); } }
Register this field type with Umbraco using a composer:
using Umbraco.Core.Composing; using Umbraco.Forms.Core.Providers.FieldTypes; public class CustomFieldComposer : IComposer { public void Compose(Composition composition) { composition.FieldTypes().Append<DynamicDropdownCheckboxField>(); } }
2. Build the Frontend Field View
Next, create a partial view to render the field and add the JavaScript logic for dynamic updates. Place this in ~/Views/Partials/Forms/Fields/DynamicDropdownCheckboxField.cshtml:
@model Umbraco.Forms.Mvc.Models.FieldViewModel @{ var field = Model.Field as DynamicDropdownCheckboxField; var mappings = field?.GetMappings() ?? new Dictionary<string, string>(); var mappingsJson = Newtonsoft.Json.JsonConvert.SerializeObject(mappings); } <div class="form-group mb-4"> <label for="@Model.Id" class="form-label">@Model.Caption</label> @if (!string.IsNullOrEmpty(Model.Description)) { <p class="form-text text-muted">@Model.Description</p> } <!-- Dropdown Control --> <select id="@Model.Id-dropdown" class="form-select dynamic-dropdown-field" name="@Model.Name-dropdown"> <option value="">Select an option</option> @foreach (var option in field.DropdownOptions.Split('\n').Where(o => !string.IsNullOrWhiteSpace(o))) { var trimmedOption = option.Trim(); <option value="@trimmedOption" @(Model.Value?.Contains(trimmedOption) == true ? "selected" : "")>@trimmedOption</option> } </select> <!-- Dynamic Checkbox Container --> <div id="@Model.Id-checkboxes" class="mt-3" style="display: none;"> <!-- Checkboxes will be injected here --> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const dropdown = document.getElementById('@Model.Id-dropdown'); const checkboxContainer = document.getElementById('@Model.Id-checkboxes'); const checkboxMappings = @Html.Raw(mappingsJson); // Handle dropdown change const updateCheckboxes = () => { const selectedValue = dropdown.value.trim(); checkboxContainer.innerHTML = ''; if (selectedValue && checkboxMappings[selectedValue]) { checkboxContainer.style.display = 'block'; const checkboxOptions = checkboxMappings[selectedValue].split(','); checkboxOptions.forEach((opt, index) => { const cleanOpt = opt.trim(); const checkboxId = '@Model.Id-checkbox-' + index; const checkboxHtml = ` <div class="form-check"> <input class="form-check-input" type="checkbox" id="${checkboxId}" name="@Model.Name" value="${cleanOpt}"> <label class="form-check-label" for="${checkboxId}">${cleanOpt}</label> </div> `; checkboxContainer.insertAdjacentHTML('beforeend', checkboxHtml); }); } else { checkboxContainer.style.display = 'none'; } }; // Initial update on page load dropdown.addEventListener('change', updateCheckboxes); updateCheckboxes(); }); </script>
3. Configure the Field in Umbraco Backend
Once your field type is registered, you can add it to any form:
- Edit your form and click Add field
- Select your new
Dynamic Dropdown + Checkboxesfield from the list - In the field settings:
- Dropdown Options: Enter each dropdown option on a new line (e.g.,
Option A,Option B) - Checkbox Mappings: Define the link between dropdown values and checkboxes (e.g.,
Option A|Checkbox A1,Checkbox A2,Option B|Checkbox B1)
- Dropdown Options: Enter each dropdown option on a new line (e.g.,
4. Handle Submitted Data
When the form is submitted, the selected checkbox values will be stored as a comma-separated string in the field's value. If you need to process this data further, you can hook into Umbraco Forms' submission events (e.g., FormSubmitted event) to parse and handle the values.
内容的提问来源于stack exchange,提问作者Gonzalo

