I have a Razor Page and in the HTML there's a list of buttons and I want to be able to change the class list on those buttons to highlight the currently selected one. Each button looks like so:
<form asp-page-handler="Posts" method="post">
<button href="posts" aria-current="page">
Posts
</button>
</form>
When it is clicked it will call a handler method and I want to add the active class to it and remove the active class from the previous one. This would be trivial in javascript and maybe it is in c# but after an hour of searching, I can't find a way to do this.
CodePudding user response:
The solution below uses jquery/js.
- Add data-attribute to all the
.nav-link
buttons. I used data-page.
<button data-page="posts href="posts" aria-current="page">
Posts
</button>
- In your Posts page get handler, assign "posts" to a certain viewdata index.
ViewData["ActivePage"] = "posts";
- Then in the layout.cshtml, add this script.
@section scripts {
<script>
$(document).ready(function(){
@if(ViewData["ActivePage"] != null)
{
<text>var activePage = "@ViewData["ActivePage"]";</text>
}
else
{
<text>var activePage = "";</text>
}
// loop through navlinks and assign/remove active class
$(".nav-link").each(function(){
var dataPage = $(this).data("page");
if(dataPage == activePage){
$(this).addClass("active");
}
else{
$(this).removeClass("active");
}
});
});
</script>
}
For the other buttons, you just need to assign unique data-page; data-page= "other name";
Then in their respective handler methods, add ViewData["ActivePage"] = "other name";
Since the script will be included in layout, it would activate for all the pages.
CodePudding user response:
Here is a working demo to add the active class to selected button without js: cshtml.cs:
[BindProperty]
public List<Button> buttons { get; set; }
public void OnGet()
{
buttons = new List<Button> { new Button { Id = 1, Content = "button1" }, new Button { Id = 2, Content = "button2"}, new Button { Id = 3, Content = "button3" } };
public IActionResult OnPostPosts(int id)
{
buttons.ForEach(b => b.IsActive = false);
buttons.Where(b => b.Id == id).ToList().ForEach(b => b.IsActive = true);
//save data to database,add data to gridBind
return Page();
}
}
Button.cs:
public class Button {
public int Id { get; set; }
public string Content { get; set; }
public bool IsActive { get; set; }
}
View:
<form method="post">
@for (var i = 0; i < Model.buttons.Count; i )
{
<input hidden name="buttons[@i].Id" [email protected][i].Id />
<input hidden name="buttons[@i].Content" [email protected][i].Content />
<input hidden name="buttons[@i].IsActive" [email protected][i].IsActive />
}
@foreach (var item in Model.buttons)
{
<input type="submit" asp-page-handler="Posts" asp-route-id="@item.Id" active" : "")" aria-current="page" value="@item.Content" />
}
</form>
CodePudding user response:
I use jquery/js write a simple demo here to show when click on the button, button will add active
class and Bold borders
to show the difference and remove the active class from the previous one
<form asp-page-handler="Index" method="post">
<button href="posts" aria-current="page" id="btn_submit1">
Posts
</button>
</form>
<br />
<form asp-page-handler="Index" method="post">
<button href="posts" aria-current="page" id="btn_submit2">
Posts1
</button>
</form>
<br />
<form asp-page-handler="Index" method="post">
<button href="posts" aria-current="page" id="btn_submit3">
Posts2
</button>
</form>
//...............
@section Scripts{
<head>
<style>
.active{
border: solid;
}
</style>
</head>
<script>
$(function(){
var data = localStorage.getItem("index");
if(data!=null){
$("#" data).addClass('active');
}
})
$("button").click(function () {
localStorage.setItem("index", this.id );
});
</script>
}