Razor Page Linked Dropdowns

Source Code: https://git.fhict.nl/I872272/RazorPageLinkedDropdown

Hosted Version: https://app8i872272.luna.fhict.nl/

This project demonstrates three different approaches to implementing cascading/linked dropdowns in ASP.NET Core Razor Pages. Each approach has its own advantages and use cases.

Overview

The application implements cascading dropdowns for selecting car Makes and Models:

  • Make dropdown: Initially populated with car makes (Toyota, Honda, Ford, BMW, Mercedes-Benz)
  • Model dropdown: Dynamically populated based on the selected Make

Three Implementation Techniques

1. Basic AJAX with jQuery (/BasicCascading)

Location: Pages/BasicCascading.cshtml and Pages/BasicCascading.cshtml.cs

Description: A straightforward implementation using jQuery AJAX calls to fetch data asynchronously without page reloads.

How it works:

  • The Make dropdown is populated server-side on initial page load
  • When a Make is selected, jQuery makes an AJAX GET request to /BasicCascading?handler=Models
  • The server returns JSON data with the models for the selected make
  • JavaScript dynamically populates the Model dropdown without page refresh

Key Features:

  • ✅ No page reloads (smooth user experience)
  • ✅ Fast and responsive
  • ✅ JSON data transfer (lightweight)
  • ❌ Requires jQuery dependency
  • ❌ JavaScript code embedded in the page (less reusable)

Files:

  • Pages/BasicCascading.cshtml - Main page with inline JavaScript
  • Pages/BasicCascading.cshtml.cs - PageModel with OnGetModels handler

Code Example:

$.ajax({
    url: '/BasicCascading?handler=Models',
    type: 'GET',
    data: { make: selectedMake },
    success: function(models) {
        // Populate dropdown
    }
});

2. PartialViews with AJAX/jQuery (/CascadingDropdowns)

Location: Pages/CascadingDropdowns.cshtml and related partial views

Description: A modular approach using PartialViews for UI components and a separate script partial for JavaScript logic.

What is a Partial View?

A partial view (also called a partial) is a Razor view file (.cshtml) that contains reusable HTML markup and Razor syntax. Unlike a full page, a partial view:

  • Cannot be accessed directly via a URL (no @page directive)
  • Is rendered within another view or page
  • Promotes code reusability and separation of concerns
  • Typically starts with an underscore (_) in the filename (e.g., _MakeDropdownPartial.cshtml)

Benefits of Partial Views:

  • Reusability: Write once, use in multiple pages
  • Modularity: Break complex pages into smaller, manageable components
  • Maintainability: Update a component in one place, affects all usages
  • Testability: Easier to test individual components
  • Organization: Keep related markup together

How to Use Partial Views:

@await Html.PartialAsync("PartialName", modelData)

The first parameter is the partial view name (without .cshtml extension), and the optional second parameter is the model/data to pass to the partial.

How it works:

  • UI components are separated into reusable partial views:
    • _MakeDropdownPartial.cshtml - Make dropdown component
    • _ModelDropdownPartial.cshtml - Model dropdown component
    • _CascadingDropdownScriptsPartial.cshtml - JavaScript logic
  • The main page composes these partials together
  • Uses the same AJAX/jQuery approach as Technique #1, but with better code organization

Key Features:

  • ✅ Modular and reusable components
  • ✅ Separation of concerns (UI, logic, scripts)
  • ✅ No page reloads
  • ✅ Easy to maintain and test
  • ❌ Still requires jQuery dependency
  • ❌ Uses JSON responses

Files:

  • Pages/CascadingDropdowns.cshtml - Main page
  • Pages/CascadingDropdowns.cshtml.cs - PageModel
  • Pages/Shared/_MakeDropdownPartial.cshtml - Make dropdown partial
  • Pages/Shared/_ModelDropdownPartial.cshtml - Model dropdown partial
  • Pages/Shared/_CascadingDropdownScriptsPartial.cshtml - JavaScript partial

Code Example:

@await Html.PartialAsync("_MakeDropdownPartial", Model.Makes)
@await Html.PartialAsync("_ModelDropdownPartial")

3. Traditional Form Submission with PartialViews (/TraditionalCascading)

Location: Pages/TraditionalCascading.cshtml and related partial views

Description: A server-side approach using traditional form POST requests with full page reloads. No jQuery or JSON required.

How it works:

  • Uses a standard HTML form with POST method
  • When a Make is selected, vanilla JavaScript automatically submits the form
  • The server processes the POST request in OnPost(string selectedMake) handler
  • The server returns the full page with the Model dropdown populated server-side
  • The selected Make is preserved through the form submission

Key Features:

  • ✅ No JavaScript dependencies (works without jQuery)
  • ✅ No JSON responses (pure HTML)
  • ✅ Server-side rendering (better for SEO)
  • ✅ Works even if JavaScript is disabled (with submit button)
  • ✅ Simpler architecture
  • ❌ Full page reloads (less smooth UX)
  • ❌ More server round-trips

Files:

  • Pages/TraditionalCascading.cshtml - Main page with form
  • Pages/TraditionalCascading.cshtml.cs - PageModel with OnPost handler
  • Pages/Shared/_TraditionalMakeDropdownPartial.cshtml - Make dropdown partial
  • Pages/Shared/_TraditionalModelDropdownPartial.cshtml - Model dropdown partial
  • Pages/Shared/_TraditionalCascadingScriptsPartial.cshtml - Vanilla JavaScript for auto-submit

Code Example:

public void OnPost(string selectedMake)
{
    Makes = CarData.GetMakes();
    SelectedMake = selectedMake;
    Models = CarData.GetModels(selectedMake);
}
// Vanilla JavaScript (no jQuery)
makeDropdown.addEventListener('change', function() {
    form.submit();
});

Comparison Table

Feature Technique 1
(Basic AJAX)
Technique 2
(Partials + AJAX)
Technique 3
(Traditional Form)
Page Reloads ❌ No ❌ No ✅ Yes
jQuery Required ✅ Yes ✅ Yes ❌ No
JSON Responses ✅ Yes ✅ Yes ❌ No
Modularity ❌ Low ✅ High ✅ High
Reusability ❌ Low ✅ High ✅ High
User Experience ✅ Excellent ✅ Excellent ⚠️ Good
SEO Friendly ⚠️ Moderate ⚠️ Moderate ✅ Excellent
JavaScript Disabled ❌ No ❌ No ✅ Yes*
Complexity ⚠️ Medium ⚠️ Medium ✅ Low

*With a submit button fallback


Data Model

All three techniques use the same data source: Models/CarData.cs

public static class CarData
{
    // Makes: Toyota, Honda, Ford, BMW, Mercedes-Benz
    // Models vary by Make
}

When to Use Each Technique

Use Technique 1 (Basic AJAX) when:

  • You need a quick, simple solution
  • Code reusability is not a priority
  • You're already using jQuery in your project

Use Technique 2 (Partials + AJAX) when:

  • You want modular, maintainable code
  • You need reusable UI components
  • You want the best user experience with AJAX
  • You're building a larger application

Use Technique 3 (Traditional Form) when:

  • You want to avoid JavaScript dependencies
  • SEO is important
  • You need to support users with JavaScript disabled
  • You prefer server-side rendering
  • Simplicity is a priority

Running the Application

  1. Navigate to the project directory
  2. Run dotnet restore (if needed)
  3. Run dotnet run
  4. Open your browser to the URLs shown in the console (typically https://localhost:5001 or http://localhost:5000)

The application includes navigation links to all three examples:

  • Home (/Index) - Overview and documentation
  • Basic Cascading (/BasicCascading) - Basic AJAX implementation
  • Cascading Dropdowns (/CascadingDropdowns) - PartialViews with AJAX
  • Traditional Cascading (/TraditionalCascading) - Traditional form submission

Technologies Used

  • ASP.NET Core 8.0
  • Razor Pages
  • jQuery (for Techniques 1 & 2)
  • Vanilla JavaScript (for Technique 3)
  • Bootstrap 5 (for styling)

Notes

  • All three techniques use the same underlying data (CarData class)
  • The partial views in Technique 3 avoid using @model directives to prevent conflicts with Razor's model directive
  • Technique 3 uses variable name carModel instead of model in loops to avoid conflicts with Razor's @model directive