I'm working on a small personal project and i have a small issue that i'm not sure how to solve. I use Bootstrap4 , ejs templating engine and express.My project has a Navbar where i show Sign in if user is not signed in and Account in the opposite case.
Here is a relevant part of the Navbar:
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto ">
<li class="nav-item navbar-item">
<a class="nav-link" href="/">Home </a>
</li>
<li class="nav-item navbar-item">
<a class="nav-link" href="/">Some link </a>
</li>
<li class="nav-item navbar-item " id="nav-signIn">
<a class="nav-link" href="/signIn">Sign in</a>
</li>
<li class="nav-item dropdown navbar-item" id="nav-account">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Account
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
This is the function that controls what to show on the client side:
function displayAccountOrSignIn() {
if (!document.cookie.split(';').filter((item) => item.includes('logedIn=')).length) {
document.querySelector('#nav-account').style.display = 'none'
}
else {
document.querySelector('#nav-signIn').style.display = 'none'
}
}
My problem is that Navbar is 'jerking' because it first loads HTML and then hides what should not be displayed. I can fix it by checking cookies on the server and then conditionally render parts of Navbar, but i don't think it's a good idea to do so. I'd appreciate any suggestions.
There are a number of options here. To know which one to recommend, we'd probably need to play with your actual site and try a few things. All will work and prevent showing something that shouldn't be seen, some may display sooner.
Have all conditional content hidden first (so nothing ever displays that shouldn't) and then enable display of appropriate parts using your conditional Javascript.
Hide the whole toolbar by default in the HTML until you have run your conditional code and then show the whole toolbar only once its state is finalized at the end of your Javascript. If desired, you can make the toolbar be visibility: hidden rather than display: none so that it still takes up the appropriate vertical height and doesn't cause other content to shift down when it is finally displayed.
Run your conditional script inline in an inline <script> tag immediately after the toolbar HTML. This will ensure that the script runs ASAP after the toolbar HTML is available. You can combine this with either #1 or #2 above.
Determine the proper toolbar server-side so that the HTML that arrives at the browser is already properly pre-formed. Since the server already knows whether the user is logged in or not, this should be possible.
Related
I want to make a dropdown which is clickable also. Like I have a menu which has dropdown options so If I hover on it, will display dropdown and if I want to click on that, it should display link that has been provided to it.
This is the HTML:
<ul class="navbar-nav ml-auto nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="mainservice.html" id="navbarDropdown" role="button" aria-expanded="false"> Logistics Services </a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="ftl.html">FTL</a>
<a class="dropdown-item" href="ltl.html">LTL</a>
<a class="dropdown-item" href="intermodal.html">Intermodal</a>
</div>
</li>
</ul>
So, now I want that if I click on Logistics Services then mainservice.html page should display and dropdown should also be there. It should be mobile friendly also.
I tried through CSS, but when I checked it on mobile, then it is not working as expected.
ul.nav li.dropdown:hover div.dropdown-menu{
display:block;
}
How should I do it?
In my blazor server side application I have cards representing datasets, which the user can manage.
They look like this:
The relevant code looks like this:
<div class="card h-100 text-dark" #onclick="() => OnDatasetSelected(dataset)">
<!-- header image -->
<div class="card-body position-relative">
<div class="dropdown dropstart">
<button type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-three-dots-vertical"></i>
</button>
<ul class="dropdown-menu">
<!-- menu content -->
</div>
<!-- card content -->
</div>
As one can see from the code, I'm currently adding the context menu (three vertical dots) using the template code from bootstraps dropdown (dropleft in my case) component.
This works fine - or rather it would if it weren't for the #onclick event on the card, which calls the code to select the dataset and navigate to another page.
Question basically is: How can I prevent the OnClick event, if an element inside is being clicked on. I guess, what I'm asking is: How can I prevent event bubbling in HTML? Is it possible without adding code to the inner dropdown element (display of bootstrap-dropdowns is done with popper.js, which is external)
Lol, found the answer here 5 minutes after posting:
Simply use onclick="event.stopPropagation();" to prevent the event bubbling.
So in the end I just add this to the dropdown container:
<div class="dropdown dropstart position-absolute top-0 end-0 " onclick="event.stopPropagation();">
<button type="button" class=" btn btn-outline-secondary fs-5 p-0 m-2 border-0"
data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-three-dots-vertical"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
And now I can click my menu button:
Important Edit:
In case you have issues with onclick="event.stopPropagation();" preventing the #onclick event of the inner button to be fired, one can use the following directly at the inner button:
<button type="button" #onclick="MyFunction"
#onclick:stopPropagation="true">
Button Text
</button>
This will call MyFunction when clicking the button, but prevents the event to be propagated to the parent elements.
Since my application had same navigation bar across application, I thought of implementing shared navigation bar across application.
My project structure is a follows
Login
|-Login.html, Login.css, Login.js
Home
|-Home.html, Home.css, Home.js
Test
|-Project.html, Project.css, Project.js
Test1
|-Test1.html, Test1.css, Test1.js
Test2
|-Test2.html, Test2.css, Test2.js
|-Temp
|-Temp.html, Temp.css, Temp.js
|-Shared
|-Shared.html, Shared.css, Shared.js, navigation.html
Here is my navigation.html which I have kept inside shared folder.
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item ">
<a class="nav-link"
href="../Home/Home.html"
>Home</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="../Employee/CreateEmployee.html"
>Employee</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle"
id="navbarDropdown" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"
>Test</a>
<div class="dropdown-menu"
aria-labelledby="navbarDropdown">
<a
class="dropdown-item"
href="../Test/Test1/NewCQ.html"
>Create New CQ</a>
<a
class="dropdown-item"
href="../Test/Test2/Test2.html"
>Update CQ</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link"
href="../Temp/Temp.html"
>Temp</a>
</li>
</ul>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link float-right" href="../Login/Login.html"
>Logout</a>
</li>
</ul>
</div>
</nav>
This is how I have created div in respective html files
<div class="row border-bottom border-dark">
<div class="col px-0">
<!--Navigation bar-->
<div id="navigationBar">
</div>
</div>
</div>
When respective page visits I am loading that navigation.html file in shared.js from shared folder which I have imported in all the pages.
//Load navigation.html from shared folder
$(function(){
$("#navigationBar").load("../Shared/navigation.html");
});
The issue here is that
relative paths will be different from different pages, so how do i need to provide the relative paths inside navigation.html
$("#navigationBar").load("../Shared/navigation.html"); is not loading inside Test.html(its beacuse of relative path) when redirect from home.html
please let me know if am doing anything wrong here. waiting for your responses. Thanks in advance.
So, why use relative paths at all? Just use an absolute path in your links.
<a class="dropdown-item" href="/folder/Test/Test2/Test2.html">Update CQ</a>
You'll need to have some more javascript detecting the current path and figuring out the relative path from there, but that's a lot of work to do for no real gain unless you have a very specific reason to use relative paths.
I have converted my PHP dynamic website into WordPress. Whole design is perfect. But unfortunately, when I click on any href link. it just changes in URL but not displaying the related linked page. Following images clarify more good:
When clicking on link:
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="Degree Pages">
<a class="nav-link nav-link-collapse collapsed" data-toggle="collapse" href="#collapseDegreePages" data-parent="#exampleAccordion">
<i class="fa fa-fw fa-graduation-cap"></i>
<span class="nav-link-text">Degree Management</span>
</a>
<ul class="sidenav-second-level collapse" id="collapseDegreePages">
<li>Add New Degree</li>
<li>View All Degrees</li>
</ul>
</li>
result of clicking on
Add New Degree
See URL in below image:
Please help me to resolve this issue.
Thanks!
I have searched through all of the questions related to this that I can find and I just can't seem to make the text change.
Here is the dropdown in question:
Marketsource
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="nav navbar-nav">
<!--First Dropdown - This needs to be fixed. Should change the text when clicked to the store that was selected.-->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="dropdown01" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"><span id="StoreType">Store Type</span></a>
<div id="dropdownStore" class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" id="100" onclick="setStoreType(100);" >Best Buy</a>
<a class="dropdown-item" id="101" onclick="setStoreType(101);" >Office Deopt</a>
<a class="dropdown-item" id="102" onclick="setStoreType(102);" >Office Max</a>
<a class="dropdown-item" id="103" onclick="setStoreType(103);" >Staples</a>
<a class="dropdown-item" id="104" onclick="setStoreType(104);" >Costco</a>
</div>
</li>
I included the part for the navbar because the way I have it setup currently doesn't seem to quite match any of the examples I have seen.
Javascript that I have right now (I've gone through quite a few variations on something similar):
//Dropdown toggle
$(".dropdown-menu a").click(function(){
$(this).closest('.dropdown-item').children('a').text($(this).text())
});
Can someone assist me with my issue? It's not super important but it's something that would give this webapp a little more responsiveness.
Thank you!
EDIT:
I realize it's been a little bit since I asked this, but I still haven't been able to get it to work. I put the two files that are needed into a Github Gist here:
JS: https://gist.github.com/ChristopherBare/bd29ba9bc4ffea9953c3039acc03f81d
HTML: https://gist.github.com/ChristopherBare/b2770b00881b978af3b666ba67c0e4b1
I don't know whats going on with it. If someone can just look over the files and tell me where I went wrong, that would help tremendously.
P.S. There are a couple functions in the JS that don't really do anything yet because they aren't done. So just ignore that for now.
The issue is here:
$(this).closest('.dropdown-item').children('a').text($(this).text());
and th html is like:
<div id="dropdownStore" class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" id="100" onclick="setStoreType(100);" >Best Buy</a>
here .dropdown-item is under .dropdown-menu and you are using closest() selector, which search for the DOM upwards. Instead of closest try find() and also remove .children('a') as .dropdown-item is itself an anchor.
Not sure if this is what you are looking for but you could do it simply without that extra setStoreType function.(though I am not sure what you are trying to do with that function so i skipped it.)
If you wanted to the id as the store type and not the text inside the link I can add that later.
//Dropdown toggle
/*
$(".dropdown-menu a").click(function(){
$(this).closest('.dropdown-item').children('a').text($(this).text())
});
*/
function setStoreType(){
}
//Dropdown toggle
$(".dropdown-item").on("click", function(){
$("#StoreType").text($(this).text());
});
.dropdown-item:hover {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="nav navbar-nav">
<!--First Dropdown - This needs to be fixed. Should change the text when clicked to the store that was selected.-->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="dropdown01" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"><span id="StoreType">Store Type</span></a>
<div id="dropdownStore" class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" id="100">Best Buy</a>
<a class="dropdown-item" id="101">Office Deopt</a>
<a class="dropdown-item" id="102">Office Max</a>
<a class="dropdown-item" id="103">Staples</a>
<a class="dropdown-item" id="104">Costco</a>
</div>
</li>
I still haven't found an answer to this issue. I have posted some github gists so that all of the code is there. It is something to do with jQuery not working properly, or possibly the way that I have my dropdown formatted?