Weird event binding issue on FF and Chrome - only on first click - javascript

This is on my plugin page on Git and I have two interactive demo in the web page. In one of the demo page, I have a small dialog that opens when you click on a div.
The weird issue is that this dialog is getting opened when I click on the top title that says attrchange beta . This happens only if the first click is on the title attrchange beta, clicking any other element in page fixes this issue.
The plugin page http://meetselva.github.io/attrchange/ [Fixed, use the below URL to see the problem]
http://meetselva.github.io/attrchange/index_so_issue.html
Below is the code,
<!-- The title -->
<h1 id="project_title">attrchange <span class="beta" style="text-decoration: line-through;" title="Almost there...">beta</span></h1>
<!-- Main dialog that has link to the sub-dialog -->
<div id="attributeChanger">
<h4 class="title">Attribute Changer</h4>
<p>Listed below are the attributes of the div:</p>
<div class="attrList"></div>
<div class="addAttribute text-right">add new attribute</div>
</div>
<!-- Sub-dialog -->
<div id="addOrmodifyAttr" title="Add/Modify Attribute">
<h4 class="title">Add/Modify Attribute</h4>
<p><b>Attr Name</b> <input type="text" class="float-right attrName"></p>
<p><b>Attr Value</b> <input type="text" class="float-right attrValue"/></p>
<div class="clear"> </div>
<button type="button" class="float-right close">Close</button>
<button type="button" class="float-right update">Update</button>
<div class="clear"></div>
</div>
JS:
var $attributeChanger = $('#attributeChanger');
var $attrName = $('.attrName', '#addOrmodifyAttr'),
$attrValue = $('.attrValue', '#addOrmodifyAttr'),
$attrAMUpdate = $('.update', '#addOrmodifyAttr');
//Handler to open the sub-dialog
$attributeChanger.on('click', '.addAttribute', function () {
$attrName.val('').removeClass('nbnbg');
$attrValue.val('');
$('#addOrmodifyAttr, #overlay').show();
});

The problem is the CSS applied to your #attributeChanger div.
If you look at the CSS applied to it:
#attributeChanger {
background-color: #FEFFFF;
border: 1px solid #4169E1;
color: #574353;
font-size: 0.9em;
margin: 10px;
min-height: 50px;
min-width: 150px;
opacity: 0;
padding: 2px;
position: absolute;
top: -200px;
z-index: 1;
}
You'll notice that the position is absolute, and it's positioned over your logo. So what you're clicking is actually your #attributeChanger div.
To fix it, you can hide #attributeChanger using display: none;, then use $('#attributeChanger').show(); in jQuery when it comes into actual view.

The pop up is showing because this code is running:
}).on('click', '.addAttribute', function () {
$attrName.val('').removeClass('nbnbg');
$attrValue.val('');
$('#addOrmodifyAttr, #overlay').show();
This is because the DIV with the class addAttribute is over the title DIV.
You can either move the 'addAttribute' DIV, or remove the last line of that onclick function.

That is because you element is hover your title and detect the click on himself and open(i don't know why it open, i didnt examine your entire code). But when you click anywhere else, your code is changing his position so it is not over the title.
The easiest fix is to change you #attributeChanger CSS top to -100px (that's the value when you click on the document) OR add a display : none.
EDIT : Axel answer show what I mean by "element is hover your title".

Related

why the functionality of the tabs not working?

I'm a beginner web developer learning front end development. Recently I was working on a project from front end mentor, It has a functionality which, if the name of a tab is clicked the content will be updated. I tried, But it's not working.
<section class="features">
<div>
<h2>Features</h2>
<p>Our aim is to make it quick and easy for you to access your favourite websites.
Your bookmarks sync between your devices so you can access them on the go.</p>
</div>
</section>
<section id="allTabs" class="allTabs">
<div class="btn-container">
<button class="tab-btn active" id="tab1">Simple Bookmarking</button>
<button class="tab-btn" id="tab2">Speedy Searching</button>
<button class="tab-btn" id="tab3">Easy Sharing</button>
</div>
<div class="tab active" id="tab1">
<img class="tab-img" src="./images/illustration-features-tab-1.svg" alt="">
<article>
<h3 class="tab-title">Bookmark in one click</h3>
<p class="tab-text">Organize your bookmarks however you like. Our simple drag-and-drop interface
gives you complete control over how you manage your favourite sites.</p>
<button class="tab-btn-more-info">More Info</button>
</article>
</div>
<div class="tab" id="tab2">
<img class="tab-img" src="./images/illustration-features-tab-2.svg" alt="">
<article>
<h3 class="tab-title">Intelligent search</h3>
<p class="tab-text">Our powerful search feature will help you find saved sites in no time at all.
No need to trawl through all of your bookmarks.</p>
<button class="tab-btn-more-info">More Info</button>
</article>
</div>
<div class="tab" id="tab3">
<img class="tab-img" src="./images/illustration-features-tab-3.svg" alt="">
<article>
<h3 class="tab-title">Share your bookmarks</h3>
<p class="tab-text">Easily share your bookmarks and collections with others. Create a shareable
link that you can send at the click of a button.</p>
<button class="tab-btn-more-info">More Info</button>
</article>
</div>
</section>
.tab {
display: none;
}
.tab-btn.active {
border-bottom: 3px solid hsl(0, 94%, 66%);
}
.tab.active {
display: flex;
margin-left: 4.2rem;
margin-right: 4.2rem;
}
const allTabs = document.querySelector(".allTabs");
const btnsAll = document.querySelectorAll(".tab-btn");
const articles = document.querySelectorAll(".tab");
allTabs.addEventListener("click", function (e) {
const id = e.target.dataset.id;
if (id) {
// remove active from other buttons
btnsAll.forEach(function (btn) {
btn.classList.remove("active");
e.target.classList.add("active");
});
// hide other all articles
articles.forEach(function (article) {
article.classList.remove("active");
});
const element = document.getElementById(id);
element.classList.add("active");
}
});
This is the code. Can anyone fix this.This CSS code adds styles to the active tabs and their corresponding articles. When a tab is clicked, the .active class is added to both the .tab-btn button and the .tab article, which triggers the styles specified in this CSS code.
The styles included in this code are:
border-bottom: 3px solid hsl(0, 94%, 66%);: Adds a colored bottom border to the active tab button to indicate which tab is currently selected.
margin-left: 4.2rem; margin-right: 4.2rem; display: flex;: Adds some margin to the left and right of the active tab article, and sets its display to flex to allow for more flexible positioning.
display: block; justify-content: left;: Sets the display to block for the active article and aligns its content to the left.
text-align: left; display: block; margin-top: 6rem; padding-left: 3rem;: Adds some margin and padding to the left of the active article's title and aligns it to the left.
text-align: left; padding-left: 1.4rem;: Aligns the active article's text to the left and adds some padding to its left.
display: block; margin-left: 3rem; margin-top: 2rem;: Positions the "More Info" button for the active article by adding some margin to its left and top.
This is a piece of HTML code that defines a section with the id "alltabs" and the class "allTabs". Inside this section, there is a container with three buttons that have the class "tab-btn" and the ids "tab1", "tab2", and "tab3". The first button has the class "active" which indicates it is the default active tab.
Each button represents a feature and when a user clicks on one of them, it activates the corresponding tab, which has the same id as the button. The tab contains an image and an article with a title, a paragraph of text, and a button with the class "tab-btn-more-info".
The purpose of this code is likely to create a user interface for a website or application that allows users to manage their bookmarks by providing features such as one-click bookmarking, intelligent search, and easy sharing. The tab system provides a way to present and switch between different features without cluttering the interface.
The only mistake that you are doing is you are using id instead of data-id on the buttons so it should be
CODESANDBOX DEMO
<div class="btn-container">
// CHANGE data-id instead of id
<button class="tab-btn active" data-id="tab1">Simple Bookmarking</button>
<button class="tab-btn" data-id="tab2">Speedy Searching</button>
<button class="tab-btn" data-id="tab3">Easy Sharing</button>
</div>

how to disable click outside a particular div

Here is the sample code. I want to disable the click outside the search id. Just like we need in pop-up to disable outside click
<body>
You can search here
<div id="search">
Search
<input type="text" name=search><button>search</button>
</div>
</body>
You can create a div with fixed position that spans the entire screen and place what you want to be able to click inside of it, making all the clicks outside that element actually be on that "empty" div.
.disable-outside-clicks {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 10000;
}
.enabled-clicks {
width: 200px;
margin: 0 auto;
}
<div>
<button>This button will not work</button>
</div>
<div class="disable-outside-clicks">
<div class="enabled-clicks">
<button>This button will work</button>
</div>
</div>
You can use the :not() CSS selector combined with the .preventDefault() JS function :
$('*:not(#search)').click(function(e){
e.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I don't work !
<div id="search"></div>
maybe the css property pointer-events is the thing you are looking for.
add a class to the body element if the pop up is opened. let's say you will add the class .popup to the body element if the pop up is visible. then you can do it like this in css:
body.popup *:not(#search) {
pointer-events: none;
}
this means, that every element (*) in the body element with the class .popup, except the element #search is not clickable.

Cannot get push menu inline with Bootstrap

I'm using Bootstrap as UI framework, what I'm trying to do is make a push menu on the left. Actually, I almost achieve this result, but there are some bugs on the system. In particular, I'm not able to get the menu inline. See the code for more details:
HTML
<div id="calendar-wrapper">
<div class="container-fluid">
<div class="row">
<div id="resource-bar" class="sidenav col-sm-2">
<h4>Resource</h4>
<div class="input-group">
<input type="text" placeholder="Search resource"
class="form-control resource-filter"/>
<span class="input-group-btn">
<button class="clear btn btn-default clean-resource btn-danger" type="button">
<span class="glyphicon glyphicon-remove"></span>
</button>
</span>
</div>
<div id="popover-content" hidden></div>
</div>
<div id="calendar-container" class="col-sm-10">
<div id="calendar" class="well"></div>
</div>
</div>
</div>
</div>
<br><br><br>
<button type="button" id="show" >Show</button>
<button type="button" id="hide" >Hide</button>
Note that the html above is adapted for a fiddle example.
CSS
.sidenav
{
background-color: azure;
height: 100%;
width: 0;
z-index: 1;
top: 0;
left: 0;
overflow-x: hidden;
transition: 0.5s;
}
#calendar-container
{
background-color: whitesmoke;
transition: margin-left .5s;
padding: 16px;
}
JS
$(document).ready(function()
{
var resourceContainer = $('#resource-bar');
var calendarContainer = $('#calendar-container');
$('#show').click(function()
{
resourceContainer.css('width', '250px');
calendarContainer.css('margin-left', '250px');
});
$('#hide').click(function()
{
resourceContainer.css('width', '0px');
calendarContainer.css('margin-left', '0px');
});
})
The result when the menu on the left is closed:
Seems that both divs are inline, the problem occurs when I press show button and the menu appears:
BUG actually noticed:
When the menu is opened I get the divs in two line instead of one row
Adding the class col-sm-2 to resource-bar the overflow-x: hidden; doesn't working, in fact, seems that the menu is visible when it should be closed.
col-sm-2 does not go in another line when the minimum resolution of the screen doesn't have enough space in width.
Someone could help me to fix this issues? Thanks. JSFIDDLE.
Edited to another workaround which wouldn't affect bootstrap grid:
With this setup sidebar would be absolute, since it's out of viewport and you set it to a fixed width (250px), using the grid wouldn't be necessary.
Visible input will not overflow once sidebar shows.
Raised buttons above sidebar.
Note the HTML structure was tweaked.
$(document).ready(function() {
var resourceContainer = $('#resource-bar');
var calendarContainer = $('#calendar-container');
$('#show').click(function() {
resourceContainer.css('width', '250px');
calendarContainer.css('margin-left', '250px');
});
$('#hide').click(function() {
resourceContainer.css('width', '0px');
calendarContainer.css('margin-left', '0px');
});
})
div.sidenav {
background-color: azure;
height: 100%;
width: 0;
z-index: 1;
top: 0;
left: 0;
overflow-x: hidden;
transition: 0.5s;
/* added absolute to sidenav since it will have fixed width anyways */
position: absolute;
}
#calendar-container {
background-color: whitesmoke;
transition: margin-left .5s;
padding: 16px;
/* this is just to vertically align with sidebar input */
padding-top: 36px;
}
button {
position: relative;
z-index: 2;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div id="calendar-wrapper">
<div class="container-fluid">
<div class="row">
<div id="calendar-container" class="col-sm-12">
<div id="calendar" class="well"></div>
</div>
<div id="resource-bar" class="sidenav">
<h4>Resource</h4>
<div class="input-group">
<input type="text" placeholder="Search resource" class="form-control resource-filter" />
<span class="input-group-btn">
<button class="clear btn btn-default clean-resource btn-danger" type="button">
<span class="glyphicon glyphicon-remove"></span>
</button>
</span>
</div>
<div id="popover-content" hidden></div>
</div>
</div>
</div>
</div>
<br>
<br>
<br>
<button type="button" id="show">Show</button>
<button type="button" id="hide">Hide</button>
You're issue lies with the mix of bootstrap and your own JavaScript generated style. It seems you already have knowledge of the Bootstrap Grid layout, but to reinforce, https://v4-alpha.getbootstrap.com/layout/grid/ will tell you that there are 12 columns in a row.
Each column is styled by Bootstrap to a set width with set margins in between. You've have all 12 columns filled up in your row. As you add an additional margin to your already-filled-up calendarContainer column, it will pop out of the row.
Therefore, the easiest way to achieve what you want without affecting any other styles is too make your column smaller and reduce the amount of 'margin-left' you push on the column like so https://jsfiddle.net/Zeenglishking/DTcHh/28837/
<div id="calendar-container" class="col-sm-8">
<div id="calendar" class="well"></div>
</div>
$('#show').click(function()
{
resourceContainer.css('width', '250px');
calendarContainer.css('margin-left', '50px');
});
Also, as you say "seems infact that the menu is even visible also when is closed.", the menu is indeed visible. This is again down to the fact of the bootstrap styling of the grid-layout. If you can figure out what styles are creating this issue (F12), you can override them using "something:!important". https://css-tricks.com/snippets/css/style-override-technique/ . Otherwise, find another way. If you mess around with css positioning elements too much, it's easy to get lost and jumbled with the rest of your code.
EDIT (in regard to comment):
What needs to be used in addition to this is 'col-xs-**' with a smaller size column, allowing for a responsive design and for it to work on the smaller viewports such as the one in JSFiddle. I have updated my fiddle to include
col-xs-1
and
col-xs-4
on resource-bar and calendar-container respectively. This will change the size of the column, upon resize of the screen/viewport to ensure it doesn't drop down on extra-small viewports. More info at http://getbootstrap.com/css/#grid-options
Upon using Bootstrap framework you almost acquire yourself to a certain standard. Shortcuts in fixing this can cause problems with other elements. You're probably best to read more into it before chucking random positioning in to fix certain elements on a page.

Angular - detect click background div but not on divs within

On ollynural.github.io, in the portfolio page i'm trying to simulate a pop-up div giving more information on the project you clicked on. To go back off the pop-up, I've added an ng-click so when you click on the main portfolio-pop-up container, the pop-up is removed.
Is it possible to only have the parts of the portfolio-pop-up div that are exposed (not on the photo nor the description white box) removing the main div once clicked? So you can click freely on the picture and the white box
<div class="portfolio-pop-up container" ng-click="losePortfolioFocus()">
<div class="row">
<div class="col-xs-12">
<img class="portfolio-image portfolio-image-popup" src="{{portfolioImageClass}}">
</div>
<div class="col-xs-12 pop-up-container">
<div class="pop-up-row">
<div class="col-xs-9" style="background: red">
<h1>
{{portfolioTitle}}
</h1>
<p>
{{portfolioDescription}}
</p>
</div>
<div class="col-xs-3" style="background: cyan">
Click me
<div ng-repeat="tech in portfolioTech">
{{tech}}
</div>
</div>
</div>
</div>
</div>
</div>
JS
$scope.losePortfolioFocus= function() {
angular.element('.portfolio-pop-up').css("display", "none");
}
CSS
.portfolio-pop-up {
display: none;
position: absolute;
width: 100%;
height: 100%;
/* color with alpha transparency */
background-color: rgba(0, 0, 0, 0.70);
top: 0;
left: 0;
bottom: 0;
right: 0;
}
Any help would be appreciated, can post more css or code if needed
You can stop the propagation of the click event on the element that wraps the pop-up's content like this:
<div class="portfolio-pop-up container" ng-click="losePortfolioFocus()">
<div class="row" ng-click="$event.stopPropagation()">
...
</div>
</div>
This way the clicks inside the popup will not trigger the losePortfolioFocus() handler.
I suggest you crawl up the event chain from you event' target and check whether your pop-up-container is in there. This way, you'll have a way to distinguish click in the pop-up or out of it.

Collapse/Expand a content box with a toggle

I go right to the point, I have a few boxes that I want them to be expanded and collapsed with a toggle located in their headers.
This toggle is an anchor tag which has a sprite background, the top part of this sprite image is pointing at top, and bottom section is pointing at down. You can guess what they mean and I want their state to be changed (first one for collapse and second one for expand)
The structure of the boxes are something like this :
<section class="box2">
<header class="box-head">
<div class="box-title fr">
<span class="box-icon"></span>
<h3 class="box-title-text">Title Title</h3>
</div>
<a class="box-toggle fl active" href="#">A</a>
<br class="cfx" />
</header>
<div class="box-content">
<img src="img/chart-1.png" alt="" />
//Content or collapsing data goes here
</div>
</section>
And I used one of the most straight forward ways to achieve this effect. You can see the following CSS and jQuery code below. (I chose active class as default when the icon is pointing at top)
JS :
<script type="text/javascript">
$("a.box-toggle").toggle(function(){
$(this).addClass("active");
}, function () {
$(this).removeClass("active");
});
//Slide up and down on click
$("a.box-toggle").click(function(){
$(this).next("div.box-content").slideToggle("slow");
});
});
</script>
CSS :
.widget-toggle {
display: block;
overflow: hidden;
text-indent: -9999px;
width: 18px; height: 9px;
margin-top: 15px;
margin-left: 13px;
background: url(../img/sidebar-arrows.png) no-repeat 0 -18px;
}
.widget-toggle.active {
background: url(../img/sidebar-arrows.png) no-repeat 0 0;
}
Thanks for your huge help :)
Edit No. #1 :
Thanks to #Recode , their tip worked just fine, But according to what I explained and you can see in this picture. I wanna show the state of this with an Icon
Active is pointing at top and Inactive is pointing at bottom, when I want the box to be collapsed I'm showing "Active" and when I want the box to be expanded I'm showing "Inactive" .
With this code I managed to show active at default (I set the class of each box to active manually, if there is a better way to set the default class to active or whatever else please note.)
When I click on it, box collapses and the Icon transitions to Inactive state. And When I click again box expands but the Icon stays in the same state (Inactive and pointing at bottom).
And after clicking :
Here is the Code :
$("a.box-toggle").click(function(){
$(this).addClass("active");
}, function () {
$(this).addClass("inactive");
});
Thanks a lot, Again.
Just use this:
$(document).ready(function() {
//Slide up and down on click
$("a.box-toggle").click(function(){
$(this).toggleClass('inactive');
$(this).parent().next("div.box-content").slideToggle("slow");
});
});
http://jsfiddle.net/Recode/DLxaB/
updated fiddle: http://jsfiddle.net/Recode/DLxaB/1/
Try this: FIddle
jQuery code:
$("a.box-toggle").on('click', function () {
$('div.box-content').slideToggle(200).toggleClass('active');
});
.slideToggle() .toggleClass()

Categories