Post Reply 
 
Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Solved] Show fired ALOT of times
1st November, 10:39 (This post was last modified: 1st November 10:42 by Lynge.)
Post: #1
[Solved] Show fired ALOT of times
Hi, I have an odd problem.

I am trying to repopulate the qTip with elements cloned from other parts of the page. This must be done every time the tip is show, in order to keep the elements up to date.

When I clone the elements I also change their width. This works fine, so I know that part of my code is being used.
But for some reason, that is the only part that work.

The elements are not really clone, since their events and data are not getting copied along with them, even though I am using .clone(true) and I have tested this to work outside the show function of qTip.
Also when I try to add a class to the first of the copied elements it is taken away. If I step through the script in Chrome, I can see that the class is added as expected, but just before qTip is show, it is removed again. I cannot see what removes it.

So in trying to figure this out, I put some alerts inside the code that call qTip and inside qTip's show function.
[php]
if (!$(this).data('qtip')) {
alert('render');
$(this).qtip(qtipvar);
}
alert('before');
$(this).qtip('show');
alert('after');

#inside the show function in the optionset that is in qtipvar

events: {
show: function(e, api) {
alert('inside');
[/php]

Now, when I click to have a qTip shown. 'render' is fired (which I expect it to) then 'before' then 'inside' is fired twice and then 'after' is fired, but still no qTip is shown. For some reason the qTip only appears when I close that last alert box. I dont get it, shouldn't qTip be there by the time that the last alert is triggered? Its after the code the should show it.

The really weird part is, that the more elements that are cloned into the tip, the more times the 'inside' alert is triggered. 2 for each element. But only the 2 for the first element is show before the tip. The rest is shown when the tip is already shown on screen.

I am really confused. Something is not right here.

If you need anymore info, just ask, but I cannot post it all as it is an internal project that is not yet released.

Many thanks for any help you can provide.
Find all posts by this user
Quote this message in a reply
1st November, 14:27
Post: #2
RE: Show fired ALOT of times
So, I thought I might be doing this the wrong way.
Maybe I should be doing all of this in the 'content' setting, but for that to work I have to remove the qtip every time it is closed so it can be rendered again.

But I cannot remove it.
I am guessing that its the api method 'destroy' that is used for this, but when I try to use it, I get this error


Uncaught SyntaxError: Invalid regular expression: /(^|\.)qtip\-0(\.|$)/: Stack overflow

And its the same with most of the other api methods. Only one I found working was .hide()

I have tried seeing where the elements stop being clones and I cannot get to the part that does it. For at long as I can trace the, they still retain their .data() and events. But when I look at them in the tip, they have nothing. Only the html of the originals.

This is giving a (un)healthy amount of grey hair
Find all posts by this user
Quote this message in a reply
2nd November, 09:29
Post: #3
RE: Show fired ALOT of times
If I set overwrite to true, and then try to create a new qTip on the same target, I get the same stack overflow error.
qTip is, for some reason, completely unable to remove itself.
Find all posts by this user
Quote this message in a reply
2nd November, 15:46
Post: #4
RE: Show fired ALOT of times
Lynge, have you got a working example of the error that's corruing so I can take a look?

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
3rd November, 10:55 (This post was last modified: 3rd November 11:16 by Lynge.)
Post: #5
RE: Show fired ALOT of times
#Craig
Absolutely.

This is a condensed example, but I have tested it and it also runs the show method twice and also gives the exception when trying to use api.destroy() or similar.
[php]
#The trigger

$('#qtip_test').click(function() {
if (!$(this).data('qtip')) {
$(this).qtip(testqtipvar);
}

$(this).qtip("show");
});

#The testqtipvar

testqtipvar = {
content: {
text: 'content content and content',
},
position: {
container: $('div.wrapper'),
at: 'top middle',
my: 'bottom middle',
adjust: {
screen: true,
offset: true,
}
},
show: {
event: '',
target: false,
},
hide: {
event: '',
fixed: true,
},
style: {
tip: true,
},
events: {
show: function(e, api) {
alert('show running');
},
},
};
[/php]

Maybe it is because of the way I trigger qTip, but I have tried using api.show() instead and it just gives me an error or does nothing at all.

Hope you can make some sense of it Smile Because I have been looking around at the other tooltips in search of a replacement and none of them even comes close to qTip feature-set or ease of integration. Even in my case where it is used in a way it was most likely not intended it is the best tool for the job. Apart from this error (and hey, its a trunk version so it should have errors) then I have to say it is a very nice piece of JS.
And just in case you can see something wrong with it, here is the original code.
The cloning works, but as I said in the first post, it never gets the data or events cloned along with it.
And the class added to the first span is not there either. It is present for some time if I step through the execution, but at some point I cant track it anymore and then just before the tip is shown, it is removed again. Or more likely, the element is replaced with a straight html copy of the source from where it is cloned, since at that point the .data() also disappears.

[php]

qtipvar = {
overwrite: true,
content: {
text: String($('#TBC-hidden-container').html()),
},
position: {
container: $('div.wrapper'),
at: 'top middle',
my: 'bottom middle',
adjust: {
screen: true,
offset: true,
}
},
show: {
event: '',
target: false,
},
hide: {
event: '',
fixed: true,
},
style: {
tip: true,
},
events: {
show: function(e, api) {
// alert('inside');
JTS_TBC_master_switch = true;
var new_width = $(api.elements.target).width();
var bigday_container = $('.TBC-bigday-container', api.elements.content);
bigday_container.css('width', String(new_width * JTS_TBC_multiplier) + 'px');

bigday_container.children().empty().remove();
// alert($(api.elements.content).html());
// alert(e);
$(api.elements.target).children('.spanblock').each(function() {
var newspan = $(this).clone(true);
$(newspan).width($(this).width() * JTS_TBC_multiplier);
old_left = ($(this).css('left')).replace("px", "");
$(newspan).css('left', (old_left * JTS_TBC_multiplier) + 'px');
bigday_container.append($(newspan));
tmp_data = $(this).metadata();
// alert(tmp_data.noget);
});

var tb_cont = $('.TBC-container', api.elements.content);
JTS_TBC_switch_inputs(tb_cont, 'off');
bigday_container.children('span.spanblock:first').addClass('TBC-bigday-bigblock-selected');

jts_cont = $($(api.elements.target).closest('td.JTS-Times-Col'));
jts_cont.css('overflow', 'hidden');
return true;
},
hide: function(e, api) {
// alert('hiding');
JTS_TBC_master_switch = false;
jts_cont = $($(api.elements.target).closest('td.JTS-Times-Col'));
jts_cont.css('overflow', 'auto');
}
}
};
[/php]
Find all posts by this user
Quote this message in a reply
3rd November, 20:26
Post: #6
RE: Show fired ALOT of times
Why not just set overwrite to false and use .live instead? This seems like a better option:

JS Code
$('.selector').live('click', function(event) {
   $(this).qtip({
      overwrite: false,
      show: {
         event: event.type,
         ready: true // Need this so it shows on first event-fire
      } 
   });
});

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
3rd November, 20:59
Post: #7
RE: Show fired ALOT of times
The overwrite was just left from a test of it. I was trying a different approach.
I am indeed using .live, the top section is just a simple cut down test to see if I somehow messed it up myself.

When adding ready:true, I get:
[php]
Uncaught TypeError: Cannot read property 'handler' of undefined
[/php]
from jQuery

Any ideas?
Oh and many thanks for your time Smile
Find all posts by this user
Quote this message in a reply
4th November, 11:57
Post: #8
RE: Show fired ALOT of times
I can post the real code if you like, but the simplified example at the top, produces the exact same error and has the same behavior.

Just let me know.
Find all posts by this user
Quote this message in a reply
5th November, 09:45
Post: #9
RE: Show fired ALOT of times
I took my head out of my rear-end and looked properly at the code you posted.

Then I got rid of all the errors and this is what I have now:
[php]
$('#qtip_test').live('click', function(event) {
if (!$(this).data('qtip')) {
$(this).qtip({
content: 'content content content',
overwrite: false,
show: {
event: event.type,
ready: true, // Need this so it shows on first event-fire
target: false,
},
hide: {
event: event.type,
fixed: true,
},
events: {
show: function(e, api) {
alert('show running');
},
},
});
}
$(this).qtip("show");
});
[/php]
This produces no errors and it only runs the show method once. Great, but for some reason it only runs the show method the second time the element is clicked.

The qtip shows up in the HTML the first time I click the element, but for some reason it completely ignores the line $(this).qtip("show");
The alert I have inside the show method is only shown on the second click.

How can I make it do both at the same time?
Find all posts by this user
Quote this message in a reply
5th November, 13:41
Post: #10
RE: Show fired ALOT of times
So I now have it working. The data is being cloned correctly and everything.

this is how the code looks now:
[php]
$('div.timeblock-container').click(function(event) {
child_count = $(this).children('.spanblock').size();
if (child_count < 1) {
JTS_create_timeblock({'cont_width': $(this).width(), 'tbparent': this, 'tbowner': ($(this).metadata()).tbowner});
} else {
if (!JTS_TBC_master_switch) {
// if (!$(this).data('qtip')) {
$(this).qtip({
overwrite: true,
content: {
text: String($('#TBC-hidden-container').html()),
},
position: {
container: $('div.wrapper'),
at: 'top middle',
my: 'bottom middle',
adjust: {
screen: true,
offset: true,
}
},
show: {
event: event.type,
target: false,
ready: true,
},
hide: {
event: false,
fixed: true,
},
style: {
tip: true,
},
events: {
render: function(e, api) {
JTS_TBC_master_switch = true;
var new_width = $(api.elements.target).width();
var bigday_container = $('.TBC-bigday-container', api.elements.content);

bigday_container.css('width', String(new_width * JTS_TBC_multiplier) + 'px');
bigday_container.attr('data-tbowner', ($(api.elements.target).metadata()).tbowner);
bigday_container.children().empty().remove();

$(api.elements.target).children('.spanblock').each(function() {
var newspan = $(this).clone(true);
$(newspan).width($(this).width() * JTS_TBC_multiplier);
old_left = ($(this).css('left')).replace("px", "");
$(newspan).css('left', (old_left * JTS_TBC_multiplier) + 'px');


$(newspan).appendTo(bigday_container);

});


var tb_cont = $('.TBC-container', api.elements.content);
JTS_TBC_switch_inputs(tb_cont, 'off');
bigblock = bigday_container.children('span.spanblock:first');
JTS_TBC_mark_bigblock(bigblock);

jts_cont = $($(api.elements.target).closest('td.JTS-Times-Col'));
jts_cont.css('overflow', 'hidden');
},
hide: function(e, api) {
// alert('hiding');
JTS_TBC_master_switch = false;
jts_cont = $($(api.elements.target).closest('td.JTS-Times-Col'));
jts_cont.css('overflow', 'auto');
}
}
});
}
[/php]

There is only one thing. I moved from show to render to make it work, but it makes no difference to me.

There is a couple of things I have noticed though.
Render is fired twice.
The function JTS_TBC_mark_bigblock is also triggered but it has no effect. Its job is to add a class to the first child of the bigday container, but no class is added.

And just as a quick note to anyone having similar problems, I changed the append method from
[php]
$(container).append($(newspan);
[/php]
to:
[php]
$(newspan).appendTo($(container));
[/php]

For some reason this cured the problems with .data not being cloned properly. I have no idea why, since they should just be reverse of each other, but there it is.

If you can tell me why render is fired twice and why I cannot add classes to elements within the tooltip then I would be happy, but the time pressure is much smaller now that I can move on with the project Smile

Many thanks for your time so far. And thanks for a great tooltip
Find all posts by this user
Quote this message in a reply
9th November, 21:02
Post: #11
RE: Show fired ALOT of times
Great to see you got it working Lynge! I can't tell from your code why render would be firing twice... are you on about the actual events.render method? Since the tooltiprender event is only ever fired once it sounds like you might be binding that method twice somewhere... other than that I can't really think of anything that would be causing that.

Also, can't add classes to elements within the tooltip? It should be as simple as using addClass? Or maybe I'm missing something.

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
10th November, 09:54
Post: #12
RE: Show fired ALOT of times
ah, yes. Im talking about the events.render method.
My first thought was the same as yours. I must be calling it twice by mistake, but I have tried creating a clean HTML file and using the same trigger style as I am now on a qtip that has nothing but an alert(); inside its events.render and the alert comes up twice when the tooltip is activated.

And yes, it should be as simple as using addClass, but for some reason its not working.
If I pause script execution in the inspector, I can see that the class is added and for as long as I can see the element, it still has the newly added class, but when the tooltip is shown, it no longer has any class.

Its just weird that I can change the elements width and all sorts of things and they keep those settings, but trying to give it a new class, does not work.
Find all posts by this user
Quote this message in a reply
10th November, 11:34
Post: #13
RE: Show fired ALOT of times
Lynge, I've setup a sample page here: http://jsfiddle.net/craga89/6dyZt/1/

It render event seems to fire only once... perhaps you actually creating TWO tooltips that are triggering two separate events? I disgress...

Also, what class are you trying to apply and to what element?

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
21st November, 16:34
Post: #14
RE: Show fired ALOT of times
Hi again. Sorry about the delay, got caught up in work on different parts of the project.

So I have tested my own code and the jsfiddle.
The problem was two-fold.
I was calling qtip inside a normal jQuery .click() event, with Show.event set to 'click' and therefor It would probably trigger twice. This I moved qTip outside the click event and it still fired both render and show twice. It also only fired render the first time around despite the fact that it was set to overwrite.
Then I included the qTip you had put in the jsfiddle and all (or almost) my troubles went away.

Now it behaves exactly like the one you set up.
I have only one or two little bugs.
What ever element I set the qTip on, gets its data removed. I am using the metadata plugin and all data on the element just goes undefined. Cant figure out why, but as soon as I comments out the qTip code, then its available again.
Thats a minor thing, I have just attached data to both these elements and their parent elements, so I get by.

But It also means that I cannot access the data inside the show/render functions of qTip:

Also inside my show function I have this:
[php]
target_data = $(api.elements.target).metadata();
[/php]
It contains no data at all
BTW: I am using metadata in the HTML5 setting, if thats any help in tracking this. I dont know if this is enough info, but if not, by all means, please let me know.

The next thing is a pain.
Is it possible to somehow tell qTip that it must never show itself unless I specifically call its show method from somewhere else? I have some fields that should only display a qTip if they have children and my normal jQuery takes care of creating those, but I dont want qTip to fire right after they are created, only when the element is clicked again, with children in it, should qTip then show itself.
So if I can somehow tell qTip to have no trigger at all, then I can do the rest myself. That would be great.

Any help here, would be really great Smile
Find all posts by this user
Quote this message in a reply
23rd November, 02:11
Post: #15
RE: Show fired ALOT of times
Hmm the data bug should be fixed in the latest commit, as I added in support for the new HTML5 data-* attributes available in metadata 2.1.

You can tell a qTip not to show on any condition except when show is called by specifying show.event as false. That should be what you need.

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
23rd November, 11:37
Post: #16
RE: [Solved] Show fired ALOT of times
Hmm, I still cant make metadata work.

Thanks for the tip on settings show.event to false, but it has caused a new problem for me.
It does exactly what I want, but now all qtips are prerendered and this will become a problem since this page will contain up to 4200 elements that could spawn a qtip.

To have all 4k qTip rendered at page load, would most likely prevent all but the most powerfull of computers from viewing the page.
I have set core.prerender:false, show.ready:false, and content.prerender:false.
And I have tried different combinations of them, none of it works. Whats more weird is that no matter if I click all the target elements, it does not use more than one or two of the prerendered tooltips.

As soon as I set show.event:'click' it stops this and only renders qtips when I click or activate show.
Find all posts by this user
Quote this message in a reply
23rd November, 23:29
Post: #17
RE: [Solved] Show fired ALOT of times
How are you actually using the metadata with qTip?

This particular problem with declaring show.event as false has now been fixed in the latest commit Smile Check it out!

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
24th November, 08:28
Post: #18
RE: [Solved] Show fired ALOT of times
YAY! Smile No more qTip-corpses all over the source Big Grin

On the metadata. In my events.show I have:
JS Code
alert(($(api.elements.target).metadata()).tbowner);

Just for testing, but it returns undefined, but its not only qTip that cannot acces it. As soon as qTip is configured for a set of elements, no matter if the tip has been rendered and/or shown, then no other code on the page can access metadata for those elements. Very strange.

I can show you the entire "new" show event, but only if you think you need it. Project is not online yet so Im trying to minimize the amount of it that ends up on the web Wink

In any case, many thanks for the super support so far Big Grin
Find all posts by this user
Quote this message in a reply
24th November, 15:52
Post: #19
RE: [Solved] Show fired ALOT of times
Hmm curious, what version of metadata are you using? 2.1? I'm testing this on a very simplistic implementation and the metadata works fine even after qTip initialisation: http://jsfiddle.net/craga89/6dyZt/

Also, try out the latest commit and see if it makes a difference to you. Fixed a problem with the library editing metadata by accident.

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
24th November, 16:15
Post: #20
RE: [Solved] Show fired ALOT of times
If you are certain (and I have no doubt you are right) that the last jsfiddle is working, then it might be a bug somewhere else.
Because it is not working here. The qtip should show on hover, and contain whatever was extracted from the data-ha, right? No qtip shows.

I thought it was my browser, but the jsfiddle does not work in either safari(osx) chrome(osx) firefox(win7).

I got a error saying that metadata.js was not loaded, so I found one at google and loaded it to jsfiddle. This removed the error, but gave me an error from qtip saying:
JS Code
options.content is undefined
 
Line 1663


I will try out the latest commit tomorrow and see what that does. And I have to start doing some more crossbrowser tests on my project, so I will include the page with qtip on it as well, just to see if it makes any difference.
Find all posts by this user
Quote this message in a reply
24th November, 17:10
Post: #21
RE: [Solved] Show fired ALOT of times
Woops my bad! Sent the wrong jsfiddle link. Check this instead: http://jsfiddle.net/craga89/6dyZt/8/

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
25th November, 13:23
Post: #22
RE: [Solved] Show fired ALOT of times
Ah, yes. That works, but its not quite like what I am doing.
I have discovered something though. If I access the metadata before I call qTip on them, it stays put. Both inside qTip and on any subsequent call to the elements by anything else.

What I do is this:
JS Code
$('div.timeblock-container').each(function(index) {
					data = $(this).metadata(); // It does not matter if it is this or the next line, one is enough. As long as something tries to read the metadata then all is well
					console.log( $(this).metadata() );
				});
 
 
				$('div.timeblock-container').qtip({ //Then all the qtip conf follows


Then it gets really weird. No matter if qtip destroys the metadata or not (i.e. I use the above fix or not) the date-something attributes are still on the element even inside qtip, so why does the metadata plugin not read them again? I mean, thats how it got the data in the first place.

Im not actually using the metadata method of qtip since I do some custom work with the data on every show. So I try to access it in my events.show, but even if I dont do that, qTip still removes or disables the data.

Would it make this easier if I just mailed you a zip with a static copy of the page Im working on? Would rather not have it plastered all over the web, but there should be no problem sending you a copy.
Find all posts by this user
Quote this message in a reply
25th November, 14:36
Post: #23
RE: [Solved] Show fired ALOT of times
That would be fine Lynge Smile It does seems rather odd... I just can't think why qTip would be causing this... all it does is access the metadata and copy the object.

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
25th November, 15:05
Post: #24
RE: [Solved] Show fired ALOT of times
Ye, cant think of a reason for this either. It's probably something stupid I wrote and then forgot about again thats causing it. But I cannot make it any further than it completely disappears when I disable qtip.

I will just make you a copy of it, maybe you can see what it is. Brace yourself, it gonna be the worst piece of Javascript you have ever seen Smile
Find all posts by this user
Quote this message in a reply
28th November, 23:18
Post: #25
RE: [Solved] Show fired ALOT of times
As it turns out ,this is actually an issue with how the metadata plugin works. For some reason it stores an the metadata object even if no data is detected? Meaning qTip was actually preventing it from being read by simply initially reading it beforehand! Weird. Submitted a patch to the metadata plugin and also added in a fix to the latest commit. Thanks for catching this one Lynge Smile

Craig Thompson
Web Developer / Designer
Craigsworks
http://www.craigsworks.com
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  [Solved] How can I manually show qtips when needed? yougotnet 3 224 28th March 15:40
Last Post: Craig
  [Solved] Multiple show/hide events with different behaviour fraze 2 267 7th March 10:59
Last Post: fraze
  [Solved] Dynamically show tooltip gnatok 6 493 31st January 12:44
Last Post: gnatok
  [Solved] AJAX Show Event hoodedperson70 2 368 25th January 21:15
Last Post: hoodedperson70
  [Solved] Don't show for touch events rsmith4321 3 411 25th January 15:47
Last Post: Craig
  [Solved] show: { event: 'focus mouseenter' }, - not working pitchfol 14 845 18th January 15:59
Last Post: Craig
  [Solved] Show Only When Calling "toggle" or "show" ChvyVele 3 424 17th January 21:53
Last Post: ChvyVele
  show qtip on blur Sobek 0 356 9th December 10:07
Last Post: Sobek
  [Solved] Show image content in qTip yenni104 1 774 21st November 21:30
Last Post: Craig
  [Solved] Focus on textfield within tooltip on show ck510 2 728 2nd November 19:42
Last Post: ck510



User(s) browsing this thread: 1 Guest(s)