Ng-click need double click why - javascript

I have a little problem : ng-click working if only i do a double-click oO i don't understand, what is wrong ?
This is my controller
function MapCtrl($scope) {
if(navigator.onLine){
$scope.online = true;
} else {
$scope.offline = true;
}
/* text */
$scope.reloadText = "Reload";
$scope.reloadingText = "Reload in progress";
$scope.offlineText = "not online";
$scope.reloadMap = function() {
$scope.reload = true;
$scope.online = false;
$scope.offline = false;
}
}
and my html :
<section class="myPanel panel-padding" ng-controller="MapCtrl">
<div id="myMap">
<div class="alert alert-danger" ng-show="offline">{{offlineText}}</div>
<p ng-show="reload"><i class="fa fa-refresh fa-spin"></i> <span>{{reloadingText}}</span></p>
<div id="map" ng-show="online"></div>
<div id="mapControls">
<ul>
<li ng-hide="reload">
<button type="button" ng-click="reloadMap()" class="btn btn-primary btn-xs">{{reloadText}}</button>
</li>
</ul>
</div>
</div>
</section>
i don't understand why i need to double-click, i want it back to normal :/

reloadMap sets reload to true und your <li> has ng-hide="reload" meaning it is hidden when reload is true. So when you lick once the button should vanish. Clicking a second time or making a doubleclick makes the button visible again.

Related

Toggle menu by changing styles in Javascript

I am trying to add a toggle function to a menu.
I'm trying to do this by changing the style of the the menu in Javascript like below.
It seems to work when I click to open the menu but it doesn't work for closing the menu.
let toogleNavStatus = false;
let toogleNav = function(){
let getSidebar = document.querySelector(".nav-links");
if (toogleNavStatus === false) {
getSidebar.style.visibility = "visible";
toogleNavStatus === true;
}
else if (toogleNavStatus === true) {
getSidebar.style.visibility = "hidden";
toogleNavStatus === false;
}
}
Can someone help me figure out what the problem is with this code?
Below is the HTML
<nav class="nav-bar">
<div class="nav-center">
<div class="nav-header">
<a href="index.html" class="nav-logo">
<img src="./assets/logo.svg" alt="logo" />
</a>
<button type="button" class="btn nav-btn">
<i class="fas fa-bars" onclick="toogleNav()"></i>
</button>
</div>
<div class="nav-links">
Home
All
Contacts
<div class="nav-link nav-social">
<a href="https://www.instagram.com/">
<i class="fab fa-instagram"></i
></a>
</div>
</div>
</div>
</nav>
Thank you
You are not assigning a new state for toogleNavStatus in your JS.
It should be
toogleNavStatus = true;
toogleNavStatus = false;
not
toogleNavStatus === true;
toogleNavStatus === false;
= assigns the value, == and === compares them.

Remove class if id's the correct ID

Looking to remove a class if a certain button is clicked.
<div class="slide-container">
<section class="about" id="slide-0">
<div class="menu-total">
<nav class="nav">
<button class="nav_link home" onclick="slideTo('slide-2')">HOME</button>
<button class="nav_link about" onclick="slideTo('slide-0')">ABOUT</button>
<button class="nav_link fun-stuff" onclick="slideTo('slide-1')">FUN STUFF</button>
<button class="nav_link professional" onclick="slideTo('slide-3')">PROFESSIONAL</button>
<button class="nav_link contact" onclick="slideTo('slide-4')">CONTACT</button>
</nav>
<div class="hamburger">
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
</div>
</div>
The one I want to remove the class on is the HOME button. So "slideTo('slide-2)". If it's clicked on the others then the class is kept. I believe someone is either wrong with my loop or not getting the ID correctly of the items/
function slideTo(slideId) {
const slide = document.getElementById(slideId);
slide.scrollIntoView({
behavior: 'smooth'
})
// above this line works fine
let nonHome = document.querySelectorAll('.slide-container section');
let nonHomeID = document.getElementById('slide-2');
var i;
setTimeout(function(){
for (i=0; i < nonHome.length; i++ ){
// i believe it's somewhere here it is wrong
if (nonHome[i].id != nonHomeID){
nonHome[i].classList.add("nav-visibility");
} else{
nonHomeID.classList.remove("nav-visibility");
}
}
}, 1000)
}
If you can use jquery library, you can write in the HTML:
<button class="nav_link" data-value="home">HOME</button>
...
and then in the JS code:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // Get the data-value clicked
$(".nav_link").each(function() { // Loop through all elements of the class 'nav-link'
var v = $(this).data("value");
if (v == valueClicked) {
$(this).removeClass("nav-visibility");
} else {
$(this).addClass("nav-visibility");
}
)
}
Not much simpler, but the HTML is cleaner.
Simpler version if it is not required to browse through all buttons at each button click:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // The value of the button clicked by the user
if (valueClicked == "home") {
$(this).removeClass("nav-visibility");
console.log('remove')
} else { $(this).addClass("nav-visibility");
console.log('add')
}
});

Fix behavior of collapse/expand blocks

I use bootstrap 4 alpha 6 version. I have several blocks in my page. I want expand/collapse these blocks by clicking main button (id='expand-collapse'). Also every button has there own individual buttons which would open/close concrete block. Right know I use next js code and have strange behavior.
For example: I open first block by clicking first button, then I click main button (id='expand-collapse') to open other blocks. But in fact first block closed and other blocks opened. How to fix this problem?
HTML:
<div class="card">
<div class="card-header">
<button id='expand-collapse' type="button" data-parent="#blocks" data-toggle="collapse" data-target=".block" aria-expanded="false" aria-controls=".block">
</button>
</div>
<div class="card-block">
<div id="blocks">
<div class="list-group">
<div class="list-group-item">
<a data-toggle="collapse" href="#block-1" aria-expanded="false" aria-controls="block-1">OPEN/CLOSE FIRST</a>
<div class="collapse block" id="block-1">
FIRST BLOCK BLOCK-->
</div>
</div>
<div class="list-group-item">
<a data-toggle="collapse" href="#block-2" aria-expanded="false" aria-controls="block-2">OPEN/CLOSE SECOND</a>
<div class="collapse block" id="block-2">
SECOND BLOCK
</div>
</div>
<div class="list-group-item">
<a data-toggle="collapse" href="#block-3" aria-expanded="false" aria-controls="block-3">OPEN/CLOSE THIRD</a>
<div class="collapse block" id="block-3">
THIRD BLOCK
</div>
</div>
</div>
</div>
</div>
</div>
JAVASCRIPT:
$(function() {
$('#expand-collapse').on('click', function() {
var target = $(this).attr('data-target');
$(target).each(function() {
if ($(this).hasClass('show')) {
$(this).collapse('hide');
} else {
$(this).collapse('show');
}
});
});
});
That kind of behaviour is due to data-toggle attribute. Take that off from the main button and change the script to this-
HTML
<button id='expand-collapse' type="button" data-parent="#blocks" data-target=".block" aria-expanded="false" aria-controls=".block">
</button>
JQUERY:
$(function() {
var showAll = false;
$('#expand-collapse').on('click', function() {
var target = $(this).attr('data-target');
//console.log('showAll=' + showAll);
$(target).each(function() {
if(showAll === false) {
$(this).collapse('show');
}
else {
$(this).collapse('hide');
}
});
if(showAll === false) {
showAll = true;
}
else {
showAll = false;
}
//console.log('showAll=' + showAll);
});
});

Event firing and can't avoid happening

I'm new with Javascript, and I'm developing a webapp. I'm using quojs, a library for tactil gestures, but my problem, I think, comes from my inexperience with Javascript. The app y basically, an images gallery that generates dinamically, and lets you interact with each image. On taphold, an interactive menu merges inside the image. On singleTap it should make 2 different actions depending if we are already in "taphold state" or not. If case is we ARE IN TAPHOLD, it showld ONLY desapear the interactive menu inside the image. Then, on the next singleTap (now WITHOUT TAPHOLD STATE), it showld go inside the image. For this, i'm actually using AJAX.
The taphold function is working fine, but the problem is that the tap action, keeps firing no matter what I try to put inside the code to administrate when it must trigger or not.
I know it's a bit difficult to explain and understand, but I couldnt find the solution yet...
Here are the files I'm using.
/////////////////////////////////////// TAP.JS ///////////////////////////////////////////////
$(document).ready(function(){
var quojs = $$(document);
isHold = false;
var all_spans = $$('#mainwrapper', 'div.showhide').hide(),
tapToShowImg = false;
var mobileMenu = $$('.footer-container', '#links-fix').hide();
var mainwrapper = $$('#mainwrapper');
var homeimgscont = $$('.homeimgscont');
var environment = $$.environment();
pinchedIn = true;
pinchedOut = false;
bottomMenu = false;
fullScrn = false;
if ($$.isMobile()) {
mobile = false;
if (environment.screen.width < 500) {
$$('.homeimgscont img.image').addClass('mobile');
mobile = true;
}
}else{
mobile = false;
}
/* SINGLE TAP */
$$('.homeimgscont div').on('singleTap', function(f) {
f.cancelBubble = true;
var allimgs =$$('.image');
console.log(f);
switch(isHold){
case true:
f.cancelBubble = true;
switch(fullScrn){
case true:
$$('.imgcont').show();
allimgs.removeClass('hiddenimgs');
break;
}
$$('.image').removeClass('blur').removeClass('blurmobile');
$$('.imgcont').removeClass('fullscrn');
$$('.homeimgscont .image').removeClass('tappedimg');
mobileMenu.hide();
bottomMenu = false;
all_spans.hide();
isHold = false;
break;
case false:
var singleImg = $$(this).children('.image');
var currentImgId = singleImg.attr('id');
$$('.homeimgscont .image').removeClass('tappedimg');
$$(this).children('.image').addClass('tappedimg');
tapToShowImg = true;
f.cancelBubble = true;
if (f.stopPropagation) f.stopPropagation();
$.ajax ({
type: 'POST',
data: {imgid: currentImgId, insingleimg: 'true', user: usr, usrid: usrid},
url: 'http://agus/home/imgtap.php',
success: function(data) {
$('#main').html(data);
}
});
break;
}
});
/* HOLD */
quojs.on('hold', '.homeimgscont .image', function(e) {
var allimgs =$$('.image');
var currentimg = $$(this);
var thisSpan = currentimg.parent().find('.insideimgmenu.showhide');
var showImgMenu = currentimg.parent().find('.imgmenu.showhide');
all_spans.hide();
switch(mobile){
case true:
if (homeimgscont.hasClass('pinchedin')) {
$$('.imgcont').hide();
currentimg.parent('.imgcont').addClass('fullscrn').show();
fullScrn = true;
}
allimgs.removeClass('blurmobile').removeClass('tappedimg');
currentimg.addClass('blurmobile');
isShowing = thisSpan.show(), showImgMenu.show();
break;
case false:
if (environment.screen.width < 500) {
$$('.imgcont').hide();
currentimg.parent('.imgcont').addClass('fullscrn').show();
fullScrn = true;
allimgs.removeClass('blur').removeClass('tappedimg').addClass('hiddenimgs');
currentimg.removeClass('hiddenimgs').addClass('blur');
isShowing = thisSpan.show(), showImgMenu.show();
}else{
allimgs.removeClass('blur').removeClass('tappedimg').addClass('hiddenimgs');
currentimg.removeClass('hiddenimgs').addClass('blur');
isShowing = thisSpan.show(), showImgMenu.show();
}
break;
}
isHold = true;
e.cancelBubble = true;
e.preventDefault();
e.stopPropagation();
});
});
////////////////////////// GALLERY.PHP //////////////////////////////////////////////////
<div id="mainwrapper" class="main wrapper clearfix">
<div id="flat" class="homeimgscont pinchedin">
<div class="imgcont one">
<img src="IMAGE">
<div class="imgmenu showhide animated fadeInWithOpacity" style="display: none;"></div>
<div class="insideimgmenu showhide animated fadeInUp" style="display: none;">
<span class="titleofpublic">Here goes the title of public.</span>
<div class="icons">
<a href="#myModalEgg1" data-toggle="modal" class="eggicon">
<img src="img/egg.png" alt="egg">
</a>
<a href="#myModalOTP1" data-toggle="modal" class="hearticon">
<img src="img/otp.png" alt="otp">
</a>
<a class="fingersicon" onclick="$(this).click(function(){ $(this).children('img').attr('src','img/hand-green.png'); });">
<img src="img/like.png" alt="like">
</a>
<a href="#myModalMsg1" data-toggle="modal" class="plainicon">
<img src="img/paperplane.png" alt="comment">
</a>
</div><!-- .icons -->
<div class="addedby">
<span class="addedby-span-text">Added By</span>
<span class="addedby-span-name">Rama</span>
<div class="addedby-div-img egg" style="background: url('http://imagizer.imageshack.com/100x100f/539/7p8ZeS.jpg') center no-repeat; background-size: cover;"></div>
</div>
</div><!--.insideimgmenu.showhide-->
</div><!--.imgcont-->
<div class="imgcont two">
<img src="IMAGE">
<div class="imgmenu showhide animated fadeInWithOpacity" style="display: none;"></div>
<div class="insideimgmenu showhide animated fadeInUp" style="display: none;">
<span class="titleofpublic">Here goes the title of public.</span>
<div class="icons">
<a href="#myModalEgg2" data-toggle="modal" class="eggicon">
<img src="img/egg.png" alt="egg">
</a>
<a href="#myModalOTP2" data-toggle="modal" class="hearticon">
<img src="img/otp.png" alt="otp">
</a>
<a class="fingersicon" onclick="$(this).click(function(){ $(this).children('img').attr('src','img/hand-green.png'); });">
<img src="img/like.png" alt="like">
</a>
<a href="#myModalMsg2" data-toggle="modal" class="plainicon">
<img src="img/paperplane.png" alt="comment">
</a>
</div><!-- .icons -->
<div class="addedby">
<span class="addedby-span-text">Added By</span>
<span class="addedby-span-name">Rama</span>
<div class="addedby-div-img egg" style="background: url('http://imagizer.imageshack.com/100x100f/539/7p8ZeS.jpg') center no-repeat; background-size: cover;"></div>
</div>
</div><!--.insideimgmenu.showhide-->
</div><!--.imgcont-->
</div><!--#flat.homeimgscont.pinchedin-->
</div><!-- #mainwrapper .main.wrapper.clearfix -->
As I said, the gallery im using is quojs, thats why im using $$ before some functions. For sure i'm making some basic mistakes with the javascript.
Thanks every help since now!!!
Firstly, try not use a switch for a boolean variable. A if/else statement is more adequate and intuitive in this case.
If you want to cancel the trigger, you can just use a return false;. This will get out of the function.

Changing CSS based on service variables

I'm new to Angular, but it seems to be the "Angular way" to avoid DOM manipulation whenever possible. I am not sure if I'm taking the right approach.
I have three buttons on the bottom (next,back, and home). These get enabled and disabled by way of the actions of other controllers. For example if a text box is NULL the next button will be disabled until something is entered. I have the following:
<div ng-controller="nextBackController" class="navbar navbar-app navbar-absolute-bottom">
<div class="btn-group justified">
<i class="fa fa-arrow-left fa-navbar" ng-class="{'btn-disabled' : btnBack}"></i> Back
<a id="btnHome" ng-click="handleClick()" href="#/" class="btn btn-navbar btn-icon-only btn-bounded" ng-class="{'btn-disabled' : btnHome}"><i class="fa fa-home fa-navbar"></i> Home</a>
Next <i class="fa fa-arrow-right fa-navbar" ng-class="{'btn-disabled' : btnNext}"></i>
</div>
</div>
And now for the JS:
app.service("nxtBackClick", function($rootScope, bottomButtonWatcher) {
this.btn = "";
this.broadcast = function(btn) {
//Toggle the Next button as an example
bottomButtonWatcher.btnNext = ~bottomButtonWatcher.btnNext;
//set the btn that is clicked
this.btn = btn;
$rootScope.$broadcast('bottomBtnClick');
};
});
app.service("bottomButtonWatcher", function($rootScope) {
//Set all these to disabled
this.btnHome = true;
this.btnNext = false;
this.btnBack = true;
});
And now the controller:
//####################### - Next Back Controller ########################
app.controller("nextBackController",
function($scope, nxtBackClick, bottomButtonWatcher){
$scope.btnHome = bottomButtonWatcher.btnHome;
$scope.btnNext = bottomButtonWatcher.btnNext;
$scope.btnBack = bottomButtonWatcher.btnBack;
$scope.handleClick = function(btn) {
nxtBackClick.broadcast(btn);
};
}
);
Having both a class attribute and an ng-class attribute can be problematic. They should both be condensed into a single ng-class attribute. You are already passing an object, so just add another property to it. Setting classes to always be shown is accomplished by setting their property to true.
<div ng-controller="nextBackController" class="navbar navbar-app navbar-absolute-bottom">
<div class="btn-group justified">
<a href="#/" class="btn btn-navbar btn-icon-only btn-bounded">
<i ng-class="{'fa fa-arrow-left fa-navbar': true, 'btn-disabled' : btnBack}"></i>
Back
</a>
<a id="btnHome" ng-click="handleClick()" href="#/" ng-class="{'btn btn-navbar btn-icon-only btn-bounded':true, 'btn-disabled' : btnHome}">
<i class="fa fa-home fa-navbar"></i>
Home
</a>
<a href="#/second" class="btn btn-navbar btn-icon-only">
Next
<i class="" ng-class="{'fa fa-arrow-right fa-navbar':true, 'btn-disabled' : btnNext}"></i>
</a>
</div>
</div>
You're using $rootScope.$broadcast but nobody is listening, you need to have a scope watcher in your controller that actually controls the buttons:
//####################### - Next Back Controller ########################
app.controller("nextBackController",
function($scope, nxtBackClick, bottomButtonWatcher){
$scope.btnHome = bottomButtonWatcher.btnHome;
$scope.btnNext = bottomButtonWatcher.btnNext;
$scope.btnBack = bottomButtonWatcher.btnBack;
$scope.handleClick = function(btn) {
nxtBackClick.broadcast(btn);
};
$scope.$watch('bottomBtnClick', function(buttonVal){
$scope[buttonVal] = true;
});
}
);

Categories