Vtiger - Jquery slideToggle randomly toggles twice - javascript

I made a widget in the summary view of the account module. In this widget i want to use a slideToggle to show some details. Sometimes the code works perfectly but other times it double toggles and instantly closes the details.
JS:
$(document).ready(function() {
$('.potential_single_title').on('click',function(e) {
$(this).parent().find('.potential_comment_list').slideToggle('slow');
});
});
TPL:
<script src="resources/ChildCommentScript.js"></script>
<link rel="stylesheet" type="text/css" href="resources/ChildCommentStyle.css">
{strip}
<div class="potential_comment_container">
{foreach from=$OPP key=K item=POT}
<br />
<div class="potential_single">
<div class="potential_single_title">
<strong>{$POT[1]}</strong> <span class="potential_assignee">Assigned to : {$POT[2]}</span>
</div>
<hr>
<div class="potential_comment_list">
<div class="commentContainer">
{foreach from=$COM[$K] item=POTCOM}
<div class="commentDetails" style="width:100%;">
<div class="span1">
<img class="alignMiddle pull-left" src="layouts/vlayout/skins/images/DefaultUserIcon.png">
</div>
<span class="commentorName"><strong> {$POTCOM[0]}</strong></span>
<span class="pull-right"><p class="muted"><small>{$POTCOM[1]}</small></p></span>
<div class="commentInfoContent">{$POTCOM[2]}</div>
</div>
{/foreach}
</div>
</div>
</div>
{/foreach}
</div>
{/strip}

Usage of slide toggle seems to be correct. I suspect the click is happening twice sometimes which is causing slide again.
Modifying JS to reject clicks if slide action is happening might resolve the issue.
$(document).ready(function() {
var sliding = false;
$('.potential_single_title').on('click',function(e) {
if(sliding) return false;
sliding = true;
$(this).parent().find('.potential_comment_list').slideToggle('slow', function() {sliding = false;});
});
});
Simple flag to reject click action while sliding is included!

This is just to show how to see if the click is happening twice.
$(document).ready(function() {
$('.potential_single_title').on('click',function(e) {
console.log("clicked")
});
});
for one click.. if in console you see clicked twice you can assume your trigger happy ;-)
try also putting a debugger in there... may highlight things
$(document).ready(function() {
$('.potential_single_title').on('click',function(e) {
console.log("clicked");
debugger;
});
});
in chrome the debugger console must be open for it to hit the debugger line.
just want to rule out stupid things.. this is one for one what is on the page no other js... like maybe your wrapping $(document).ready( twice or something and just havnt included that code in the question?

Related

How to slide down dynamic content using jQuery?

I have a comment system and I would like to implement the "Show Replies (2)" slide down effect.
This is an example of my setup.
<div class="comment">
<div class="main-comment">
Message.
Show Replies (1)
</div>
<div class="sub-comment">
Funny comment up there, mate.
</div>
</div>
But because both the main comment and its sub comments are dynamically generated using ajax, setting event handlers was a little tricky. This is how I did it:
$(".comment").delegate('.show-replies', 'click', function(event) {
$(this).parent().next(".sub-comment").slideDown();
});
I've tried to make the setup as simple and close to the real thing as possible.
What am I doing wrong and how do I solve it?
<div class="comment">
<div class="main-comment">
Message.
Show Replies (1)
</div>
<div class="sub-comment" style="display: none">
Funny comment up there, mate.
</div>
</div>
<script>
$(document).ready(function() {
$('.show-replies').on('click', function() {
$('.sub-comment').slideToggle();
});
});
</script>
In order to bind to NEW dynamic content you need to tell jquery where it is going to be.. Also make sure to use the latest jQuery, delegate is old.
<div class="comments">
<div class="main-comment">
Message.Show Replies (1)
</div>
<div class="sub-comment" style="display: none">
Funny comment up there, mate.
</div>
</div>
<script>
$(document).ready(function() {
$('.show-replies').on('click','.comments', function() {
$('.sub-comment').slideToggle();
});
});
</script>
Notice the .on(eventType, selector, function) signature.
This will work for dynamic content, anything loaded INTO the div class 'comments' - jQuery will always travesre that container from fresh, instead of caching it.
Also- dont just do it on the entire page,because it will cause slow response, since, every click, it will try and bind to the selector.
Replacing
$(this).parent().next(".sub-comment").slideDown();
with
$(this).parent().parent().next(".sub-comment").slideDown();
Fixed the problem.

Javascript / Html Show All / Hide All Thing

I'm trying to make a "Show All / Hide All", currently I've made it so when you click the text, it opens the image and text but I want a Show all so it will expand all divs.
Here is how it works at this moment: JSFiddle .
<div class="gwshowhide"><li><a class="printer">Amber Money Printer</a>
<div class="gwinfo">Level Requirement: 1<br>
<img src="pic.png"></div>
</div></li>
<div class="gwshowhide"><li><a class="printer">Moonstone Money Printer</a>
<div class="gwinfo">Level Requirement: 5<br>
<img src="pic1.png"></div>
</div></li>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
$(function () {
<script>
$('.printer').click(function () {
$(this).siblings('.gwinfo').slideToggle('slow')
})
})
</script>
In general: I want to add a Show all / Hide all text that would open all / hide all of these at once, I also want to keep the current system so when you click one, it opens / closes it. Thank you!
Here is a fiddle to get you started. I've outlined the general gist of what you need below.
Essentially, you need two components.
First, HTML. Which is just another anchor to click to toggle show/hide all.
<a class="toggle-all">Show All</a>
Second, you need an event on that new anchor to trigger the function you have, but for ALL the options.
$('.toggle-all').click(function() {
$('.printer').each(function () {
$(this).siblings('.gwinfo').slideToggle('slow');
});
});
From there, you might want to add something to toggle the text like:
if (open) {
$('.toggle-all').text('Hide all');
} else { ... }
Bonus tip: ALWAYS put semicolons at the end of your lines in JavaScript. Even though JS will auto-insert them, it can cause difficult to debug problems as well as make IE die in some cases.
<p class="showall">Show Hide All</p>
<div class="gwshowhide">
<li>
<a class="printer">Amber Money Printer</a>
<div class="gwinfo">Level Requirement: 1<br/>
<img src="pic.png"/>
</div>
</li>
</div>
<div class="gwshowhide">
<li>
<a class="printer">Moonstone Money Printer</a>
<div class="gwinfo">Level Requirement: 5<br/>
<img src="pic1.png"/>
</div>
</li>
</div>
and your jquery code would be
$(function () {
$('.printer').click(function () {
$(this).siblings('.gwinfo').slideToggle('slow');
})
});
$('.showall').on('click',function(){
$('.gwinfo,.gwinfo').slideToggle('slow');
});
Demo
To show/hide all use:
$('.gwinfo').toggle('slow');
Also, i believe the "gwinfo" divs are not correctly closed on the JSFiddle.

jquery Slide effect on multiple DIVs with embedded close effect

I have many questions here so please be patient with me, very new jquery/javascript user.
Here is my current page http://integratedcx.com/index.php/experience
Basically I would like each of the projects and project categories to have the hidden div, slidedown like a drawer not just appear as they do now.
I have tried to achieve this through jquery without much success, here is my working http://integratedcx.com/temp/slide.html
How do I get the div below the one opening to "ease" down instead of jump
How do I get my close feature (orange box) in recent projects to work properly
How do I get my the project list on the right side of image to hide (as it does on my current page) as well as have the drawer opening effect.
Is there an easy way to i.e. variable to assign this to multiple divs using jquery.
Thank you in advanced for any/all help.
For your question 4, With the following script (based on ComputerArts's answer above), you can easily add the slide effect to a large number of divs:
$(document).ready(function () {
$(".toggle-to-show").click(function (evt) {
var targetdiv = $(evt.currentTarget).attr("data-drawer");
$(targetdiv).slideToggle(1000, function() {
if ($(this).is(':visible')) {
$('.bracket', evt.currentTarget).html('less');
$('.project', evt.currentTarget).hide();
$('.closebox', this).bind('click', function(e) {$(evt.currentTarget).triggerHandler('click');});
}
else {
$('.bracket', evt.currentTarget).html('more');
$('.project', evt.currentTarget).show();
$('.closebox', this).unbind('click');
}
});
})
})
Then, you can mark up the toggle buttons and sliders as follows:
<div class="toggle-to-show" data-drawer="#firstsection">
<div class="project">Project One Heading</div>
<div class="bracket">more</div>
</div>
<div id="firstsection">
<h3>Project One Heading</h3>
stuff
<img class="closebox" src="close.jpg">
</div>
<div class="toggle-to-show" data-drawer="#secondsection">
<div class="project">Project Two Heading</div>
<div class="bracket">more</div>
</div>
<div id="secondsection">
<h3>Project Two Heading</h3>
stuff
<img class="closebox" src="close.jpg">
</div>
<div class="toggle-to-show" data-drawer="#thirdsection">
<div class="project">Project Third Heading</div>
<div class="bracket">more</div>
</div>
<div id="thirdsection">
<h3>Project Three Heading</h3>
stuff
<img class="closebox" src="close.jpg">
</div>
As for points #1 and #2, try this fiddle
I only changed the first script tag to
<script type='text/javascript'>
$(document).ready(function () {
$(".projectx-show").click(function () {
$("#projectx").slideToggle(1000, function() {
if ($(this).is(':visible')) {
$('#projectx-bracket').html('less');
}
else {
$('#projectx-bracket').html('more');
}
});
})
})
</script>
FYI, you don't need to use $(window).load and then $(document).ready... one is enough
As for #3, I don't understand what you're trying to say.
#4, yes there is a way, using classes and keeping the structure the same for every bloc in your page.
http://api.jquery.com/slideDown/
$("#link_id").click(function(){
$("#div_to_show").slideDown();
});
http://api.jquery.com/slideUp/
$('#div_to_close').slideUp();
Using both of the methods from 1, and 2
By using class names instead of IDs for your selectors. For example:
$(".link_class").click(function(){
$(this).parentsUntil('.ex-wrapper').find('.div_to_show').slideDown();
});

Jquery collapsible region

I am trying to make sections of page collapsible. No plan to use accordion, but simple hide/show to save screen space. See the sample code below. The first link has to click twice to make the section hide, and the second one works fine. Neglect this issue, if you can suggest a better way to do it.. In this example, div1 is in open position and div2 hidden initially.
thanks,
bsr.
<!doctype html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
<a class="toggle" href="#">Hide</a>
<div class="toggle">
<p>First div</p>
</div>
<a class="toggle" href="#">Show</a>
<div class="toggle" style="display: none">
<p>Second div</p>
</div>
<script type="text/javascript">
jQuery().ready(function() {
$("a.toggle").toggle(
function() {
$(this).text("Hide");
$(this).next("div.toggle").show();
},
function() {
$(this).text("Show");
$(this).next("div.toggle").hide();
}
);
});
</script>
</body>
</html>
I would use the toggle() function, as it's not only used to bind toggling events, it also toggles visibility is called without any parameters:
jQuery().ready(function() {
$("a.toggle").click(function(){
var $div = $(this).next("div.toggle");
$div.toggle();
if($div.is(':visible'))
$(this).text('Hide');
else
$(this).text('Show');
});
});
The problem with your code is that you're showing/hiding the elements regardless of their initial state. No matter what you do, if you bind events using toggle(func, func), the first function will always be called first.
The reason the first one needs to be clicked twice is because it starts with the div showing. When you click on it the first time, because of the nature of the toggle event, jQuery thinks that you're trying to show it. But it's already showing. So none of the changes take effect.
You can solve this by having everything start out hidden. But if that's not an option, then you'll have to do away with the toggle event listeners and just listen for clicks:
$('a.toggle').click(function () {
var $this = $(this);
if ($this.text() === 'Show') {
$this.text('Hide').next('div.toggle').show();
} else {
$this.text('Show').next('div.toggle').hide();
}
});

Show / Hiding Divs

After cobbling together a few questions I've managed to get this far to showing / hiding divs:
$(document).ready(function(){
$('.box').hide();
$('#categories').onMouseOver(function() {
$('.box').hide();
$('#div' + $(this).val()).show();
});
});
HTML:
<div id="categories">
<div id="btn-top20">Top 20 Villas</div>
<div id="btn-villaspec">Villa Specials</div>
<div id="btn-staffpicks">Our Staff Picks</div>
</div>
<div id="category-content">
<div id="divarea1" class="box">
Content 1
</div>
<div id="divarea2" class="box">
Content 2
</div>
<div id="divarea3" class="box">
Content 3
</div>
</div>
What am I missing?
This will work:
<div id="btn-top20" rel="area1">Top 20 Villas</div>
<div id="btn-villaspec" rel="area2">Villa Specials</div>
<div id="btn-staffpicks" rel="area3">Our Staff Picks</div>
with this code:
$(document).ready(function(){
$('.box').hide();
$('#categories div').mouseenter(function() {
$('.box').hide();
$('#div' + $(this).attr('rel')).show();
});
});
Corrections:
No such function onMouseHover.
Attached the event to every div, not the #categories parent, so this has the right context.
added rel for every div, because val is meaningless.
Working example: http://jsbin.com/ivuxo
You may also want to hide the div on mouse out, in wich case you can use hover:
$('#categories div').hover(
function() { //hover in
$('.box').hide();
$('#div' + $(this).attr('rel')).show();
}, function(){ //out
$('.box').hide();
});
Flexible, generic (and untested!) solution which works with any number of "tabbed" element groups. You just need to specify ".tab-handles a[href=#id_of_target_tab]" hierarchy. As a bonus, the selected tab is remembered between page loads.
$(function() { // Shortcut for $(document).ready()
$('.tab-handles a').mouseenter(function() {
// Trigger custom event 'hide' for sibling handles.
$(this).siblings().trigger('hide');
// Show current tab.
$($(this).attr('href')).show();
}).bind('hide', function() {
// Hide the corresponding tab on custom event 'hide'.
$($(this).attr('href')).hide();
}).each(function() {
// Show tab if its id is found in url as an anchor (or hash).
if (new RegExp($(this).attr('href') + '$')).test(window.location.href))
$(this).trigger('mouseenter');
});
})
Your page can contain any number of the following structure:
<ul class="tab-handles">
<li></li>
<li></li>
</ul>
<div>
<div id="top-villas"> Your tab content goes here. </div>
<div id="villa-specials"> ... </div>
</div>
onMouseOver isn't a valid jquery method, among other things.
I really recommend browsing with google chrome when you're looking to debug javascript, it's error console is very useful for not just determining errors like this, but also for pinpointing the location in the script that is throwing the error, which might be an advantage beyond Firebug in firefox.
(And you can always run firebug lite as well via the bookmarklet even while using chrome, as the firebug lite website will show: http://getfirebug.com/firebuglite)
I used this to toggle my divs:
html
<div class="content-item-news">..</div>
<div class="content-news-extra">...</div>
jquery
$(".content-item-news").click(function() {
$(this).next(".content-news-extra").slideToggle(100);
});
I know this has already had a decent answer and although this isn't jQuery/mooTools - I figured it was worth a mention:
Seven Ways To Hide An Element With Javascript:
http://www.dustindiaz.com/seven-togglers/
:)

Categories