Can Bootstrap popovers not be destroyed? - javascript

Is it possible to have a bootstrap (v3) popovers to have it's div loaded right at the start of pageload and not be destroyed when it is being toggled?
I have a popover content in a div:
<div id="popoverContent">
<h1>Stuff</h1>
<p>I'm in a popover!</p>
</div>
And a button that toggles the popover:
<a id="floating_tab" data-toggle="popover" data-placement="left">Button</a>
Here is my Javascript code that handles the button pushes:
<script>
var x = false;
$('[data-toggle=popover]').popover({
content: $('#popoverContent').html(),
html: true
}).click(function() {
if (x) {
$(this).popover('hide');
x = false;
}
else {
$(this).popover('show');
x = true;
}
});
</script>
The thing is, that when $(this).popover('show'); is called, a div is created. Something like this shows up in the inspect element (chrome):
<div class="popover fade left in" role="tooltip" id="popover460185" style="top: 430.5px; left: 2234px; display: block;"><div class="arrow" style="top: 50%;"></div><h3 class="popover-title" style="display: none;"></h3><div class="popover-content">
<h1>Stuff</h1>
<p>I'm in a popover!</p>
</div></div>
But when the button is clicked again, the whole div itself is removed and obliterated from the page.
Is it possible to have the popover div to be created during pageload (hidden though) and can be toggleable without having the div to be deleted?

As stated in the comments, it is not presently possible with Bootstrap 3. The Popover (which is an extension of the Tooltip) is dynamically created on show and detached (using jQuery.detach) from the DOM on hide.
It is probably best to roll your own JavaScript and simply utilize Bootstrap's CSS. However, you could easily patch the functionality using the Popover's event API -the following can be used as a starting place:
$(function () {
var content = $('#popover-content'), // Pre defined popover content.
popover = $('#popover-anchor').popover();
popover.on('inserted.bs.popover', function () {
var instance = $(this).data('bs.popover');
// Replace the popover's content element with the 'content' element
instance.$tip = content;
});
popover.on('shown.bs.popover', function () {
var instance = $(this).data('bs.popover');
// Remove the reference to 'content', so that it is not detached on hide
instance.$tip = null;
});
popover.on('hide.bs.popover', function () {
// Manually hide the popover, since we removed the reference to 'content'
content.removeClass('in');
content.addClass('out');
});
});
Codepen

Related

Foundation dropdown stop working

I have a Foundation 5 dropdown on my page, which works fine. However when I submit a form in the dropdown area a new element is added to the top of the page so all the elements are moved down.
After that, all my dropdowns stop to work. (If I skip the adding of the element to the DOM, everything is working fine)
My dropdown:
<div id="file-tab">
<i data-dropdown="shareForm16" aria-controls="shareForm16" aria-expanded="false" class="iconTrigger"></i>
<form data-dropdown-content class="share-form f-dropdown content" aria-hidden="true" tabindex="-1" action="" id="shareForm16">
...
</form>
</div>
I thought I need to rebind the foundation event listeners, but it doesn't work. Maybe I am just doing it wrong.
$('#file-tab').on("submit", 'form.share-form',function(e){
e.preventDefault();
var groupName = $(form.target).find('input[type="text"]').val();
var id = $(e.target).parent().children('input[type="hidden"]').val();
if (groupName) {
$(e.target).trigger('click');
window.currentFTT.share(id ,groupName); // adds the element to the DOM
// my attempt to rebind:
$('#'+e.target.id).foundation({bindings: 'events'});
$('i[aria-controls="'+e.target.id+'"]').foundation({bindings: 'events'});
}
});
Instead of calling foundation for individual elements, make a general call to foundation, passing 'reflow' as a parameter:
$(document).foundation('reflow');
E.g:
$('#file-tab').on("submit", 'form.share-form',function(e){
e.preventDefault();
var groupName = $(form.target).find('input[type="text"]').val();
var id = $(e.target).parent().children('input[type="hidden"]').val();
if (groupName) {
$(e.target).trigger('click');
window.currentFTT.share(id ,groupName); // adds the element to the DOM
// my attempt to rebind:
$(document).foundation('reflow');
}
});

How to show hide divs INSIDE divs easily?

My website is a blog where I have a page with all the posts on a single HTML page. The "posts" are just images inside divs and I need some information to be able to show and hide in side the parent div of the images. Heres how its set up:
HTML
<div class="posts">
<h3>mm/dd/yy<p class="preview">click to show more</p><p class="expand">click to show less</p></h3>
<h4>Title</h4><br>
<p class="expand">caption caption caption caption caption caption caption caption caption</p>
<div class="centertext">
<img class="post" src="path/to/image">
</div>
<br>
</div>
lil CSS
.expand{display: none;}
JS
$(document).ready(function(){
$(".posts").click(function(){
$('.expand').toggle();
$('.preview').toggle();
});
What ends up happening that I don't want to happen is that all images and their captions are hiding and showing when I just click one. Shown here or fullscreen here Someone please help me! Additional info: I am using JQuery and Bootstrap too
Change your JS to:
$(document).ready(function () {
$(".posts").click(function () {
$(this).find('.expand').toggle();
$(this).find('.preview').toggle();
});
});
Or more simple:
$(document).ready(function () {
$(".posts").click(function () {
$(this).find('.expand, .preview').toggle();
});
});
To toggle means, that you don't know the state. The best way is, to change a css-class or a data-attribute.
You can use event.target/this to refer the current object clicked and find child(expand/preview) of the object you clicked with find()
or
check for the children if it is .expand/.preview with function is() //not a better approach
$(document).ready(function () {
$(".posts").click(function () {
$(this).find('.expand').toggle();
$(this).find('.preview').toggle();
});
});
or
$(document).ready(function () {
$(".posts").click(function (event) {
$(event.target).find('.expand').toggle();
//check if target is .expand or its child then first go to its parent with .parents().eq() then apply find()
$(event.target).find('.preview').toggle();
//check if target is .preview or its child then first go to its parent with .parents().eq() then apply find()
});
});

Toggling Background Color on Click with Javascript

I am working on a class project and need to be able to toggle the background color of a transparent png on click. I have been working through a number of examples from the site, but I can't get it working. I am a total novice at Javascript and haven't had luck trying to plug in jQuery code either.
Here is the targeted section:
<div class="expenseIcon"><a href="#">
<img src="images/mortgage.png"></a><br/>
<p>Rent or Mortgage</p>
</div>
On clicking the linked image, the goal is for the background on the image to change to green. Clicking it again would change it back to the default, white. Here's the CSS I'd like to toggle on/off with click.
.colorToggle {
background: #A6D785;
}
I had tried adding class="iconLink" to the href and class="iconBox" to the image with the following Javascript adapted from another post, but it didn't work.
var obj = {};
$(document).ready(function () {
$(".iconLink").click(function () {
var text = $(this).find(".iconBox");
obj.var1 = text;
//alert(obj.var1);
//return false;
$('.iconBox').removeClass('colorToggle');
$(this).addClass('colorToggle')
});
});
Any advice would be greatly appreciated!
Let's break down what is happening with your current code when you click the link.
var obj = {};
$(document).ready(function () {
$(".iconLink").click(function () {
var text = $(this).find(".iconBox");
obj.var1 = text;
$('.iconBox').removeClass('colorToggle');
$(this).addClass('colorToggle')
});
});
JQuery finds all elements with the classname "iconBox". In your case, this is the img element. The reference to that element is then saved in "obj.var1". You do not end up doing anything with this reference, so these two lines can be removed.
All elements with the class "iconBox" have the class "colorToggle" removed. Your img element didn't have this class on it, so nothing happens.
The class "colorToggle" is added to the anchor element. Yes! Now the element wrapping the img has a background color.
Unfortunately, clicking the anchor tag again won't do anything, since the anchor tag will already have the "colorToggle" class and all we would be doing would be trying to add it again. Hmm. Let's try changing addClass to toggleClass. Here's our new code:
$(document).ready(function () {
$(".iconLink").click(function () {
$(this).toggleClass('colorToggle');
}
});
Also, note that because we're working with the anchor element, the p element won't be affected by this change. If you want the entire div to change background colors, use this line instead:
$(".expenseIcon").toggleClass('colorToggle');
Using the given markup:
<!-- to toggle the bg-color onClick of anchor tag -->
<div class="expenseIcon">
<a href="#">
<img src="images/mortgage.png">
</a>
<br/>
<p>Rent or Mortgage</p>
</div>
since the question asks for javascript, heres an option for updating the background-color of an element using the built-in js.style method
//get a handle on the link
//only one element w/ className 'expenseIcon'
//first child of 'expenseIcon' is the anchor tag
var link = document.getElementsByClassName('expenseIcon')[0].children[0];
//get a handle on the image
var image = link.children[0];
//listen for click on link & call bgUpdate()
link.addEventListener('click', bgUpdate, false);
function bgUpdate() {
if(image.style.backgroundColor === 'lightgoldenrodyellow'){
image.style.backgroundColor = 'aliceblue';
} else if (image.style.backgroundColor === 'aliceblue') {
image.style.backgroundColor = 'lightgoldenrodyellow';
}
else console.log('image bgColor: ' + image.style.backgroundColor);
}
a similar example
css
.expenseIcon{
background: red;
}
.colorToggle {
background: blue;
}
jquery
$(".expenseIcon").click(function () {
$('.expenseIcon').toggleClass('colorToggle');
});
By default, the div will have expenseIcon background. ToggleClass will toggle the div class with colorToggle so will override the previous color.
You don't need an hyperlink tag A to manage clicks, just put it on the DIV.

Show div once clicked and hide when clicking outside

I'm trying to show the #subscribe-pop div once a link is clicked and hide it when clicking anywhere outside it. I can get it to show and hide if I change the:
$('document').click(function() {
TO
$('#SomeOtherRandomDiv').click(function() {
HTML:
<div id="footleft">
Click here to show div
<div id="subscribe-pop"><p>my content</p></div>
</div>
Script:
<script type="text/javascript">
function toggle_visibility(id) {
var e = document.getElementById("subscribe-pop");
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
}
$('document').click(function() {
$('#subscribe-pop').hide(); //Hide the menus if visible
});
$('#subscribe-pop').click(function(e){
e.stopPropagation();
});
</script>
You have to stop the event propagation in your container ('footleft' in this case), so the parent element don't notice the event was triggered.
Something like this:
HTML
<div id="footleft">
<a href="#" id='link'>Click here to show div</a>
<div id="subscribe-pop"><p>my content</p></div>
</div>
JS
$('html').click(function() {
$('#subscribe-pop').hide();
})
$('#footleft').click(function(e){
e.stopPropagation();
});
$('#link').click(function(e) {
$('#subscribe-pop').toggle();
});
See it working here.
I reckon that the asker is trying to accomplish a jquery modal type of display of a div.
Should you like to check this link out, the page upon load displays a modal div that drives your eye into the center of the screen because it dims the background.
Moreover, I compiled a short jsFiddle for you to check on. if you are allowed to use jquery with your requirements, you can also check out their site.
Here is the code for showing or hiding your pop-up div
var toggleVisibility = function (){
if($('#subscribe-pop').is(":not(:visible)") ){
$('#subscribe-pop').show();
}else{
$('#subscribe-pop').hide();
}
}
Changing $(document).click() to $('html').click() should solve the main problem.
Secondly, you do not need the toggle_visibility() function at all, you can simply do:
$('#subscribe-pop').toggle();
Ref: changed body to html as per this answer: How do I detect a click outside an element?

CSS/Javascript Mouseover Popup box

I have table cell with a javascript/css content box that pops up upon mouseover.
There are 20 cells on the page. Everything is working correctly, in that when you mouseover the product link, you see the content box. However, I want to put a LINK inside the content box that the user can click on if they choose. So, the popup box has to stay up long enough for the user to mouseover to click the link.
Really, I want the OnMouseOver to stay open until either a second or two has gone by and/or the user OnMouseOver's another cell.
The problem I'm having is that the pop up box doesn't stay open (due to OnMouseOut) to click the link. If I turn OnMouseOut off (which I tried), then all the pop up boxes just stay open, so this doesn't do the job either.
My CSS looks like this:
<style type="text/css" title="">
.NameHighlights {position:relative; }
.NameHighlights div {display: none;}
.NameHighlightsHover {position:relative;}
.NameHighlightsHover div {display:block;position:absolute;width: 15em;top:1.3em;*top:20px;left:70px;z-index:1000;}
</style>
And the html:
<td>
<span class="NameHighlights" onMouseOver="javascript:this.className='NameHighlightsHover'" onMouseOut="javascript:this.className='NameHighlights'">
Product 1
<div>
# of Votes: 123<br>
% Liked<br>
<a href="product review link>See User reviews</a>
</div>
</span>
</td>
So, how can I make the pop up box stay open long enough to click on the link, but also make it disappear if another content box is activated?
Thanks in advance.
You have to improve your HTML markup for this task, need to get rid of inline event handlers:
<span class="NameHighlights">
Product 1
<div>
# of Votes: 123<br>
% Liked<br>
See User reviews
</div>
</span>
Then you have to bind your events to all .NameHighlights spans:
var span = document.querySelectorAll('.NameHighlights');
for (var i = span.length; i--;) {
(function () {
var t;
span[i].onmouseover = function () {
hideAll();
clearTimeout(t);
this.className = 'NameHighlightsHover';
};
span[i].onmouseout = function () {
var self = this;
t = setTimeout(function () {
self.className = 'NameHighlights';
}, 300);
};
})();
}
http://jsfiddle.net/3wyHJ/
So the idea is to use setTimeout method.
Notes: I used querySelectorAll which is not supported by IE7, if you need to support it then you can use any of implementations of the getElementsByClassName method.
In case anyone is looking for a jQuery version of the accepted answer:
var t;
$(function(){
$('span.NameHighlights').mouseover(
function(e){
hideAll();
clearTimeout(t);
$(this).attr('class', 'NameHighlightsHover');
}
).mouseout(
function(e){
t = setTimeout(function() {
//$(this).attr('class', 'NameHighlights');
hideAll();
}, 300);
}
);
});
function hideAll() {
$('span.NameHighlightsHover').each(function(index) {
console.log('insde hideAll');
$(this).attr('class', 'NameHighlights');
})
};
jsFiddle

Categories

Resources