Skip to content

Commit abb3d2c

Browse files
authored
Breadcrumb subscribe to LocationChanged example (#119)
1 parent 466ddda commit abb3d2c

37 files changed

+1449
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
2+
<Found Context="routeData">
3+
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
4+
</Found>
5+
<NotFound>
6+
<LayoutView Layout="@typeof(MainLayout)">
7+
<p>Sorry, there's nothing at this address.</p>
8+
</LayoutView>
9+
</NotFound>
10+
</Router>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@page "/products/computer-peripherals"
2+
3+
<h1>Computer Peripherals</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
@page
2+
@model SubscribeToLocationChanged.Pages.ErrorModel
3+
4+
<!DOCTYPE html>
5+
<html>
6+
7+
<head>
8+
<meta charset="utf-8" />
9+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
10+
<title>Error</title>
11+
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
12+
<link href="~/css/app.css" rel="stylesheet" />
13+
</head>
14+
15+
<body>
16+
<div class="main">
17+
<div class="content px-4">
18+
<h1 class="text-danger">Error.</h1>
19+
<h2 class="text-danger">An error occurred while processing your request.</h2>
20+
21+
@if (Model.ShowRequestId)
22+
{
23+
<p>
24+
<strong>Request ID:</strong> <code>@Model.RequestId</code>
25+
</p>
26+
}
27+
28+
<h3>Development Mode</h3>
29+
<p>
30+
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
31+
</p>
32+
<p>
33+
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
34+
It can result in displaying sensitive information from exceptions to end users.
35+
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
36+
and restarting the app.
37+
</p>
38+
</div>
39+
</div>
40+
</body>
41+
42+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.AspNetCore.Mvc.RazorPages;
3+
using Microsoft.Extensions.Logging;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Diagnostics;
7+
using System.Linq;
8+
using System.Threading.Tasks;
9+
10+
namespace SubscribeToLocationChanged.Pages
11+
{
12+
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
13+
[IgnoreAntiforgeryToken]
14+
public class ErrorModel : PageModel
15+
{
16+
public string RequestId { get; set; }
17+
18+
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
19+
20+
private readonly ILogger<ErrorModel> _logger;
21+
22+
public ErrorModel(ILogger<ErrorModel> logger)
23+
{
24+
_logger = logger;
25+
}
26+
27+
public void OnGet()
28+
{
29+
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
30+
}
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@page "/products/computer-peripherals/keyboards/gaming-keyboards"
2+
3+
<h1>Gaming Keyboards</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@page "/"
2+
3+
<h1>Home</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@page "/products/computer-peripherals/keyboards"
2+
3+
<h1>Keyboards</h1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@page "/products"
2+
3+
<h1>Products</h1>
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@page "/"
2+
@namespace SubscribeToLocationChanged.Pages
3+
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4+
@{
5+
Layout = null;
6+
}
7+
8+
<!DOCTYPE html>
9+
<html lang="en">
10+
<head>
11+
<meta charset="utf-8" />
12+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
13+
<title>SubscribeToLocationChanged</title>
14+
<base href="~/" />
15+
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
16+
<link href="css/site.css" rel="stylesheet" />
17+
<link href="SubscribeToLocationChanged.styles.css" rel="stylesheet" />
18+
<link rel="stylesheet" href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" />
19+
<script src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js" defer></script>
20+
</head>
21+
<body>
22+
<component type="typeof(App)" render-mode="ServerPrerendered" />
23+
24+
<div id="blazor-error-ui">
25+
<environment include="Staging,Production">
26+
An error has occurred. This application may no longer respond until reloaded.
27+
</environment>
28+
<environment include="Development">
29+
An unhandled exception has occurred. See browser dev tools for details.
30+
</environment>
31+
<a href="" class="reload">Reload</a>
32+
<a class="dismiss">🗙</a>
33+
</div>
34+
35+
<script src="_framework/blazor.server.js"></script>
36+
</body>
37+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.Extensions.Hosting;
3+
4+
namespace SubscribeToLocationChanged
5+
{
6+
public class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
CreateHostBuilder(args).Build().Run();
11+
}
12+
13+
public static IHostBuilder CreateHostBuilder(string[] args) =>
14+
Host.CreateDefaultBuilder(args)
15+
.ConfigureWebHostDefaults(webBuilder =>
16+
{
17+
webBuilder.UseStartup<Startup>();
18+
});
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:46352",
7+
"sslPort": 44369
8+
}
9+
},
10+
"profiles": {
11+
"IIS Express": {
12+
"commandName": "IISExpress",
13+
"launchBrowser": true,
14+
"environmentVariables": {
15+
"ASPNETCORE_ENVIRONMENT": "Development"
16+
}
17+
},
18+
"SubscribeToLocationChanged": {
19+
"commandName": "Project",
20+
"dotnetRunMessages": "true",
21+
"launchBrowser": true,
22+
"applicationUrl": "https://localhost:5001;http://localhost:5000",
23+
"environmentVariables": {
24+
"ASPNETCORE_ENVIRONMENT": "Development"
25+
}
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
@implements IDisposable
2+
3+
<div style="padding:20px">
4+
<TelerikBreadcrumb Data="@Items" Width="100%"></TelerikBreadcrumb>
5+
</div>
6+
7+
@code {
8+
9+
[Inject] private NavigationManager NavigationManager { get; set; }
10+
11+
public List<BreadcrumbItem> Items { get; set; }
12+
13+
//Create a handler that will be invoked on each location change
14+
private void OnLocationChanged(object sender, LocationChangedEventArgs e)
15+
{
16+
var relativeLocation = NavigationManager.ToBaseRelativePath(e.Location);
17+
SetBreadcrumbs(relativeLocation);
18+
}
19+
20+
//Bind the above handler to the NavigationManager's LocationChanged event
21+
protected override void OnInitialized()
22+
{
23+
NavigationManager.LocationChanged += OnLocationChanged;
24+
var relativeLocation = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
25+
26+
//Set new breadcrumb items on each invocation
27+
SetBreadcrumbs(relativeLocation);
28+
29+
base.OnInitialized();
30+
}
31+
32+
//Sets new breadcrumbs based on the current URL. Called on initial page load as well as on every subsequent location change
33+
public void SetBreadcrumbs(string relativeLocation)
34+
{
35+
var newItems = new List<BreadcrumbItem>() { new BreadcrumbItem { Icon = "home", Url = NavigationManager.BaseUri } };
36+
37+
var locationCrumbs = relativeLocation.Split('/');
38+
string url = NavigationManager.BaseUri;
39+
40+
foreach (var crumb in locationCrumbs)
41+
{
42+
if (!string.IsNullOrEmpty(crumb))
43+
{
44+
url += crumb;
45+
newItems.Add(new BreadcrumbItem { Text = crumb, Url = url, Title = crumb });
46+
url += "/";
47+
}
48+
}
49+
50+
Items = newItems;
51+
StateHasChanged();
52+
}
53+
54+
void IDisposable.Dispose()
55+
{
56+
// Unsubscribe from the event when disposed
57+
NavigationManager.LocationChanged -= OnLocationChanged;
58+
}
59+
60+
public class BreadcrumbItem
61+
{
62+
public string Text { get; set; }
63+
public string Url { get; set; }
64+
public string Title { get; set; }
65+
public string Icon { get; set; }
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@layout TelerikLayout
2+
@inherits LayoutComponentBase
3+
4+
<div class="page">
5+
<div class="sidebar">
6+
<NavMenu />
7+
</div>
8+
9+
<div class="main">
10+
<BreadcrumbWrapper/>
11+
<div class="content px-4">
12+
@Body
13+
</div>
14+
</div>
15+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
.page {
2+
position: relative;
3+
display: flex;
4+
flex-direction: column;
5+
}
6+
7+
.main {
8+
flex: 1;
9+
}
10+
11+
.sidebar {
12+
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
13+
}
14+
15+
.top-row {
16+
background-color: #f7f7f7;
17+
border-bottom: 1px solid #d6d5d5;
18+
justify-content: flex-end;
19+
height: 3.5rem;
20+
display: flex;
21+
align-items: center;
22+
}
23+
24+
.top-row ::deep a, .top-row .btn-link {
25+
white-space: nowrap;
26+
margin-left: 1.5rem;
27+
}
28+
29+
.top-row a:first-child {
30+
overflow: hidden;
31+
text-overflow: ellipsis;
32+
}
33+
34+
@media (max-width: 640.98px) {
35+
.top-row:not(.auth) {
36+
display: none;
37+
}
38+
39+
.top-row.auth {
40+
justify-content: space-between;
41+
}
42+
43+
.top-row a, .top-row .btn-link {
44+
margin-left: 0;
45+
}
46+
}
47+
48+
@media (min-width: 641px) {
49+
.page {
50+
flex-direction: row;
51+
}
52+
53+
.sidebar {
54+
width: 250px;
55+
height: 100vh;
56+
position: sticky;
57+
top: 0;
58+
}
59+
60+
.top-row {
61+
position: sticky;
62+
top: 0;
63+
z-index: 1;
64+
}
65+
66+
.main > div {
67+
padding-left: 2rem !important;
68+
padding-right: 1.5rem !important;
69+
}
70+
}

0 commit comments

Comments
 (0)