Ui Bootstrap (angularjs) sidenav doesn't work as intended - javascript

I have a problem with a sidenav which I'm trying to create for one of my projects. My intention is to create a side menu which pushes the content to the right when is opened and when closed the content should move back to the left, sort of a toggle function. For some reason my ternary operator doesn't work as intended.
Here is my snippet:
<!doctype html>
<html lang="en">
<html ng-app="uiBootstrapBlog">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-animate.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-sanitize.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="navbarCtrl">
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<ul class="nav navbar-nav">
<li style="font-size:30px; cursor:pointer;color:white" ng-click="isCollapsedHorizontal = !isCollapsedHorizontal" ng-model="singleModel" uib-btn-checkbox>☰</li>
</ul>
</div>
</nav>
<div style="position: fixed; width: 230px">
<div class="horizontal-collapse" uib-collapse="isCollapsedHorizontal" horizontal style=" margin-top: 50px !important; min-height: 150px; max-height: 80vh; background: gray; color: black; padding-top: 25px;" >
</div>
</div>
<div style="position: absolute; top: 60px; transition: left .5s;" id="main">grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br></div>
</div>
</body>
</html>
<script>
var uiBootstrapBlog = angular.module('uiBootstrapBlog', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
uiBootstrapBlog.controller('navbarCtrl', function($scope) {
$scope.singleModel = false;
var menuSlide = document.getElementById("main");
$scope.singleModel === false ? menuSlide.style.left = "250px" : menuSlide.style.left = "0";
});
</script>

It does not work because the codes gets called only once after the initialisation. Follow these three steps to fix the issue
Define a function and put isCollapsedHorizontal and the last two lines of code inside of it.
Your ternary operator has also an issue. Assign the variable that gets changed to the result of it.
Call the function inside the controller and with the ng-click.
$scope.slideMenu = function() {
$scope.isCollapsedHorizontal = !$scope.isCollapsedHorizontal;
var menuSlide = document.getElementById("main");
menuSlide.style.left = $scope.singleModel ? "250px" : "0";
}
$scope.slideMenu();
<li style="font-size:30px; cursor:pointer;color:white" ng-click="slideMenu()" ng-model="singleModel" uib-btn-checkbox>☰</li>

Related

Not connect js to html

When hovering over the picture, hide information about the link that will appear at the bottom left. When adding this script, the image became unclickable. I think the main problem is the incorrect connection of the js file or the execution of this script. I have added the code of 3 files below
openUrl(url: string): void {
window.open(url, '_blank');
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Roshan Timing</title>
<script src="eel.js"></script>
<link rel="icon" type="image/ico" href="/Roshan.ico"></link>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<!-- TIMER -->
<p class="timer">Timer</p>
<!-- CHAT(INPUT) -->
<!-- created by dankYbat -->
<div class="about_right">
<div class="text_wrap">
<p class="noselect">created by dankYoff</p>
</div>
<!--Connect js to tage image -->
<div class="image_wrap">
<a><img src="github.svg" (click)="openUrl('https://github.com/dankYoff')" width="50"></a>
</div>
</div>
</body>
</html>
You can not use openUrl(url: string): void in a *.js file, looks like you want to use TypeScript. If you want to create a faster vanilla typescript project you can use vite.
Anyway the a solution can be this:
const imgProfile = document.querySelector('#img-profile');
const openUrl = (url) => {
window.open(url, '_blank');
};
imgProfile.addEventListener('click', () => {
openUrl('https://github.com/dankYoff');
});
.img-profile {
cursor: pointer;
}
.img-profile img {
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
transition: 0.3s;
}
.img-profile img:hover {
transform: scale(1.1);
}
<a class="img-profile" id="img-profile">
<img src="https://cdn.pixabay.com/photo/2022/09/16/13/07/woman-7458584_960_720.jpg" />
</a>

Hiding classes by clicking outside

I made a script that when I click on the container it hides a list. However, what I have been trying to do is that the list should hide when clicking outside the container and not inside. I have been looking for answers but nothing really worked for me as I use classes. Does someone know a solution?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<title>Hiding the list</title>
</head>
<body>
<h1>Hiding the list</h1>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
</body>
</html>
<style>
.list {
width: 50%;
height: 100%;
background-color: #f2f2f2;
}
li {
}
</style>
<script>
function hide_list() {
var children = this.children;
for (let i = 0; i < children.length; i++) {
children[i].style.display = "none";
}
}
document.querySelectorAll(".list").forEach(function (elem) {
elem.addEventListener("click", hide_list);
});
</script>

Set different timers in javascript to show divs

I have this code that makes me able to set a timer to show/hide divs, but i wouls like to adapt it to be able to set different timers, i mean some divs for 2000ms then others for 1500ms. But i don't know how to do as i never code in JS, I tried to adapt idangerous but i cannot make it work either.
EDIT : I FOUND A WAY BY ADDING "IF" STATEMENT IN THE JS ! But still i have like 100 divs, it's a little bit "bad coded" to do it like this in my opinion.
so here is the js :
<script>
$(document).ready(function() {
var images = $('.images')
current = 0;
images.hide();
Rotator();
function Rotator() {
if (current == 1 || current == 3){
$(images[current]).fadeIn('slow').delay(2500).fadeOut('slow');
}
else{
$(images[current]).fadeIn('slow').delay(10).fadeOut('slow');
}
$(images[current]).queue(function() {
current = current < images.length - 1 ? current + 1 : 0;
Rotator();
$(this).dequeue();
});
}
});
</script>
and in the HTML :
<div id="imagescollection">
<div class="images"><!----- 1 ------>
<div class="pam _3-95 _2ph- _2lej uiBoxWhite noborder"><div class="_3-95 _2pim _2lek
_2lel">Anne faure (Brouteur)</div>
<div class="_3-95 _2let"><div><div></div><div>Coucou</div><div></div><div></div></div>
</div>
<div class="_3-94 _2lem">15 janv. 2022 à 08:29</div></div></div>
<div class="images"><!----- 73 ------>
<div class="pam _3-95 _2ph- _2lej uiBoxWhite noborder"><div class="_3-95 _2pim _2lek
_2lel">Sir Perceval</div>
<div class="_3-95 _2let"><div><div></div><div>Salut</div><div></div><div></div></div>
</div>
<div class="_3-94 _2lem">15 janv. 2022 à 08:56</div></div></div>
<div class="images"><!----- 72 ------>
<div class="pam _3-95 _2ph- _2lej uiBoxWhite noborder"><div class="_3-95 _2pim _2lek
_2lel">Anne faure (Brouteur)</div>
<div class="_3-95 _2let"><div><div></div><div>Comment tu vas</div><div></div><div></div>
</div></div>
<div class="_3-94 _2lem">17 janv. 2022 à 07:30</div></div></div>
<div class="images"><!----- 71 ------>
<div class="pam _3-95 _2ph- _2lej uiBoxWhite noborder"><div class="_3-95 _2pim _2lek
_2lel">Sir Perceval</div>
<div class="_3-95 _2let"><div><div></div><div>On se connaît?</div><div></div><div></div>
</div></div>
<div class="_3-94 _2lem">17 janv. 2022 à 11:09</div></div></div>
</div>
Is there a way to adapt this code to be able to set different times for my divs ? Thank you in advance !
If you want to render more divs you can try out this way
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="./script.js"></script>
</body>
</html>
style.css
.reveal{
padding: 2rem;
background-color: pink;
margin: 1rem;
transform: translateX(150%);
transition: all 0.5s ease-in-out;
}
body{
overflow-x: hidden;
}
script.js
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
for(var i=0; i<100; i++){
var div = document.createElement('div');
div.classList.add('reveal')
div.innerText = `This is div ${i}`; // here u can use other array which contains the contents
document.body.appendChild(div);
}
var reveals = document.getElementsByClassName('reveal');
for(var i=0; i<reveals.length; i++){
((div)=>{
setTimeout(()=>{
div.style.transform = 'translate(0)';
}, 1000*(i+1));
})(reveals[i]);
}
console.log(reveals)
Its simple
All that you have to do is set different timeouts and change style as you like in the function passed as argument to this setTimeout (reference)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="div1">This is div 1</div>
<div id="div2">This is div 2</div>
<script src="./script.js"></script>
</body>
</html>
style.css
#div1{
padding: 2rem;
background-color: grey;
font-weight: bold;
margin: 1rem;
transform: translateX(150%);
transition: all 0.5s ease-in-out;
}
#div2{
padding: 2rem;
background-color: pink;
margin: 1rem;
transform: translateX(150%);
transition: all 0.5s ease-in-out;
}
body{
overflow-x: hidden;
}
script.js
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
setTimeout(()=>{div1.style.transform = 'translateX(0)'},1000)
setTimeout(()=>{div2.style.transform = 'translateX(0)'},2000)

classlist.toggle() with force false still adding class

I have a side navigation bar with a button to toggle showing just the icons or to show the icons and the text. There are multiple different HTML pages that share this nav bar, so I needed to save the nav bar's state for when you switch to each (Dashboard to Items, Contacts to Dashboard, etc). I do this using the follow code:
var navBar = document.querySelector(".side-bar");
var toggle = document.querySelector(".nav-toggle");
window.onload = () =>
{
let isClosed = localStorage.getItem("navState");
navBar.classList.toggle("nav-is-closed", isClosed);
}
toggle.addEventListener("click", () =>
{
let isClosed = navBar.classList.toggle("nav-is-closed");
localStorage.setItem("navState", isClosed);
});
.side-bar {
position: relative;
background-color: var(--default-back-color);
min-width: 200px;
}
.nav-is-closed {
min-width: inherit;
}
.nav-is-closed a h2 {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="resources/css/styles.css">
<!--Google Fonts-->
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Neucha&family=Poppins:wght#300&display=swap" rel="stylesheet">
<title>Rucksack</title>
</head>
<body>
<header>
<div>
<img src="resources/images/rucksack.png" alt="">
<h1 class="title">Rucksack</h1>
</div>
<div>
<a class="smaller-icon" href="#"><img src="resources/images/gear.png" alt=""></a>
<img src="resources/images/blue-profile.png" alt="">
</div>
</header>
<main>
<section id="main-section">
<nav class="side-bar">
<a class="selected-nav" href="dashboard"><img src="resources/images/house-icon.png" alt=""><h2>Dashboard</h2></a>
<img src="resources/images/item-icon.png" alt=""><h2>Items</h2>
<hr class="nav-break">
<img src="resources/images/contacts-icon.png" alt=""><h2>Contacts</h2>
<hr class="nav-break">
<img src="resources/images/reports-icon.png" alt=""><h2>Reports</h2>
<div class="nav-toggle"><img src="resources/images/arrow-icon.png" alt=""></div>
</nav>
<div class="content">
<strong>Content</strong>
</div>
</section>
</main>
<script src="shell-controls.js"></script>
</body>
</html>
Everything works fine, except when you move to a new page while the nav is open. It closes even though in window.onload, isClosed is false. As far as I know, toggle with force set to false removes the class, but in this case it's still adding it.
As Kaiido said, isClosed was being pulled from localStorage as a string, which caused toggleClass to think the string of "false" was truthy, therefore still adding the 'nav-is-closed' class. Adding JSON.parse when getting isClosed and adding JSON.stringify when setting isClosed in localStorage solves the problem.

Resizable split screen divs using jquery UI

I have a design in mind that involves a split panel view in html, similar to a winforms split panel. I've been expirimenting with jQuery UI - Resizable and I like the function, I just can't seem to co-ordinate the resizing of the two divs. The problem with the current code is that the two divs resize away from each other, not with one following the other. How can I make the two divs work together?
<html>
<head>
<title>Test</title>
<link rel="stylesheet" type="text/css" href="css/custom.css" />
<link rel="stylesheet" type="text/css" href="css/superfish.css" media="screen">
<link rel="stylesheet" type="text/css" href="css/jquery-ui-1.8.10.custom.css" media="screen">
<script type="text/javascript" src="script/jquery-1.5.1.js"></script>
<script type="text/javascript" src="script/superfish.js"></script>
<script type="text/javascript" src="script/jquery-ui-1.8.10.custom.min.js"></script>
<script type="text/javascript">
// initialise plugins
$(function(){
try {
$('ul.sf-menu').superfish();
//set up divs
$('#Content').resizable({ handles: 'e', alsoResize: $('#Attributes')});
}catch(ex){
alert(ex.message);
}
});
</script>
</head>
<body>
<div id="Header">
<div id="Menu">
<ul class="sf-menu" id="nav">
<!-- Snip menu -->
</ul>
</div>
</div>
<div id="Middle">
<div id="Content" class="ui-widget-content">This is where the view is.<br/>
Imagine an image here ...
<br/>
<br/>
<br/>
</div>
<div id="Attributes" class="ui-widget-content">
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
</div>
</div>
<div id="FootBreak"/>
<div id="Footer">
Help
</div>
</body>
</html>
I have worked out a reasonable hack, using the resize event.
<script type="text/javascript">
var WIDTH_ATTR = 'initWidth';
// initialise plugins
$(function(){
try {
$('#Content').resizable({ handles: 'e', resize: resizeAttr });
$('#Content').attr(WIDTH_ATTR, $('#Content').width());
$('#InfoPanel').attr(WIDTH_ATTR, $('#InfoPanel').width());
}catch(ex){
alert(ex.message);
}
});
function resizeAttr(event, ui){
var change = ui.size.width - $('#Content').attr(WIDTH_ATTR);
$('#InfoPanel').width($('#InfoPanel').attr(WIDTH_ATTR) - change);
};
</script>
I'm still open to cleaner answers from others...
I am not sure if this meets the requirements, but ExtJS handles split panes with ease and works cross-browser. For example, see this RSS feed client in ExtJS. Be aware the ExtJS has commercial licensing restrictions if your intent is to sell your product.
Here is an example with a horizontal split (one top div, one bottom div), maybe slightly more minimalistic:
HTML:
<html>
<head>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div id="div1">1st</div>
<div id="div2">2nd</div>
</body>
</html>
CSS:
#div1, #div2 {
position: absolute;
left: 0;
right: 0;
outline: solid 1px #ccc; /* just for making the divs visible */
margin: 5px; /* just for making the divs visible */
}
#div1 {
height: 100px;
top: 0;
}
#div2 {
top: 110px;
bottom: 0;
}
JavaScript:
$('#div1').resizable({
handles: 's',
resize: resizeEventHandler
});
function resizeEventHandler(event, ui){
var new_height = ui.size.height;
$('#div2').css('top', new_height + 10);
}
See demo here.

Categories

Resources