Bootstrap dropdown not closing on clicking outside - javascript

In my application I have added close button side bootstrap dropdown.
Clicking on that close button I have to close that dropdown.
This is working properly, but when I click anywhere outside dropdown, dropdown is not closing
Here is Fiddle : goo.gl/3RAkBw
Can any one tell me how can I close

You can try this:
$(document).on('click',function(){
$('#layers').hide();
})

$( document.body ).on( 'click', '.dropdown-menu li', function( event ) {
var $target = $( event.currentTarget );
$target.closest( '.btn-group' )
.find( '[data-bind="label"]' ).text( $target.text() )
.end()
.children( '.dropdown-toggle' ).dropdown( 'toggle' );
return false;
});
$(window).on('click', function () {
$( '#layers' ).css( 'display','none' );
});
.btn-input {
display: block;
}
.btn-input .btn.form-control {
text-align: left;
}
.btn-input .btn.form-control span:first-child {
left: 10px;
overflow: hidden;
position: absolute;
right: 25px;
}
.btn-input .btn.form-control .caret {
margin-top: -1px;
position: absolute;
right: 10px;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"/>
<br/><br/>
<div class="panel panel-default">
<div class="panel-body">
<div class="btn-group">
<button onclick="$('#layers').toggle();" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span data-bind="label">Select One</span> <span class="caret"></span>
</button>
<ul id="layers" class="dropdown-menu" role="menu">
<span><img class="close_img dropdown-toggle" onclick="$('#layers').toggle();" data-toggle="dropdown" src="https://www.eonenergy.com/images/icons/close.gif" alt="CloseWindow" title="Close" style="margin-top:5px;margin-right:5px" /></span>
<li>Item 1</li>
<li>Another item</li>
<li>This is a longer item that will not fit properly</li>
</ul>
</div>
</div>
</div>
<br/><br/>
You can set click event on window like, (if you have to hide only on click of anywhere on window)
$(window).on('click', function () {
$( '#layers' ).css( 'display','none' ); //$( '#layers' ).hide();
});

Simply use the below jquery code
$(document).click( function () {
$("#layers").css("display", "");
});
or use
$(document).click( function () {
$("#layers").toggle();
});

"show" class is added when the dropdown is clicked so to hide the dropdown menu you have to remove it:
$(document).on('click',function(){
$('#user-menu').removeClass('show');
})

Related

Is there a more efficent way to do this?

How can I achieve this code easier or with less lines of code?
I'm curious if it can be done easier and/or more efficently. Because I feel like there is too much repetition in this, so there must be an easy way.
And I'm not only planning to make 4 of this but like 20-30, so performance is a key aspect.
Jquery:
$( document ).ready(function() {
$( "#q1" ).click(function() {
$( "#a1" ).slideToggle( "slow", function() {});
if ($(this).hasClass('on')){
$(this).removeClass('on');
}else{
$(this).addClass('on');
}
});
$( "#q2" ).click(function() {
$( "#a2" ).slideToggle( "slow", function() {});
if ($(this).hasClass('on')){
$(this).removeClass('on');
}else{
$(this).addClass('on');
}
});
$( "#q3" ).click(function() {
$( "#a3" ).slideToggle( "slow", function() {});
if ($(this).hasClass('on')){
$(this).removeClass('on');
}else{
$(this).addClass('on');
}
});
$( "#q4" ).click(function() {
$( "#a4" ).slideToggle( "slow", function() {});
if ($(this).hasClass('on')){
$(this).removeClass('on');
}else{
$(this).addClass('on');
}
});
});
HTML:
<div id="faq_content">
<div class="faq_box">
<div class="questions" id="q1">
<span>xyz</span>
</div>
<div class="answers" id="a1">
<span>xyz</span>
</div>
</div>
<div class="faq_box">
<div class="questions" id="q2">
<span>xyz</span>
</div>
<div class="answers" id="a2">
<span>xyz</span>
</div>
</div>
</div>
The easiest way that I can think of, given your HTML structure, is the following:
$(document).ready(function() {
// selecting all the elements you need to work with,
// and binding the anonymous function of the click()
// method as the event-handler:
$("#q1, #q2").click(function() {
// here $(this) will refer to the element that fired the
// click event, from that element:
$(this)
// we navigate to the next-sibling element matching the
// supplied selector:
.next('.answers')
// we use the slideToggle() method to show/hide the element,
// using an Arrow function to compose the anonymous
// function so that we can use the same this (and therefore
// $(this)) as the outer function:
.slideToggle('slow', () => {
// here $(this) still refers to the clicked element, as
// Arrow functions don't establish their own 'this'; and
// we use the toggleClass() method to add, or remove, the
// supplied class based on whether it already exists on
// the element:
$(this).toggleClass('on');
});
// here we again call the click() method, without arguments, in
// order to fire the click event on page-load (which, in this
// context will cause the answers to be hidden on page-load):
}).click();
});
$(document).ready(function() {
$("#q1, #q2").click(function() {
$(this).next('.answers').slideToggle('slow', () => {
$(this).toggleClass('on');
});
}).click();
});
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.faq_box {
border: 1px solid #000;
margin: 0.2em auto;
width: 80vw;
}
.questions {
background-color: #ffff;
border: 1px solid transparent;
border-bottom-color: #000;
cursor: pointer;
font-size: 1.2em;
font-weight: bold;
transition: background-color 0.3s linear;
}
.questions::before {
content: attr(id) ': ';
text-transform: capitalize;
}
.answers::before {
content: attr(id) ': ';
}
.on {
background-color: #0f06;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="faq_content">
<div class="faq_box">
<div class="questions" id="q1">
<span>xyz</span>
</div>
<div class="answers" id="a1">
<span>xyz</span>
</div>
</div>
<div class="faq_box">
<div class="questions" id="q2">
<span>xyz</span>
</div>
<div class="answers" id="a2">
<span>xyz</span>
</div>
</div>
</div>
References:
click().
next().
slideToggle().
$(document).ready(function(){
var qClasses = $('.q');
qClasses.on('click', function(){
var $this = $(this);
var aIds = $this.data('id');
$(aIds).slideToggle("slow");
$this.toggleClass("on");
});
});
Since all the #q1,#q2... are doing the same thing on click you can utilize the classes for this and with <div id="#q1" class="q" data-id="#a1" ></div> you can refer to the id on click of the q classes. Also, you can define the initial state of #q1 or q classes as there are only two states with class "on" or without it so the default state can be defined directly in HTML instead of checking in the JS. like: <div id="#q1" class="q on" data-id="#a1"></div>
Because all your handlers look the same, you can create a function which returns a function:
function createHandler(selector) {
return function() {
$( selector ).slideToggle( "slow", function() {});
if ($(this).hasClass('on')){
$(this).removeClass('on');
}else{
$(this).addClass('on');
}
}
}
and use it like this:
$( "#q1" ).click(createHandler("#a1"))
To find out more about this principle search for "Higher-Order Functions" and "Closures"

Change background when you click a picture

I basically want for the visitor to be able to click on a picture and for the background to change :
<div class="box1">
<ul id="bgbg">
<li id="bg1"> </li>
<li id="bg2"> </li>
<li id="bg3"> </li>
</ul> </div>
$(document).ready(function() {
$( "#bgbg > li" ).click(function() {
$( 'body' ).removeClass('bg1 bg2 bg3');
$( 'body' ).addClass( $(this).attr('id') );
});
});
But it's not working ...
EDIT : It was due to the jQuery’s Compatibility Mode of wordpress - Link
jQuery(document).ready(function() {
jQuery( "#bgbg > li" ).click(function() {
jQuery( 'body' ).removeClass('bg1 bg2 bg3');
jQuery( 'body' ).addClass( jQuery(this).attr('id') );
});
});
I belive you have mistake in selector. It should be:
$(document).ready(function() {
$( ".box1 li" ).click(function() { //check selector
$( 'body' ).removeClass('bg1 bg2 bg3');
$( 'body' ).addClass( $(this).attr('id') );
});
});
Here's a working example
$(document).ready(function() {
$( "#bgbg > li" ).click(function() {
$( 'body' ).removeClass('bg1 bg2 bg3');
$( 'body' ).addClass($(this).attr('id')) ;
alert($(this).attr('id'));
});
});
#bg1{
width:60px;
height:60px;
background:url('https://www.w3schools.com/css/trolltunga.jpg');
background-size: auto 100%;
background-repeat: no-repeat;
background-position: left top;
}
#bg2{
width:60px;
height:60px;
background:url('http://hdwallpaperfun.com/wp-content/uploads/2015/07/Big-Waves-Fantasy-Image-HD.jpg');
background-size: auto 100%;
background-repeat: no-repeat;
background-position: left top;
}
#bg3{
width:60px;
height:60px;
background:url('http://i.dailymail.co.uk/i/pix/2014/12/19/2429637D00000578-0-image-a-284_1419003100839.jpg');
background-size: auto 100%;
background-repeat: no-repeat;
background-position: left top;
}
.bg1{
background:url('https://www.w3schools.com/css/trolltunga.jpg');
}
.bg2{
background:url('http://hdwallpaperfun.com/wp-content/uploads/2015/07/Big-Waves-Fantasy-Image-HD.jpg');
}
.bg3{
background:url('http://i.dailymail.co.uk/i/pix/2014/12/19/2429637D00000578-0-image-a-284_1419003100839.jpg');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="box1">
<ul id="bgbg">
<li id="bg1"> </li>
<li id="bg2"> </li>
<li id="bg3"> </li>
</ul> </div>
</body>
You are have a mistake in select a element:
Use the way i use in this code (You can use this code also to add att ):
<script>
$('your element #id or .class or name').attr('att name','value');
</script>
i did something similar recently and went with this approach
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default waves-effect bg-btn" data-img="bg1.jpg">1</button>
<button type="button" class="btn btn-default waves-effect bg-btn" data-img="bg2.jpg">2</button>
<button type="button" class="btn btn-default waves-effect bg-btn" data-img="bg3.jpg">3</button>
</div>
$(document).ready(function(){
$('.bg-btn').click(function(){
var img = 'images/' + $(this).data('img');
$('body').css('background-image', 'url('+ img + ')');
console.log(img);
});
});
Might help you out.

JavaScript/JQuery Enable backbutton behaviour for a iframe in Cordova

I am developing a Webview Application in Cordova. This webview App has iframe where I am showing the Content from my website. Layout of my webview app, Black portion is the iframe
<body style="background-color: #f8f8f8">
<div id="web_container">
<iframe id="main_content"
src="https://www.mycollegepicks.in/home"
style="margin: auto auto; overflow: hidden; border: 1px solid #f8f8f8"></iframe>
</div>
<div id='error' style='display: none'></div>
<div id="menu_wrapper" style="min-height: 40px">
<div>
<img class="menu_item_img" src="img/home.png"
style="width: 36px; padding: 2px;" id="home_btn">
</div>
<div>
<img class="menu_item_img" src="img/arrow_left.png"
style="width: 36px; padding: 2px;" id="back_btn">
</div>
<div>
<img class="menu_item_img" src="img/refresh.png"
style="width: 36px; padding: 2px;" id="reload_btn">
</div>
<div>
<img class="menu_item_img" src="img/arrow_right.png"
style="width: 36px; padding: 2px;" id="forward_btn">
</div>
<div>
<img class="menu_item_img" src="img/shut_down.png"
style="width: 36px; padding: 2px;" id="logout_btn">
</div>
</div>
</div>
I have written following JS -
$( "#logout_btn" ).click(function() {
showToast('Logging Out', 'info');
console.log("Logout Button Clicked");
logout_user();
});
$( "#reload_btn" ).click(function() {
showToast('Reloading Page', 'info');
console.log("Reload Button Clicked");
$( '#main_content' ).attr( 'src', function ( i, val ) { return val; });
});
$( "#home_btn" ).click(function() {
console.log("Home Button Clicked");
$( '#main_content' ).attr( 'src','https://www.mycollegepicks.in/home?app=1&tab_type=home');
});
$( "#back_btn" ).click(function() {
console.log("Back Button Clicked");
iFrameHistory = document.getElementById("main_content").contentWindow.history.length;
if(iFrameHistory)
document.getElementById('main_content').contentWindow.history.back();
writeLog("iFrameHistory "+iFrameHistory);
PopeyeLogger('Iframe History Length '+iFrameHistory,'info');
});
$( "#forward_btn" ).click(function() {
console.log("Forward Button Clicked");
iFrameHistory = document.getElementById("main_content").contentWindow.history.length;
if(iFrameHistory)
document.getElementById('main_content').contentWindow.history.forward();
writeLog("iFrameHistory "+iFrameHistory);
PopeyeLogger('Iframe History Length '+iFrameHistory,'info');
});
But clicking on the backbutton redirects to previous page instead of iframe page back.
Note : In iframe every page load and change made via ajax. On every ajax we push the url to browser state.
I had the same issue, the solution that worked for me is a simple trick. Replace the :
<a data-rel="back" data-icon="back">back</a>
by
<a data-id="persistent" href="the page_before" data-transition="slide" data-icon="back"> back</a>
It worked fine

jQuery Tree Up Traversal

Simple question. I'm trying to target the 'i' tag with the panel-indicator class in the tree. Additionally I need to remove the 'hide' class from the panel-edit 'i' tag. Here's the HTML:
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<i class="panel-indicator glyphicon glyphicon-chevron-down pull-right"></i>
<i class="panel-edit glyphicon glyphicon-pencil pull-right hide"></i>
<h4 class="panel-title" id="-collapsible-group-item-#1-">
<a data-toggle="collapse" data-parent="#collapseOne" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne" class="collapsed">System Details</a>
<a class="anchorjs-link" href="#-collapsible-group-item-#1-"><span class="anchorjs-icon"></span></a>
</h4>
</div>
</div>
Here's the script code. Though it works, it seems like a sloppy way to get it to work. So I'm just wanting to know how to write it correctly so that it sets the 'rotate' class to the 'i' tag with the panel-indicator class.
$('.panel-heading > h4.panel-title > a').click(function () {
if (!$(this).hasClass("open")) {
$(this).addClass("open");
$(this).parent().prev('i.panel-indicator').addClass('rotate');
} else if (
$(this).hasClass("open")) {
$(this).removeClass('open');
$(this).parent().prev().prev('i.panel-indicator').removeClass('rotate');
}
});
Try '.closest' instead:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>closest demo</title>
<style>
li {
margin: 3px;
padding: 3px;
background: #EEEEEE;
}
li.hilight {
background: yellow;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<ul>
<li><b>Click me!</b></li>
<li>You can also <b>Click me!</b></li>
</ul>
<script>
$( document ).on( "click", function( event ) {
$( event.target ).closest( "li" ).toggleClass( "hilight" );
});
</script>
</body>
</html>
source: https://api.jquery.com/closest/
Edit: in your case:
$('.panel-heading > h4.panel-title > a').click(function () {
if (!$(this).hasClass("open")) {
$(this).addClass("open");
$(this).closest('i.panel-indicator').addClass('rotate'); //edited line
} else if (
$(this).hasClass("open")) {
$(this).removeClass('open');
$(this).closest('i.panel-indicator').removeClass('rotate'); // edited line
}
});
$('.panel-heading > h4.panel-title > a').click(function () {
if (!$(this).hasClass("open")) {
$(this).addClass("open");
$(this).closest('.panel-heading').find('i.panel-indicator').addClass('rotate');
$(this).closest('.panel-heading').find('i.panel-edit').removeClass('hide');
} else if (
$(this).hasClass("open")) {
$(this).removeClass('open');
$(this).closest('.panel-heading').find('i.panel-indicator').removeClass('rotate');
$(this).closest('.panel-heading').find('i.panel-edit').addClass('hide');
}
});

How to drag and drop multiple elements between different tabs

I am trying to drag and drop multiple elements between different tabs.
in this jsfiddle, When an item is being dragged, i want to drag all other checked items along with it, like Gmail does when you move several email from inbox to another folder.
I think it is necessary to use ui.helper but i don't have enough skill in query.
following is the code i'm currently working with:
$( "#sortable1, #sortable2" ).sortable().disableSelection();
var $tabs = $( "#tabs" ).tabs();
var $tab_items = $( "ul:first li", $tabs ).droppable({
accept: ".connectedSortable li",
hoverClass: "ui-state-hover",
drop: function( event, ui ) {
var $item = $( this );
var $list = $( $item.find( "a" ).attr( "href" ) )
.find( ".connectedSortable" );
ui.draggable.hide( "slow", function() {
$tabs.tabs( "option", "active", $tab_items.index( $item ) );
$( this ).appendTo( $list ).show( "slow" );
});
}
});
After a lot of fiddling, I came up with the following based on my answer here
Basically we save the selected items using data(), Initialize the tabs as droppable() and append the selected items into the sortable on drop event.
$('.connectedSortable').on('click', 'input', function() {
$(this).parent().toggleClass('selected');
});
$("#sortable1, #sortable2").sortable({
revert: 0,
helper: function(e, item) { //create custom helper
if (!item.hasClass('selected')) item.addClass('selected');
// clone selected items before hiding
var elements = $('.selected').not('.ui-sortable-placeholder').clone();
//hide selected items
item.siblings('.selected').addClass('hidden');
return $('<ul/>').append(elements);
},
start: function(e, ui) {
var $elements = ui.item.siblings('.selected.hidden').not('.ui-sortable-placeholder');
//store the selected items to item being dragged
ui.item.data('items', $elements);
},
stop: function(e, ui) {
//show the selected items after the operation
ui.item.siblings('.selected').removeClass('hidden');
//unselect since the operation is complete
$('.selected').removeClass('selected');
$(this).find('input:checked').prop('checked', false);
}
});
var $tabs = $("#tabs").tabs(),
$tab_items = $("ul:first li", $tabs).droppable({
accept: "ul, .connectedSortable li",
hoverClass: "ui-state-hover",
drop: function(event, ui) {
var $item = $(this),
$elements = ui.draggable.data('items'),
$list = $($item.find("a").attr("href")).find(".connectedSortable");
ui.draggable.show().hide("slow", function() {
$tabs.tabs("option", "active", $tab_items.index($item));
$(this).appendTo($list).show("slow").before($elements.show("slow"));
});
}
});
ul {
list-style-type: none;
}
.connectedSortable li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
.chbox {
margin-right: 10px;
}
.selected {
background: red !important;
}
.hidden {
display: none !important;
}
<link href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<div id="tabs">
<ul>
<li>Nunc tincidunt
</li>
<li>Proin dolor
</li>
</ul>
<div id="tabs-1">
<ul id="sortable1" class="connectedSortable ui-helper-reset">
<li class="ui-state-default">
<input class="chbox" type="checkbox" />Item 1</li>
<li class="ui-state-default">
<input class="chbox" type="checkbox" />Item 2</li>
<li class="ui-state-default">
<input class="chbox" type="checkbox" />Item 3</li>
<li class="ui-state-default">
<input class="chbox" type="checkbox" />Item 4</li>
</ul>
</div>
<div id="tabs-2">
<ul id="sortable2" class="connectedSortable ui-helper-reset"></ul>
</div>
</div>
Updated Fiddle

Categories

Resources