Click in popover not working - javascript

I try to get data-lang value after click event on an a tag with this code:
$("[data-toggle=popover]").popover({
html: true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
$('.popover-body').on('click', 'a', function() {
let lang = $(this).data("lang")
alert(lang);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<nav class="mainnav">
<ul class="topnav">
Popover
</ul>
</nav>
<div id="a1" class="hidden">
<div class="popover-heading">_('Välj ditt språk')</div>
<div class="popover-body">
<div class="lang">
Norsk
</div>
<div>
Deutsch
</div>
<div>
Nederlands
</div>
<div>
Español
</div>
<div>
Dansk
</div>
</div>
</div>
But when I click it, nothing happens.
How can I fix this?

The issue is because although you're using a delegated event handler, which is the correct solution to this problem, the .popover-body element is not cloned along with the content of the popover by the plugin. You can see this if you inspect the elements in the DOM after you open the popover.
To fix this you can use the .mainnav element as the primary selector of your delegated event handler:
$("[data-toggle=popover]").popover({
html: true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
$('.mainnav').on('click', '.topnav div a', function() { // change this
let lang = $(this).data("lang")
console.log(lang);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<nav class="mainnav">
<ul class="topnav">
Popover
</ul>
</nav>
<div id="a1" class="hidden">
<div class="popover-heading">_('Välj ditt språk')</div>
<div class="popover-body">
<div class="lang">
Norsk
</div>
<div>
Deutsch
</div>
<div>
Nederlands
</div>
<div>
Español
</div>
<div>
Dansk
</div>
</div>
</div>

The issue seems to be with the selector. In the source code when the popup was open I couldn't see the class popover-body. This should work though:
$("[data-toggle=popover]").popover({
html: true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
$('body').on('click', '.popover-content a', function() {
let lang = $(this).data("lang")
alert(lang);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<nav class="mainnav">
<ul class="topnav">
Popover
</ul>
</nav>
<div id="a1" class="hidden">
<div class="popover-heading">_('Välj ditt språk')</div>
<div class="popover-body">
<div class="lang">
Norsk
</div>
<div>
Deutsch
</div>
<div>
Nederlands
</div>
<div>
Español
</div>
<div>
Dansk
</div>
</div>
</div>

There is an issue with selector 'popover-body' which may not exist.
Take a look at JsFiddle: https://jsfiddle.net/xe54r7db/37/
$("[data-toggle=popover]").popover({
html : true,
content: function() {
var content = $(this).attr("data-popover-content");
return $(content).children(".popover-body").html();
},
title: function() {
var title = $(this).attr("data-popover-content");
return $(title).children(".popover-heading").html();
}
});
//Register with document parent selector to attach event.
$(document).on('click','.popover-content a',function(e){
// e.preventDefault();
let lang = $(this).data("lang")
alert(lang);
});

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object, I change class selector to document for binding event to element
$(document).on('click', 'a', function() {
let lang = $(this).data("lang")
alert(lang);
});

Related

jquery chosen in bootstrap popover not working

I am trying to run jquery chosen inside a bootstrap popover, but the initiated chosen dropdown is not clickable.
Here is my code:
html
<button type="button" class="btn btn-md btn-danger" id="popover" data-title="Popover title" >Click to toggle popover</button>
<div style="display: none;" id="popovercontent">
<select class="chosen chzn-done">
<option>Choose...</option>
<option>jQuery</option>
<option selected="selected">MooTools</option>
<option>Prototype</option>
<option>Dojo Toolkit</option>
</select>
</div>
JS
$(document).ready(function(){
// init chosen
var $chosen = $(".chosen").chosen();
// init popover
var $popover = $('#popover').popover({
placement: 'bottom',
html: true,
content: function () {
return $('#popovercontent').html();
},
title: function () {
return $(this).data('title');
},
});
// on show popover
$popover.on("show.bs.popover", function(e) {
console.log('open popover');
$chosen.trigger("chosen:updated");
});
}); // document.ready
https://jsfiddle.net/gdtocsud/
similar question (not answered): Chosen in bootstrap popover not working?
thank you
Bjoern
try this, may be this will help u
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.6.2/chosen.jquery.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.6.2/chosen.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.6.2/chosen.css">
<script>
$(document).ready(function() {
var $popover = $('#popover').popover({
placement: 'bottom',
html: true,
content: function() {
return $('#popovercontent').html();
},
title: function() {
return $(this).data('title');
},
});
$popover.on("shown.bs.popover", function(e) {
$('.chzn-done').chosen();
});
$popover.on('hidden.bs.popover', function() {
$('.chzn-done').chosen('destroy');
});
});
</script>
</head>
<body style="padding:25px">
<button type="button" class="btn btn-md btn-danger" id="popover" data-title="Popover title">Click to toggle popover</button>
<div id="popovercontent" style='display:none'>
<select class="chosen chosen-select chzn-done" >
<option>Choose...</option>
<option>jQuery</option>
<option selected="selected">MooTools</option>
<option>Prototype</option>
<option>Dojo Toolkit</option>
</select>
</div>
</body>
</html>
Here is the js code :
$(document).ready(function() {
// init chosen
//var $chosen = $(".chosen").chosen();
// init popover
var $popover = $('#popover').popover({
placement: 'bottom',
html: true,
content: function() {
return $('#popovercontent').html();
},
title: function() {
return $(this).data('title');
},
});
// on show popover
$popover.on("shown.bs.popover", function(e) {
$('.chzn-done').chosen();
});
$popover.on('hidden.bs.popover', function() {
$('.chzn-done').chosen('destroy');
});
}); // document.ready
For working code:
Here is fiddle link
Similar to chosen with modal the chosen behaviour needs to be initialized after the content is ready, so similar to modal events, you can use the popover events
Hi here is the working demo
https://jsfiddle.net/gdtocsud/2/
<div class="panel panel-default">
<div class="panel-body">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span data-bind="label">Select One</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Item 1</li>
<li>Another item</li>
<li>This is a longer item that will not fit properly</li>
</ul>
</div>
</div>
</div>

Error running script on existing element

I'm having issues running a script and getting and error on the addEventListener property. I understand that this occurs when I reference an element that doesn't exist in the DOM, but I'm running the script at the bottom of my markup, so I'm not sure what I need to change.
Script:
var slideLeft = new Menu({
wrapper: '#o-wrapper',
type: 'slide-left',
menuOpenerClass: '.c-button',
maskId: '#c-mask'
});
var slideLeftBtn = document.querySelector('#c-button--slide-left');
slideLeftBtn.addEventListener('click', function(e) {
e.preventDefault;
slideLeft.open();
});
Example: http://codepen.io/ourcore/pen/ZBLeVQ
Working demo: http://callmenick.com/_development/slide-push-menus/
I updated the CodePen: http://codepen.io/HenryGranados/pen/rWjmVj
Here's a working solution. Hope it helps :)
var slideLeft = new Menu({
wrapper: '#o-wrapper',
type: 'slide-left',
menuOpenerClass: '.c-button',
maskId: '#c-mask'
});
var slideLeftBtn = document.querySelector('#c-button--slide-left');
slideLeftBtn.addEventListener('click', function(e) {
e.preventDefault;
slideLeft.open();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://callmenick.com/_development/slide-push-menus/css/style.min.css">
<link rel="stylesheet" type="text/css" href="http://callmenick.com/_development/slide-push-menus/css/font-awesome.min.css">
<script type="text/javascript" src = "http://callmenick.com/_development/slide-push-menus/js/dist/menu.js"></script>
<main class="o-content">
<div class="o-container">
<div class="c-buttons">
<button id="c-button--slide-left" class="c-button">Slide Left</button>
</div>
</div>
</main>
<div id="o-wrapper" class="o-wrapper">
</div>
<nav id="c-menu--slide-left" class="c-menu c-menu--slide-left">
<button class="c-menu__close">← Close Menu</button>
<ul class="c-menu__items">
<li class="c-menu__item">Home</li>
<li class="c-menu__item">About</li>
<li class="c-menu__item">Services</li>
<li class="c-menu__item">Work</li>
<li class="c-menu__item">Contact</li>
</ul>
</nav>
<div id="c-mask" class="c-mask"></div>

Set CSS property with js click event handler

I am trying to create an onclick event which will show/hide elements of an array however I am struggling with the showSubTabGroup() function below.
Sidenote: Eventually I would like to make this onmouseenter and onmouseleave, rather than 'click' as you see below.
I would like to be able to click on a div and show subsequent div's below as you might expect from a navigation feature.
The console is not returning any errors, however the 'click' function seems alert("CLICKED") properly.
Any help would be greatly appreciated.
Problem:
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', function () {
alert("CLICKED");//Testing 'click' call
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
});
}
function Tab (subTabGroup) {
this.tab = document.getElementsByClassName("tab");
this.subTab = document.getElementsByClassName("sub-tab");
this.subTabGroup = subTabGroup;
}
Tab.prototype.hideSubTabs = function () {
for (var i = 0; i < this.subTab.length; i++) {
this.subTab[i].style.display = "none";
}
}
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', function () {
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
});
}
var tab = new Tab(3);
tab.hideSubTabs();
tab.showSubTabGroup(0,0);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Responsive Nav</title>
</head>
<body>
<!-- JQuery CDN -->
<script src="http://code.jquery.com/jquery-3.1.0.js"></script>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
</div>
<script type="text/javascript" src="tab.js"></script>
<script type="text/javascript" src="tabEvents.js"></script>
</body>
</html>
The problem of what is this inside the click. It is not your tab code, it is the reference to the element that you clicked on. You need to change that by using bind
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', (function () {
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
}).bind(this));
}
As I read your post, I assume hideSubTabs() is working properly. In that case I will suggest to use in showSubTabGroup():
this.subTab[i].style.display = "initial";
instead of
this.subTab[i].style.display = "";
"initial" will set to its default e.g. as "block" for div and "inline" for span
I see that you also have included jQuery. If I may ask why don't jQuery functions which will do the same with less code:
$('.tab').on('click',function() {
$(this).closest('.container').find('.sub-tab').toggle()
})
$('.tab').click();
$('.tab')[0].click();

jQuery stop function running twice

I am using slideUp / down to show and hide content and have written it to that it will close any visible content when opening another one. This works until I try to close content by clicking on it, it opens it again straight away.
The HTML
<ul class="contents">
<li>
while($results->fetch()){
<div class="details">text</div>
<div class="more_details">more text</div>
}
</li>
</ul>
The jQuery
$("#results").on("click", ".details", function() {
$(".open").slideUp(600, function() {
$(".open").css("display", "none").removeClass("open");
});
if ($(this).hasClass("open")) {
$(this).slideUp( 600, function() {
$(this).css("display", "none").removeClass("open");
});
} else {
$(this).next(".more_details").slideDown(600, function() {
$(this).css("display", "show").addClass("open");
});
}
});
In the slide down code you are working with the next sibling more_details, where in the slide up code you are dealing with this element.
$("#results").on("click", ".details", function() {
var $details = $(this).next(".more_details");
$details.slideToggle(600, function() {
$details.toggleClass("open");
});
$(".more_details.open").not($details).slideUp(600, function() {
$(this).removeClass("open");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="results">
<div class="details">details</div>
<div class="more_details">more_details</div>
<div class="details">details</div>
<div class="more_details">more_details</div>
<div class="details">details</div>
<div class="more_details">more_details</div>
<div class="details">details</div>
<div class="more_details">more_details</div>
</div>

materialbox Materializecss works only after typing initialization jQuery in console

I have used '.materialboxed' in my webpage, but the initialization in script doesn't work, I have to manually type $('.materialboxed').materialbox(); in console for it to work.
Html (ui-view in angular route)
<div class="row">
<div class="card-panel col l12" style="height: 750px;">
<img class="col l5 materialboxed" height="500px" id="poster"
ng-src="https://image.tmdb.org/t/p/original{{poster_path}}"/>
<div class="col l7">
<div class="row">
<a class="col l10" style="float:left;text-align: left;" ng-href="{{homepage}}">
<h3 class="title" ng-bind="original_title"></h3>
</a>
<a ng-href="http://www.imdb.com/title/{{imdb_link}}"
style="float:right;text-align: right; margin-top: 29px;"
class="imdb-link col l2" title="IMDb"><i class="icon-imdb"></i></a>
</div>
<div class="row"><p ng-bind="overview"></p>
<span class="right" ng-bind="release_date"></span>
<h5>Genres</h5>
<p ng-bind="genre"></p>
<h5>Production Companies</h5>
<p ng-bind="names">
</p>
<h5>Voting</h5>
<p ng-bind="vote_average"></p></div>
</div>
</div>
</div>
See the in 3rd line.
index.html
//rest code
<main ui-view></main>
</div>
<script src="js/angular_min.js"></script>
<script src="js/angular-touch.min.js"></script>
<script src="js/angular-ui-router.min.js"></script>
<script src="js/angucomplete-alt.js"></script>
<script src="appRoute.js"></script>
<script src="controller/MovieController.js"></script>
<script src="controller/LoginController.js"></script>
<script src="controller/RegisterController.js"></script>
<script src="controller/TvController.js"></script>
<script src="controller/LoggedInController.js"></script>
<script src="controller/TopMovieController.js"></script>
<script src="app-services/DetailsService.js"></script>
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/materialize.min.js"></script>
<script>
$(document).ready(function () {
$('.materialboxed').materialbox();
$('.button-collapse').sideNav({
menuWidth: 300,
edge: 'left',
closeOnClick: true
}
);
$('.modal-trigger').leanModal();
$("#movie").click(function () {
window.location.href = window.location.pathname + "#/movie";
});
$("#tv").click(function () {
window.location.href = window.location.pathname + "#/tv";
});
});
</script>
</body>
Even after initializing the materialboxed, it doesn't work. It works only after typing $('.materialboxed').materialbox(); in console manually.
Help me figure this out. Thanks
You shouldn't use $(document).ready in Angular. In fact you should try to use as little jQuery as possible, but if you need to, then you should create a directive that allows you to initialize the function after they render.
var app = angular.module('myApp');
app.directive('onLastRepeat', function() {
return function(scope, element, attrs) {
if (scope.$last)
setTimeout(function() {
scope.$emit('onRepeatLast', element, attrs);
}, 1);
};
});
app.controller('MoviesController', function($scope) {
$scope.$on('onRepeatLast', function(scope, element, attrs) {
$('.materialboxed').materialbox();
});
}
Now you can apply this to your HTML:
<ul>
<!-- this is just an example with the added directive -->
<li ng-repeat="movie in movies" on-last-repeat>
<img ng-src="{{imageObjectHere}}" class="materialboxed">
</li>
</ul>
Since you added this new directive in there, the $('.materialboxed').materialbox(); should fire after the repeat is done

Categories