Blazor WASM working with dom elements without using JavaScript - javascript

I am in the process of porting an old web form app to Blazor WASM.
The app is using a lot of JavaScript and I wonder how to best work with the DOM in Blazor.
Let's take this example:
<ul id="cii-tabmenu" class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" data-tabIndex="0" href="#">Mål og investeringspolitik</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="1" href="#">Risk-reward-profil</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="2" href="#">Gebyrer</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="3" href="#">Tidligere resultater</a>
</li>
<li class="nav-item">
<a class="nav-link" data-tabIndex="4" href="#">Praktiske oplysninger</a>
</li>
</ul>
We need the following to have a functional tab strip
A click handler that gets the tab clicked
Code that sets the Active class on the clicked tab and removed it on the previous tab.
I can easily add an onclick handler like #onClick="TabClicked(index)" but how can I set the active class and remove the one previously selected?
I know how to do it in JavaScript but now I work in Blazor and would like to use as little js as possible.

This is not the most elegant solution by a long shot but it should help you understand the blazor paradigm better:
<ul id="cii-tabmenu" class="nav nav-tabs">
<li class="nav-item">
<a class="#(myawesometab[0])" data-tabIndex="0" href="#" #onclick="#(e => myawesometabclick(e, 0))">Mål og investeringspolitik</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[1])" data-tabIndex="1" href="#" #onclick="#(e => myawesometabclick(e, 1))">Risk-reward-profil</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[2])" data-tabIndex="2" href="#" #onclick="#(e => myawesometabclick(e, 2))">Gebyrer</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[3])" data-tabIndex="3" href="#" #onclick="#(e => myawesometabclick(e, 3))">Tidligere resultater</a>
</li>
<li class="nav-item">
<a class="#(myawesometab[4])" data-tabIndex="4" href="#" #onclick="#(e => myawesometabclick(e, 4))">Praktiske oplysninger</a>
</li>
</ul>
#code
{
private string[] myawesometab = new string[5] { "nav-link active", "nav-link", "nav-link", "nav-link", "nav-link" };
private void myawesometabclick(MouseEventArgs e, int myawesometabnumber)
{
for (int i = 0; i < 5; i++)
{
myawesometab[i] = "nav-link";
}
myawesometab[myawesometabnumber] = "nav-link active";
}
}
Also, as razor pages use a similar file structure to winforms, you might try to update the entire project to razor pages, although I obviously don't understand all the complexities of the project.

Related

JavaScript scrollIntoView gets randomly stuck

I have made a one-page website using HTML, CSS/Tailwind, and Vanilla JavaScript. The issue is that when I click on one of the navbar links sometimes it works, and sometimes it gets stuck; where it does not respond until I click multiple times on the link(The number of times is not consistent). Not sure what the issue could be.
HTML markup:
<ul class="hidden sm:flex uppercase items-center space-x-10">
<li class="nav-link">
<a onclick="scrollToSection('#main-container')">Hjem</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#services')">Tjenster</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#pricing')">Priser</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#contact')">Kontakt</a>
</li>
</ul>
JavaScript Code:
function scrollToSection(element) {
var element = document.getElementById(element);
element.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"})
}
I was able to fix this thanks to the comment made by Rana; where it was pointed out that only the text(a tag) is clickable rather than the entire li element.
New HTML markup:
<ul class="hidden sm:flex uppercase items-center space-x-10">
<li class="nav-link" onclick="scrollToSection('#main-container')">
<a>Hjem</a>
</li>
<li class="nav-link" onclick="scrollToSection('#services')">
<a >Tjenster</a>
</li>
<li class="nav-link" onclick="scrollToSection('#pricing')">
<a >Priser</a>
</li>
<li class="nav-link" onclick="scrollToSection('#contact')">
<a >Kontakt</a>
</li>
</ul>

AngularJS tabs notifications

I'm looking for a way to implement "tab notification" in AngularJS, to indicate that there are alerts that need to be taken care of. Something like :
(1) (3)
TAB_ONE TAB_TWO TAB_THREE
Do you have any suggestions on how this can be done?
I will use a UI framework, like Bootstrap. Then I will have a controller that holds the counters for the badges.
(function() {
var app = angular.module("tabbadges",[]);
app.controller("badgesController", badgesController);
function badgesController($scope) {
$scope.badges = {
tab1: 4,
tab2: 6,
tab3: 2
};
}
})();
I will then create the html for the view
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" href="#">Tab one
<span class="badge badge-pill badge-primary">{{badges.tab1}}</span>
</a>
<li class="nav-item">
<a class="nav-link" href="#">Tab two
<span class="badge badge-light badge-primary">{{badges.tab2}}</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Tab three <span class="badge badge-light badge-primary">{{badges.tab3}}</span></a>
</li>
</ul>
[Codepen] (https://codepen.io/xaviguardia/pen/LYEybvZ)

I need to highlight the clicked navbar with active class

This is my Navbar code:
<div class="navbar-collapse offcanvas-collapse justify-content-md-center" id="navbarsExampleDefault">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#Url.Action(" DashBoard ","Admin ")">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" SectionsList ","Admin ")">Sections</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" DifficultyList ","Admin ")">Difficulty</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" QuestionsList ","Admin ")">Questions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" AssessmentList ","Admin ")">Assessments</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" UsersList ","Admin ")">User's</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Students</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="nav-link" href="#Url.Action(" StudentResult ","Admin ")">Student Results</a>
</div>
</li>
</ul>
</div>
This is my click function:
$("#navbarsExampleDefault li a").click(function() {
$(this).parent().addClass('active').siblings().removeClass('active');
});
I need to highlight the selected navbar with active class. I have tried this one but not working
public ActionResult SectionsList()
{
return view();
}
This is one of my action method
Place the below edited piece of code which is tested
$(document).ready(function(){
$(".navbar-nav .nav-link").click(function (e) {
e.preventDefault();
$('.nav-item').removeClass('active');
$(this).closest('.nav-item').addClass('active');
});
});
var change = function () {
var url = window.location.pathname;
$('ul.navbar-nav a[href="' + url + '"]').parent().addClass('active');
};
change();
Load this function in the js file which is common to every page and remove class active from li.
Works even when the page reloads.
I hope it works for you! Thanks!
Please use below code
$("#navbarsExampleDefault li a").click(function () {
$('.nav-item').removeClass('active');
$(this).parent().addClass('active');
});
Hope it works for you Thanks!

Storing active class in local storage when using bootstrap 4 tabs

I am having some trouble with the tab list below:
<ul class="nav nav-tabs" data-tabs="tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" href="{$PageUrl}" role="tab">View</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=edit" role="tab">Edit</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=diff" role="tab">History</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=print" role="tab">Print</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{$PageUrl}?action=attr" role="tab">Attributes</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown2">
<a class="dropdown-item" data-toggle="tab" href="#fat2" role="tab">#fat</a>
<a class="dropdown-item" data-toggle="tab" href="#mdo2" role="tab">#mdo</a>
</div>
</li>
</ul>
Everything displays fine but this differs from how a lot of people implement tabs. Most examples i see have 'tab-content' and that shows the content for each tab. In my case i am using tabs to link alternate pages all together. This is where my issue comes in, When clicking on 'Edit' tab it does indeed load the edit page but with the active class or the 'View' tab still active. I cannot get the active class to switch between the tabs. I think this is because the page is reloading therefore eliminating the active data and setting it to default. How can I get around this and have it show the correct active tab after the newly selected page loads? Thanks for any help!
Edit:
Previously I was trying to use this at the bottom of my body with no luck:
$(function(){
var current = location.pathname;
$('#nav li a').each(function(){
var $this = $(this);
// if the current path is like this link, make it active
if($this.attr('href').indexOf(current) !== -1){
$this.addClass('active');
}
})
})
Here is a possible solution:
<ul class="nav nav-tabs" data-tabs="tabs" role="tablist">
<li class="nav-item">
<a class="default nav-link" href="{$PageUrl}" role="tab">View</a>
</li>
<li class="nav-item">
<a class="edit nav-link" href="{$PageUrl}?action=edit" role="tab">Edit</a>
</li>
<li class="nav-item">
<a class="diff nav-link" href="{$PageUrl}?action=diff" role="tab">History</a>
</li>
<li class="nav-item">
<a class="print nav-link" href="{$PageUrl}?action=print" role="tab">Print</a>
</li>
<li class="nav-item">
<a class="attr nav-link" href="{$PageUrl}?action=attr" role="tab">Attributes</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown2">
<a class="dropdown-item" data-toggle="tab" href="#fat2" role="tab">#fat</a>
<a class="dropdown-item" data-toggle="tab" href="#mdo2" role="tab">#mdo</a>
</div>
</li>
</ul>
<script>
$(function() {
var action = (location.search.match(/(\^?|&)action=(.*?)($|&)/i) || [])[2]
if(action) {
$('a.nav-link.'+action).addClass('active')
} else {
$('a.nav-link.default').addClass('active')
}
})
</script>
Does not add active class to any of the tabs by default.
All tab links have their action as class, to make it easy
On load it thecks the query in the window's address, and sets the active class accordingly

How to change element's class to active?

I'm using a bootstrap template for a side navbar as a partial in EJS which is then included on all pages that use it. Is was taken from their Dashboard template. The HTML is
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" href="/profile">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accountdetails">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/admin">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/transactions">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/contract">Contract</a>
</li>
</ul>
</nav>
Whichever link has the active class has particular styling with darker blue in the background. I now want to change this programatically when navigating to the different links.
They're all going to different pages so I could just change there the issue is that I'm including the whole sidebar code as an EJS partial so that wouldn't work. I also tried this answer but it didn't work (flashes the active styling but disappears - probably because it is routing to another page?).
There are plenty of questions here about changing an HTML element programatically but they usually use document.getElementById which seems like too much work (giving each an ID, checking all, etc). Is there a quicker / correct way of doing this?
You could do the following:
Set a click event on .nav-item, to add .active class.
Remove .active class from any other sibling element.
$('.nav-item').on('click', function() {
$(this).addClass('active').siblings('li').removeClass('active');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item active">
<a class="nav-link" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contract</a>
</li>
</ul>
</nav>
Some people answering are a bit confused, thinking you are staying on the same page, and changing the class of your <a> tags. But I think your clicks on these navigate to new pages, and you want the appropriate <a> to have class active when the page loads.
This might help:
<script>
var path = location.pathname; // ex: '/profile';
var activeItem = document.querySelector("a[href='" + path + "']");
activeItem.class += ' active';
</script>
And of course with jquery it's even easier:
$(function() {
var path = location.pathname;
$("a[href='" + path + "']").addClass('active');
})
This is a code for helping you.
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Account Details</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Admin</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contract</a>
</li>
</ul>
</nav>
<script type="text/javascript">
$(function () {
$(".nav-item").click(function () {
$(".nav-item").each(function () {
$(this).find("a").removeClass("active");
});
$(this).find("a").addClass("active");
});
});
</script>
If your using EJS you can probably do something like the following
<a class="nav-link<% if (page_name === 'profile') { %> active<% } %>" href="/profile">Overview</a>
This is untested but should get you going on the right path. Just do a if statement using EJS's syntax to check if you are on the correct page and add the word active.

Categories