Navigating pages in Blazor - c#

SO i want to navigate from one page to another. From a list of products to a edit product view. On my list page i have a link as follows.
<NavLink class="nav-link">
<span class="oi oi-list-rich" aria-hidden="true" id="#product.Id" #onclick="#(() => Navigate(product.Id))" style="cursor: pointer"></span> Edit #*FIX ME should link to edit product. Obviously...*#
</NavLink>
And the code is to navigate is:
void Navigate(long productId)
{
NavManager.NavigateTo("/editproduct/" + productId);
}
and i want to get to a page:
#page "/editproduct/{id}"
In my opinion my code should work. Yet im getting a:
Uncaught Error: System.ArgumentException: There is no event handler associated with this event.
when i click on my link.
Any ideas how to fix this ?

I don't believe that the problem is the navigation itself. Try the navigation from two other pages (create page1 and page2) and give it a try.
If it works properly, the problem is elsewhere in your code.
I would give this response as a comment, but like Caveman, I don't have enough reputation.

Take a look at a NavLink in NavMenu.razor
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
Note the href pointing to where you want to navigate to.
<NavLink class="nav-link" href="#($"editproduct/{product.Id}")">

Related

Problem aligning contents of Blazor dropdown-menu

I have a problem with a dropdown-menu I've added to a Blazor server application, in that the background shading of each dropdown-item doesn't align correctly when placed in the default top-row div.
When I drop the same code in the default counter page, I don't have the problem.
I'm guessing the top-row div is causing inheritance of one or more CSS classes, but as a long-time (20 yrs) C# WinForms developer that's only just starting to look at Blazor and web development, I don't really know where to start correcting this. Can anybody offer me some pointers on where I might be going wrong?
Here's the code taken from MainLayout.razor. The exact same dropdown div block in the counter.razor page works fine, as shown above.
<main>
<div class="top-row px-4">
Home
Plans
<AuthorizeView>
<Authorized>
</Authorized>
<NotAuthorized>
<div class="dropdown">
<a #onclick=this.Toggle class="btn btn-secondary dropdown-toggle" type="button"
id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Manage
</a>
#if (isActive)
{
<div class="dropdown-menu show" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Sign In</a>
<a class="dropdown-item" href="#">Register</a>
</div>
}
</div>
</NotAuthorized>
</AuthorizeView>
About Us
</div>
By default, MainLayout.razor also includes the MainLayout.razor.css file (with .top-row style). You probably should look for a solution to your problem there.

Why doesnt the page preserve the data?

So I'm currently looking at the Blazor example project.. The "Counter" to be more specific, and when I increment the value on the page, and then click a different tab on the webapp, let's say the "Fetch data" tab which pulls up the weather, and then I go back, the value that was incremented is back to 0.. Why is that? Why isn't it saved?
Here is the NavMenu
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
</ul>
</div>
And the Counter
#page "/counter"
<h1>Counter</h1>
<p>Current count: #currentCount</p>
<button class="btn btn-primary" #onclick="IncrementCount">Click me</button>
#code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
This is by design. When your Counter Page Component goes out of scope it is destroyed, and when you go back, it is re-created. But you can cache its state (the count value) and read the last value when you go back to the page. You may save the state value in the local storage or session storage (JavaScript Api), which you can use directly employing the JSInterop feature of Blazor, or still better, use libraries design to work with Blazor created by the Blazor community, and even by the Blazor team (recommended)
Hope this helps...
Components are created/destroyed as needed, even within a single page if they are displayed / hidden. Therefore, any state they hold is lost along with the component that has disappeared.
Components are designed for rendering visuals and managing interaction. They can hold some state, but not state across their own lifetimes. To achieve this you need to store the state elsewhere, in a service for example.
I wrote Fluxor to deal with this scenario: https://github.com/mrpmorris/fluxor
Someone created a video here: https://www.youtube.com/watch?v=k_c-ErPaYa8
I think what you are looking for is, State Management.
When you change your state for each user and you want to keep the state, then you need to save the state.
There are several methods (like caching) to perform this,
Take a look at here

How do I navigate different pages while my data loads and keep the state? [duplicate]

So I'm currently looking at the Blazor example project.. The "Counter" to be more specific, and when I increment the value on the page, and then click a different tab on the webapp, let's say the "Fetch data" tab which pulls up the weather, and then I go back, the value that was incremented is back to 0.. Why is that? Why isn't it saved?
Here is the NavMenu
<div class="#NavMenuCssClass" #onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
</ul>
</div>
And the Counter
#page "/counter"
<h1>Counter</h1>
<p>Current count: #currentCount</p>
<button class="btn btn-primary" #onclick="IncrementCount">Click me</button>
#code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
This is by design. When your Counter Page Component goes out of scope it is destroyed, and when you go back, it is re-created. But you can cache its state (the count value) and read the last value when you go back to the page. You may save the state value in the local storage or session storage (JavaScript Api), which you can use directly employing the JSInterop feature of Blazor, or still better, use libraries design to work with Blazor created by the Blazor community, and even by the Blazor team (recommended)
Hope this helps...
Components are created/destroyed as needed, even within a single page if they are displayed / hidden. Therefore, any state they hold is lost along with the component that has disappeared.
Components are designed for rendering visuals and managing interaction. They can hold some state, but not state across their own lifetimes. To achieve this you need to store the state elsewhere, in a service for example.
I wrote Fluxor to deal with this scenario: https://github.com/mrpmorris/fluxor
Someone created a video here: https://www.youtube.com/watch?v=k_c-ErPaYa8
I think what you are looking for is, State Management.
When you change your state for each user and you want to keep the state, then you need to save the state.
There are several methods (like caching) to perform this,
Take a look at here

Passing data to Layout Razor Pages without controller

I would like to visualize data from my model in my layout page - specifically when user adds an item to the shopping cart I would like to count number of items in the shopping cart and display it in the navbar next to the image of shopping cart.
User can add the product from more then 1 page (e.g. from Index page, or Product/index page etc.).
Anyone dealt with something similar?
I would like my navbar to look like this :
Navbar
<div class="navbar-collapse collapse show" id="navbarColor01" style="">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a asp-page="/Index" class="nav-link" >Home <span class="sr-only">(current)</span></a>
</li>
<li>
<a asp-page="/ShoppingCart/Index"> <i class="fas fa-shopping-cart fa-1x fa-cog "></i></a>
<div class="badge badge-danger badge-pill">5</div> //here is the number to be displayed
</li>
</ul>
</div>
There are different ways to achieve this, evaluate your options then decide what to do.
You can achieve this by:
Using view bags. This would cause code reputation throughout your project. Because you are going to set the view bag for each page visit.
Using partial views. By calling Ajax request to the action, and then return partial view. Partial views usually intended to be part of the Controller/Page, which wouldn't make sense to have GetCart from different controller/page. Also it is best for avoiding view reputation.
View Component. This is usually the ideal way to do it, since you need to do work behind the scene then return the value. View Components can live in their own, which is good for SoC.
My personal recommendation would be View Component, it is a new feature in asp.net core (replacing ChildAction).

Anchor tag not appending to URL Action C# MVC5

I have a strange issue that I can't seem to debug. I have some Bootstrap Tabs, that have Action Links in like so:
<div class="page-tabs">
<ul class="nav nav-tabs">
<li class='#(actionName.ToLower() == "viewamendments" &&
controllerName.ToLower() == "songsmanagement" ? "active" : "")'>
Old Song
</li>
</ul>
But for some reason when I go to the URL /SongManagement/ViewAmendments the tab is styled correctly but in the Console using Chrome it's not appending the href attribute instead of its showing:
<a data-container="body" data-toggle="tooltip" title="" data-original-title="Old Song">Old Song</a>
I have cleaned the solution in VS2017 and Rebuilt it, I have also Cleared the browser cache and hard reset. Also tried in Incognito.
Any advice on what it could be?
Turns out that it was due to the controller name, not being found. A simple change, but usually it won't append the href tag when it can't find the method in the controller.
can you please try with
data-target='#Url.Action("ViewAmendments", "SongManagement")'
Add this attribute in your anchor tag and try again.

Categories

Resources