Sitecore双下拉联动搜索功能示例及可配置实现需求问询
Absolutely! This is a common scenario often called a dependent dropdown with filtered results (or cascading dropdown with submit-based filtering). Below I’ll walk you through a complete implementation that works seamlessly with Sitecore, letting content editors configure countries, departments, and their associated contacts directly in the CMS.
Step 1: Sitecore Template Setup
First, let's build the templates so editors can manage all the data without touching code:
1.1 Contact Template
- Fields:
Name(Single-Line Text)Email(Single-Line Text)Phone(Single-Line Text)
1.2 Department Template
- Fields:
Department Name(Single-Line Text)Associated Contacts(Multilist, targets Contact items)
1.3 Country Template
- Fields:
Country Name(Single-Line Text)Associated Departments(Multilist, targets Department items)
1.4 Organize Your Items
Create a folder structure under /sitecore/content/Global like:
/Countries(store all Country items here)/Departments(store all Department items here)/Contacts(store all Contact items here)
Step 2: Frontend (Razor View)
Here's the Razor view for the dropdowns, submit button, and contact display area. We'll populate the country dropdown on page load, and optionally add AJAX to update departments when a country is selected (but we'll also support full form submission as requested):
@model YourProject.Models.ContactFilterModel <form method="post" asp-action="FilterContacts"> <div class="form-group mb-3"> <label for="country" class="form-label">Country:</label> <select id="country" name="selectedCountryId" class="form-control"> <option value="">Select a country</option> @foreach (var country in Model.Countries) { <option value="@country.Id" @(Model.SelectedCountryId == country.Id ? "selected" : "")>@country.Name</option> } </select> </div> <div class="form-group mb-3"> <label for="department" class="form-label">Department:</label> <select id="department" name="selectedDepartmentId" class="form-control"> <option value="">Select a department</option> @foreach (var department in Model.Departments) { <option value="@department.Id" @(Model.SelectedDepartmentId == department.Id ? "selected" : "")>@department.Name</option> } </select> </div> <button type="submit" class="btn btn-primary">Find Contact</button> </form> @if (Model.FilteredContacts.Any()) { <h3 class="mt-4">Matched Contacts:</h3> <ul class="list-group mt-2"> @foreach (var contact in Model.FilteredContacts) { <li class="list-group-item"> <strong>@contact.Name</strong><br/> Email: <a href="mailto:@contact.Email">@contact.Email</a><br/> Phone: @contact.Phone </li> } </ul> } else if (Model.IsSubmitted) { <p class="mt-4 text-muted">No contacts found for the selected country and department.</p> }
Step 3: C# View Models
Create simple view models to pass data between the controller and view:
public class ContactFilterModel { public List<SitecoreItemOption> Countries { get; set; } = new(); public List<SitecoreItemOption> Departments { get; set; } = new(); public List<ContactViewModel> FilteredContacts { get; set; } = new(); public string SelectedCountryId { get; set; } public string SelectedDepartmentId { get; set; } public bool IsSubmitted { get; set; } } public class SitecoreItemOption { public string Id { get; set; } public string Name { get; set; } } public class ContactViewModel { public string Name { get; set; } public string Email { get; set; } public string Phone { get; set; } }
Step 4: Controller Logic
Here's the controller code to fetch Sitecore data, handle form submission, and filter contacts based on user selections:
using Sitecore.Data.Items; using Sitecore.Mvc.Controllers; using Sitecore.Data.Fields; using Sitecore.Data; public class ContactController : SitecoreController { private readonly Database _sitecoreDb = Sitecore.Context.Database; public ActionResult Index() { var model = new ContactFilterModel(); PopulateCountries(model); return View(model); } [HttpPost] public ActionResult FilterContacts(ContactFilterModel model) { model.IsSubmitted = true; PopulateCountries(model); // Populate departments based on selected country (or all if no country selected) if (!string.IsNullOrEmpty(model.SelectedCountryId)) { var countryItem = _sitecoreDb.GetItem(new ID(model.SelectedCountryId)); if (countryItem != null) { var departmentsField = (MultilistField)countryItem.Fields["Associated Departments"]; if (departmentsField?.TargetIDs.Any() == true) { model.Departments = departmentsField.GetItems() .Select(item => new SitecoreItemOption { Id = item.ID.ToString(), Name = item["Department Name"] }) .ToList(); } } } else { PopulateAllDepartments(model); } // Filter contacts if both country and department are selected if (!string.IsNullOrEmpty(model.SelectedCountryId) && !string.IsNullOrEmpty(model.SelectedDepartmentId)) { var departmentItem = _sitecoreDb.GetItem(new ID(model.SelectedDepartmentId)); if (departmentItem != null) { var contactsField = (MultilistField)departmentItem.Fields["Associated Contacts"]; if (contactsField?.TargetIDs.Any() == true) { model.FilteredContacts = contactsField.GetItems() .Select(item => new ContactViewModel { Name = item["Name"], Email = item["Email"], Phone = item["Phone"] }) .ToList(); } } } return View("Index", model); } private void PopulateCountries(ContactFilterModel model) { // Adjust the query path to match your Sitecore item structure var countryItems = _sitecoreDb.SelectItems("/sitecore/content/Global/Countries//*[@@templatekey='country']"); if (countryItems != null) { model.Countries = countryItems .Select(item => new SitecoreItemOption { Id = item.ID.ToString(), Name = item["Country Name"] }) .ToList(); } } private void PopulateAllDepartments(ContactFilterModel model) { var departmentItems = _sitecoreDb.SelectItems("/sitecore/content/Global/Departments//*[@@templatekey='department']"); if (departmentItems != null) { model.Departments = departmentItems .Select(item => new SitecoreItemOption { Id = item.ID.ToString(), Name = item["Department Name"] }) .ToList(); } } }
Step 5: Sitecore Editor Workflow
Content editors can now manage everything directly in the CMS:
- Create Contact items with name, email, and phone details.
- Create Department items, then use the
Associated Contactsmultilist to link relevant contacts to the department. - Create Country items, then use the
Associated Departmentsmultilist to link departments that operate in that country. - When a user selects a country + department and submits, the system automatically pulls and displays the linked contacts.
Optional: AJAX Cascading Dropdown Enhancement
To make the department dropdown update automatically when a country is selected (no submit needed), add this jQuery snippet to your view:
<script> $("#country").on("change", function() { const countryId = $(this).val(); $.ajax({ url: '@Url.Action("GetDepartmentsByCountry", "Contact")', type: 'GET', data: { countryId: countryId }, success: function(data) { $("#department").empty().append('<option value="">Select a department</option>'); $.each(data, function(index, item) { $("#department").append(`<option value="${item.id}">${item.name}</option>`); }); } }); }); </script>
And add this action to your controller:
public JsonResult GetDepartmentsByCountry(string countryId) { var departments = new List<SitecoreItemOption>(); if (!string.IsNullOrEmpty(countryId)) { var countryItem = _sitecoreDb.GetItem(new ID(countryId)); if (countryItem != null) { var departmentsField = (MultilistField)countryItem.Fields["Associated Departments"]; if (departmentsField?.TargetIDs.Any() == true) { departments = departmentsField.GetItems() .Select(item => new SitecoreItemOption { Id = item.ID.ToString(), Name = item["Department Name"] }) .ToList(); } } } return Json(departments, JsonRequestBehavior.AllowGet); }
This adds a smoother user experience by eliminating the need to submit just to see relevant departments.
内容的提问来源于stack exchange,提问作者ImSobesBoosted

