JQuery For Everyone: Live LoadTip
This code is nothing new to the wonderful people who help support EndUserSharePoint by attending our online workshops. But if you haven’t had a chance to attend the online workshop, this example code replaces the AOP LoadTip example.
I mentioned in a previous post how event delegation, using jQuery’s live events, can create a listener waiting for an event no matter where it happens. By handling the event target, we can achieve the same results as the AOP version with more elegance.
<script type="text/javascript"> if(typeof jQuery=="undefined"){ var jQPath="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/"; document.write("<script src='",jQPath,"jquery.min.js' type='text/javascript'><\/script>"); } </script> <style type="text/css"> #loadTip { background: #6F9DD9; color: #fff; border: 2px solid #6F9DD9; font-size: 10px; padding: 3px; width: 342px; display: none; position: absolute; text-align: right; } #tipContent { background: #fff; padding: 3px; } </style> <script type="text/javascript"> /* * Copyright (c) 2009 Paul Grenier (endusersharepoint.com) * Licensed under the MIT (MIT-LICENSE.txt) */ (function () { jQuery.fn.calcHTML = function () { var arrayList = $(this); arrayList = $.grep(arrayList, function (e, i) { return ($(e).text().match(/<\;.+?>\;|<.+?>/)); }); return $(arrayList).each(function (i, e) { $(e).html($(e).text().replace(/<(.+?)>/g, '<$1>')); }); }; var handleError = function () { return true; }, createLoadTip = function () { var html = "<span>click to close </span>" + "<img style='vertical-align:text-top;' " + "src='/_layouts/images/menudark.gif' alt=''/>"; $(document.createElement("div")).attr("id", "loadTip").html(html).appendTo("body"); $(document.createElement("div")).attr("id", "tipContent").appendTo("#loadTip"); $("#loadTip").click(function (e) { $("#loadTip").hide(); }); }, defaults = { links: "a[href*='DispForm.aspx']", //tags that trigger a preview type: "link", //descriptive name sometimes used in cleanupCSS() key: "a", //find the target url by this key element's attribute target: "", //specify the target suffix: "", //appended to the target url delay: 500, //delay in ms selector: "table.ms-formtable:first", //selector used on target page remove: "", //selector(s) of removed elements from target page source: "", //source parameter appended to urls in preview html: "td[id='SPFieldCalculated']" //fields needing re-rendering }, cleanupCSS = function (p, o) { switch (o.type) { case "discussion": //nothing to do break; default: $("h3.ms-standardheader", p).css({"font-size": "1em"}); $("td", p).removeAttr("width"); $("td.ms-formbody[cellIndex='1']", p).css({width: "100%"}); } }, callback = function (event, p, o) { if (p.contents().length === 0) { return setTimeout(callback(event, p, o), 100); } $("#loadTip").show(); var r = o.remove, h = o.html, a = event.target.href, x = event.pageX, winx = $(window).width(), y = event.pageY, winy = $(window).height(), ly = p.height(), lx = p.width(); if (ly + y + 22 > winy) { y = y - ly - 22; } if (lx + x + 9 > winx) { x = x - lx - 9; } if (y < 0) { y = 0; } if (ly > winy) { $("#loadTip").css({"overflow-y": "auto", "height": winy}); } if (r && r.length > 0) { $(r, p).remove(); } if (h && h.length > 0) { $(h, p).calcHTML(); } $("#loadTip").css({"top": y, "left": x}); }, fire_preview = function (e, p, o) { p.empty(); p.load(o.target + o.suffix + " " + o.selector, function () { p.data("loadTip", o.target); cleanupCSS(p, o); callback(e, p, o); }); }, bind = function (p, options) { window.onerror = handleError; var o = $.extend({}, defaults, options); $(o.links).live("mouseover", function (event) { var elm = $(event.target); switch (o.key) { case "a": if (elm[0].tagName == "A") { o.target = elm.attr("href"); } else { o.target = elm.parents("a:first").attr("href"); } break; case "table": elm = elm.parents("table[ctxname]"); o.target = "/" + elm.attr("dref").replace(/\s/g, "%20") + "/Forms/DispForm.aspx?ID=" + elm.attr("id"); break; case "img": elm = elm.parents("a"); o.target = elm.attr("href"); break; default: //fall through to pass target override } $("#loadTip").css({"top": -1000, "left": -1000, "height": ""}); if (loadTip.timer) { clearTimeout(loadTip.timer); } if (p.data("loadTip") === o.target) { return callback(event, p, o); } loadTip.timer = setTimeout(function () { fire_preview(event, p, o); }, o.delay); event.stopImmediatePropagation(); }); $(o.links).live("mouseout", function (event) { clearTimeout(loadTip.timer); event.stopImmediatePropagation(); }); }; loadTip = function (options) { if ($("#loadTip").length === 0) { createLoadTip(); } bind($("#tipContent"), options); }; }()); $(function(){ loadTip(); //loadTip({type: "wiki", links: "a[href*='.aspx']:has(img.ms-hidden)", key: "table"}); //loadTip({type: "thumbnail", links: "a[href*='Forms/DispForm.aspx']", key: "img"}); //loadTip({type: "person", links: "a[href*='userdisp.aspx']", suffix: "&Force=1"}); //loadTip({type: "discussion", links: "a[href*='Flat.aspx']", selector: "table.ms-disc", remove: "[id^='ToggleQuotedText'], tr.ms-viewheadertr"}); //loadTip({type: "excel document", links: "a[href$='.xls']:has(img.ms-hidden)", key: "table"}); //loadTip({type: "excel document", links: "a[href$='.xlsx']:has(img.ms-hidden)", key: "table"}); //loadTip({type: "word document", links: "a[href$='.doc']:has(img.ms-hidden)", key: "table"}); //loadTip({type: "word document", links: "a[href$='.docx']:has(img.ms-hidden)", key: "table"}); //loadTip({type: "powerpoint document", links: "a[href$='.ppt']:has(img.ms-hidden)", key: "table"}); //loadTip({type: "powerpoint document", links: "a[href$='.pptx']:has(img.ms-hidden)", key: "table"}); }); </script>
I commented out several examples of “loatTip-able” links. By default, only the items pointing to a dispform.aspx page will be displayed. Keeping with the traditions of jQuery plugins, there are lots of options which can change the behavior of tip box.
- JQuery for Everyone: Accordion Left Nav
- JQuery for Everyone: Print (Any) Web Part
- JQuery for Everyone: HTML Calculated Column
- JQuery for Everyone: Dressing-up Links Pt1
- JQuery for Everyone: Dressing-up Links Pt2
- JQuery for Everyone: Dressing-up Links Pt3
- JQuery for Everyone: Cleaning Windows Pt1
- JQuery for Everyone: Cleaning Windows Pt2
- JQuery for Everyone: Fixing the Gantt View
- JQuery for Everyone: Dynamically Sizing Excel Web Parts
- JQuery for Everyone: Manually Resizing Web Parts
- JQuery for Everyone: Total Calculated Columns
- JQuery for Everyone: Total of Time Differences
- JQuery for Everyone: Fixing Configured Web Part Height
- JQuery for Everyone: Expand/Collapse All Groups
- JQuery for Everyone: Preview Pane for Multiple Lists
- JQuery for Everyone: Preview Pane for Calendar View
- JQuery for Everyone: Degrading Dynamic Script Loader
- JQuery for Everyone: Force Checkout
- JQuery for Everyone: Replacing [Today]
- JQuery for Everyone: Whether They Want It Or Not
- JQuery for Everyone: Linking the Attachment Icon
- JQuery for Everyone: Aspect-Oriented Programming with jQuery
- JQuery for Everyone: AOP in Action - loadTip Gone Wild
- JQuery for Everyone: Wiki Outbound Links
- JQuery for Everyone: Collapse Text in List View
- JQuery for Everyone: AOP in Action - Clone List Header
- JQuery for Everyone: $.grep and calcHTML Revisited
- JQuery for Everyone: Evolution of the Preview
- JQuery for Everyone: Create a Client-Side Object Model
- JQuery for Everyone: Print (Any) Web Part(s) Plugin
- JQuery for Everyone: Minimal AOP and Elegant Modularity
- JQuery for Everyone: Cookies and Plugins
- JQuery for Everyone: Live Events vs. AOP
- JQuery for Everyone: Live Preview Pane
- JQuery for Everyone: Pre-populate Form Fields
- JQuery for Everyone: Get XML List Data with OWSSVR.DLL (RPC)
- Use Firebug in IE
- JQuery for Everyone: Extending OWS API for Calculated Columns
- JQuery for Everyone: Accordion Left-nav with Cookies Speed Test
- JQuery for Everyone: Email a List of People with OWS
- JQuery for Everyone: Faster than Document.Ready
- jQuery for Everyone: Collapse or Prepopulate Form Fields
- jQuery for Everyone: Hourly Summary Web Part
- jQuery for Everyone: "Read More..." On a Blog Site
- jQuery for Everyone: Slick Speed Test
- jQuery for Everyone: The SharePoint Game Changer
- JQuery For Everyone: Live LoadTip
Paul,
The old version allowed one to popup a users details when the cursor was placed over a user name in the “assigned to” column. This made it convenient to view the “assigned to” users phone number, email and other details. This new version seems to be missing this function. Is that by design?
Robin,
Remove the comment (”//”) from the third commented example. It has type: person.
I tried this script on a link list and it didn’t work. Apparently the column linked to the DisplayForm is shown as an image which sits above the A itself. I had to add the following if code to the binding fucntion:
Otherwise it works beautifully.
Thanks again for all the good work!
Dominique
Hello Paul,
This is great. I’m getting strange behavior on the Month view for events that span multiple days as they are not popping up when hovering over. On single day view and weekly view the multiple day events work fine.
Single day events work fine on any view.
Can you duplicate this? Any ideas?
Hi,
I have a sharepoint page in which i have added the calendar view to a webpart. I also have CEWP below that contains this script. I am able to see only the url in the popup. It is not showing Title, location, start time etc. What i am missing. Correct me please…..
@Paul,
I made a slight change to the code that should now work with multi-day events. You’ll need to copy/paste the new version.
@Ravi,
This sounds like a custom page. CSS changes, or customized DispForm.aspx can cause things not to to work. I’ve only tested this with default pages and theme.
Thank you – works perfectly!
I found the problem in webpart page. The actual jquery works based on [[ if(!group)group="#MSO_ContentTable"; ]] MSO_ContentTable as main content. If you put this in webpart[custom] page, it will not work. Get the view source of your page and find out the main content id[in my case it is “ctl00_MSO_ContentDiv”. It is working perfectly.
Thank you very much.
I have tried inserting the above code in CEWP on the page with my list items, and it is not working (no pop-up box). Do I need to add this code to the “last version” of LoadTip to make this work?
Paul, you have amazing work! Thanks so much!
I have implemented the tooltip in a CEWP to show list items in several webparts on my “dashboard” page and it works flawlessly, except for 2 scenarios:
1. The tooltip pops up BEHIND some javascript or flash components. I have tried to add in the z-index in the css with no luck.
2. I have two columns I would like to show: title and message. Sometimes the messsage has long links in it and a lot of text and people usually copy and paste the text from an email which results in weird text. The pop-up in this case become huge (literally takes up the whole window) and due to issue 1, can barely be seen at times.
Your help is greatly appreciated!
Thanks again!
Alex
I have a puzzle on the “remove” option
I have a document library with 3 columns, “Title, Name, and URL” – which is a hyperlink.
remove: “td[id!='SPFieldURL']” does what I want — it just shows a URL in the hover form. (It oddly doesn’t show the field name though).
However, remove: “td[id='SPFieldTitle'],td[id='SPFieldName']” does not behanve as expected. It shows ALL fields, and including all 3 titles, and just “whites out” the content od the removed items.
Have you tried this?
Actaully, now that I read the above post I’m starting to understand how this works — the behavior makes sense.
So the question becomes: Is there any way to select entire Fields from the DispForm and choose not to show them?
This syntax will remove specific unwanted rows : I’m sure there is a more elegant way of doing this as this is a manual process.
remove: “tr:eq(0),tr:eq(1),tr:eq(2),tr:eq(3),tr:eq(4),tr:eq(5),tr:eq(6),tr:eq(7)”
The above removes numbered occurences of a – entire row from the DispForm.aspx file. Only useful if you use this in a specific document library that you know which columns you don’t want to display.
Requote:
I have tried inserting the above code in CEWP on the page with my list items, and it is not working (no pop-up box). Do I need to add this code to the “last version” of LoadTip to make this work?
Am I missing something here (obviously). How dod I get this to work?
To get it to work I had to enable (uncomment) the lines at the bottom of the code. There was no “default” tooltip. So, if you want it to work on a Microsoft Word .doc or .docx, uncomment those lines.
(For ‘Field’ read ‘Column’)Great piece of coding and I love the enhancement in this version that gives the ability to remove field data from the display which I’ve used to hide around 8 data fields. However the ToolTip height is not being adjusted to take account of the hidden data and there is a lot of blue space at the bottom. Is it possible to set the height to adjust dynamically based on the fields displayed?
Ignore my last email about ‘removing’ data displayed and height adjustment, must have been a quirk when viewing still in Edit mode. Once saved and published it works perfectly, thanks again.
David
Does this work on a List? I am unable to get this to work by entering in CEWP.
@Timmy,
Yes, it was primarily designed for a list. Make sure your list items have links to the default DispForm.aspx page. If you use something else, you’ll need to adjust the script/configuration as needed.
I’m using Internet Explorer 7 to view this site but cannot view the code due to page errors. Can you email me the code please. It is exactly what I’m looking for to use to preview data in a calendar event.
Thank You :-)
Mylene – This is not a page error. We have just migrated the site to a new server and have not finished updating the code content. Give me five minutes and the code in this article will be available. — Mark
Hi Paul,
I have one question which is not related to above post but i don’t know how to contact you so i am going to ask here
How can i traverse HTML Comments in DOM using Jquery ?do you have any idea on this
Thanks
Ron,
Normally comments are not parsed, so the only method I can think of involves using jQuery’s AJAX methods to call the page as a text file then use regex filters to find the comments in the text.
Thanks Paul,
I thought there should be method like in JavaScript we can use get ElementbyTagName(”!”) .
Thanks for Reply
I don’t know if this is the most efficient method but it works and seems to do the job quickly (should work in all browsers):
Thanks Paul
Hi Paul;
I was Trying to Set Value in People Picker Control with Current Logged in User in sharepoint.
So far I have done following Jquery which give me Current logged in User but i cant set it to People Picker.
Here is Jquery
I know i doing something silly here thats why its not working can you please suggest me
Thanks
@Ron,
See my examples of using the people picker field http://www.endusersharepoint.com/2009/04/20/jquery-for-everyone-pre-populate-form-fields/ (line 53) and http://spff.codeplex.com/. There are really two fields, a textarea and a div.
For the textarea you want to update the val() or .value. For the div, you want to update the text() or html().
Hi, I originally asked this question in the wrong post so I’ll reiterate here. We’re using the above script but need to set its target to a different support file, lets say DispForm2.aspx. Changing or hardcoding the target doesnt appear to be working, it still fetches the value of the old DispForm file. I’ve checked the target attribute in the fire_preview function and it does point to the new file we specified, however it doesnt work.
Any clue as to why? I did take your suggestion in your reply, but it did not work sadly.
@Gus,
In the bind function (line 117), target is selected from the DOM based on the target type (SharePoint puts the link in different places). You want this to be dynamic so it gets the right ID value. The target option you can pass is an override, it will not pick the link up dynamically but always use the hardcoded override (think static page).
You probably just need to change links option to a[href*='DispForm2.aspx'] and if you customized that form, you’ll need to change the selector as well (targets the area of the page to be previewed).
Thanks for your reply, I’ve managed to solve the problem. It was a combination of issues, illegal characters in the URL string combined with the fact that overriding the target attribute using the function paramater doesn’t work, because a link is always issued a value in your if clause, no matter what the value sent in was or what the default target was.
Anyway, keep up your good work.
Is there a way to get the popup window to close without clicking on it? maybe a timer
Do you ever find out how to do this?
1st of all thank you for this script.
I have a problem with this one, I have document library with folder, it works perfectly when you put a file at the root folder of the document library but if you put the file in another level the script doesn’t work…
There’s a solution with that ?
Thank you very much.
Hi AutoSponge,
Thanks for providing this useful script.
I’m attempting to use it to display the attached items on a list item and I’m getting some odd behaviour. When I define parameters to remove rows from the DispForm like SteveC in a previous post ( “tr:eq(0),tr:eq(2)”) the first time the LoadTip is displayed correctly. If I then close the tip and hover over the link again the LoadTip displays incorrectly.
(IE the list has five columns and I am displaying column2, column4, and column5 in the LoadTip, on the second display of LoadTip only column4 is displayed, after that nothing is displayed).
Is there a better way to define the selectors of removed rows from the target page?
Cheers,
Marc S
Is it possible to point the tip to come up on a “name” not “title?
Hi, love the solution but am struggling with one problem.
If I hover over my loadtip url at the top of the page it appears as it should at the top of the page but the further down the page I go it starts to appear next to my mouse icon where as I need it to start at the top of the page. Is there a way to control this behaviour?
Hello Paul, hello all,
run into the same problem like Mark C. does. Repetetive hovering over the same list element decreases the number of shown informations, ends up in an empty box.
Refresh of webpage (F5) fix this for the next view, then again rows are reduced.
I am only interested to display one row, so I can get the informations about attachments (mainly name/title of attachment). This is the last row in my view.
So iI would aks for two tipps, if possible:
a) Can you show me how I can only address the Attachment part of my list?
b) Or can can show me to touch only some elements out of the list (remove all, add #1,#5,#x)?
Finally: Thanks for the script as is, I always have learned from this (and sometimes I understand more of the code behind as with this example)
Thanks a lot for your work!
Kind regards
Michael
Hi there,
Great bit of code that I can really see being useful on my current project.
A question for the people here — has anyone got this working once a regular list has been converted to a Data View Web Part in SPD?
I have found that the tooltips do not appear and that a “Stack overflow at line 30″ error is intermittently thrown.
Anyone else discovered a workaround for this?
Many thanks
Ben