AJAX call to display dynamic data with Tooltipster - javascript

I'm having an issue where my tooltip from Tooltipster is showing the same data everytime I hover a new element, instead of showing new dynamic data everytime I hover a new element.
How can I fix my code so that only one tooltip shows with new dynamic data each time I hover?
I hover an element that's supposed to activate it, creating this console message:
"Tooltipster: one or more tooltips are already attached to this element: ignoring. Use the "multiple" option to attach more tooltips."
Using the 'multiple' option works by generating new tooltips that shows the proper data, but this causes the tooltips to stack on top of each other instead of replacing itself.
function showAsynchronousTooltipForTopicWithName(name) {
var urlToSend = '/API/v1/topic?name='+encodeURIComponent(name.trim());
$.ajax({
type: "GET",
url: urlToSend,
success: function (result) {
showNotification("API Success", 'success');
showTopicsTooltips(result);
},
error: function (result) {
showNotification("Something went wrong", 'error')
}
});
}
function showTopicsTooltips(response) {
var topic = response;
console.log(topic['name']);
// create content based on experts_internal and experts_external properties
$('.tooltip-topics').tooltipster({
animation: 'fade',
theme: 'tooltipster-shadow',
trigger: 'hover',
viewportAware: true,
contentAsHTML: true,
multiple: true,
content: '<div>' +
'<p><b>Team Experts</b></p>' +
'<p>'+ topic['experts_internal'] + '</p>' +
'<p><b>External Experts</b></p>' +
'<p>'+ topic['experts_external'] + '</p>' +
'</div>'
});
}
I was expecting the tooltip to replace the data dynamically every time I hover a different element that has the tooltip, but right now without 'multiple' option it keeps showing the same data for each element, and with 'multiple' option it just generates a new tooltip everytime without removing the last so they end up stacking.

Related

Dynamically-generated table keeps multiplying even though it's being cleared

I have a variety of fields I'm appending to a table (#dvdCollectionBody) in my function loadDvdCollectionView().
The problem: if I click the tag that calls my displayDvd() function, then hit the 'Back' button, everything works as it should. If I click the tag, calling displayDvd() a second time, then click the 'Back' button again, the table will be duplicated, indicating that rows are being appended that aren't getting cleared.
I cannot for the life of me understand why the table keeps appending itself, but only after repeating the process of clicking a 'td' tag more than once.
$(document).ready(function () {
loadDvdCollectionView();
// create on a click
createDvd();
});
function loadDvdCollectionView(){
// hide errors
$('#errorDiv').hide();
// show this view
$('#viewingTable').show();
// empty table body of any preexisting data
$('#dvdCollectionBody').empty();
$.ajax({
type: "GET",
url: "http://localhost:8080/dvds",
success:
function (data, status) { $.each(data, function (index, dvd) {
// append DVD collection to table rows in #dvdCollectionBody
var dvdRow = '<tr><td onclick="displayDvd(' + dvd.dvdId + ')">' + .......
$('#dvdCollectionBody').append(dvdRow);
});
}
// called when <td> tag is clicked
function displayDvd(dvdId){
//hide viewingTable
$('#viewingTable').hide();
// empty preexisting data
$('#releaseYearDisplay, #directorDisplay, #ratingDisplay, #notesDisplay, #dvdTitleHeader').empty();
// show table
$('#dvdDetailsDisplay, #dvdTitleHeader').show();
$.ajax({
type: "GET",
url: "http://localhost:8080/dvd/" + dvdId,
success: function (data) {
$('#dvdTitleHeader').append('
<h3>' + data.title + '</h3>'); $('#releaseYearDisplay').append('
<h3>' + data.releaseYear + '</h3>'); $('#directorDisplay').append('
<h3>' + data.director + '</h3>'); $('#ratingDisplay').append('
<h3>' + data.rating + '</h3>'); $('#notesDisplay').append('
<h3>' + data.notes + '</h3>'); }
}
});
$('#backButton').click(function(){
// hide current display and header
$('#dvdDetailsDisplay, #dvdTitleHeader').hide();
// load main view again
loadDvdCollectionView();
});
}
The problem is that, this piece of code:
$('#backButton').click(function(){
// hide current display and header
$('#dvdDetailsDisplay, #dvdTitleHeader').hide();
// load main view again
loadDvdCollectionView();
});
is placed inside your displayDvd() function.
So when the first time your <td> is clicked, the displayDvd() is called and your #backButton callback is added.
Then you hit the #backButton, the callback function is called, everything should work fine here.
However, when you hit the <td> 2nd time, displayDvd() is called again and another click callback is added to #backButton again, also.
This is where the bug occurred. Now your #backButton have 2 same click callback functions attached. So when you click on it, 2 loadDvdCollectionView() are called simultaneously.
Simply move the piece of code into $(document).ready() callback should fix the problem.
You're hiding the DOM elements, but you're not removing them from the DOM. Try the following to remove the content from dvdDetailsDisplay and dvdTitleHeader:
$('#backButton').click(function(){
// hide current display and header
$('#dvdDetailsDisplay, #dvdTitleHeader').empty();
// load main view again
loadDvdCollectionView();
});

Preppend a new child div ahead of previous child div's jquery

I am trying to a do a simple media posting project. When new records are added to the database I use ajax to add a new child div to a parent div based on the info in the record. I have it working except for the order that children are added in. Doing a prepend does not place the new div as the first child of the parent div, it puts it as the last child of the specified parent. That's no good when I want new posts displayed on top. Here is the code for the file I'm working on. How do I prepend above previously added children?
$(document).ready(function (){
setInterval(function(){
$.ajax({
type: 'GET',
url: 'JSONFile.php',
data: { get_param: 'value' },
dataType: 'json',
success: function(retrieved){
//$("#MainContent").empty();
$.each(retrieved, function(index, i){
$('#MainContent').append('<br><div class="Post"><h2>' + i.UserName + '</h2><br><p>' + i.Content + '</p></div>');
});
}
});
},3000);
});
Instead of using .append, you can use .prepend, which was made for exactly this purpose:
Insert content, specified by the parameter, to the beginning of each element in the set of matched elements.
So, you can use the code:
$.each(retrieved, function(index, i){
$('#MainContent').prepend('<br><div class="Post"><h2>' + i.UserName + '</h2><br><p>' + i.Content + '</p></div>');
});

CKEditor doesn't show content

I have problem with CKEditor. I use setData() method to put content into editor. It works, but only first time I display it. When I click back button in the browser and try to open this view or another once again editor is displayed but no content is in it although the data were returned from database. Have you any ideas how can I resolve this problem?
This is my init method which is invoked in ng-init directive:
$scope.initCKEEditor = function() {
CKEDITOR.replace('questionEditor', {
uiColor: '#C0B9B9',
height: 100,
toolbarCanCollapse: true,
skin: 'kama'
});
};
And this is my method to getting question content from database:
$scope.getQuestionContent = function() {
Database.get("SELECT question_content FROM `question` WHERE question_ID = "
+ $scope.idQuestion, function(response) {
CKEDITOR.instances['questionEditor'].setData(response[0].question_content);
});
};

Can I use dynamic content in a Bootstrap popover?

I am using a Bootstrap Popover in a 'Repeat Region' which displays Testimonials. Each testimonials has a 'View Property Details' button which opens up the popover. In the Pop over I am wanting to display the image associated with each testimonial and details of the image. The image path is stored in a column in the database so to display the image for each testimonial I need to bind the image source to the content but it is not accepting PHP. I am using a script that allows me to write html into the content but the image needs to be created dynamically. Dynamic text works in the 'a' tag 'title' option but not for Content.
Can anyone shed light on this?
Here is what I have.
<script type="text/javascript">
$(document).ready(function() {
$("[rel=details]").popover({
placement : 'bottom', //placement of the popover. also can use top, bottom, left or right
html: 'true', //needed to show html of course
content : '<div id="popOverBox"><img src="<?php echo $row_rsTstmnlResults['image']; ?>" width="251" height="201" /></div>' //this is the content of the html box. add the image here or anything you want really.
});
});
</script>
View Property
var popover = $("[rel=details]").popover({
trigger: 'hover',
placement: 'bottom',
html: 'true'
}).on('show.bs.popover', function () {
//I saw an answer here with 'show.bs.modal' it is wrong, this is the correct,
//also you can use 'shown.bs.popover to take actions AFTER the popover shown in screen.
$.ajax({
url: 'data.php',
success: function (html) {
popover.attr('data-content', html);
}
});
});
One year old :( but this may help another person
Remove your js script and Add This :
var content = $('[id*="yourDivId"]');
var title = "Your title, you can use a selector...";
$('[data-toggle="popover"]').popover({
html: true,
content: function () {
return content.html();
},
title: function() {
return title.html();
}
});
Here is the generic approach, but uses ASP.Net handler to process image. Use similar things in PHP to generate images dynamically
<script type="text/javascript">
$(document).ready(function() {
$("[rel=details]").popover({
placement : 'bottom', //placement of the popover. also can use top, bottom, left or right
html: 'true', //needed to show html of course
content : getPopoverContent(this)// hope this should be link
});
});
function getPopoverContent(this)
{
return '<div id="popOverBox"><img src="/getImage.php?id="'+this.data("image-id")+'
width="251" height="201" /></div>'
}
</script>
<a href="#" rel="details" class="btn btn-small pull-right"
data-toggle="popover" data-image-id="5" data-content="">View Property</a>
$("selector").popover({
trigger : "manual",
placement : 'right',
html : true,
template : '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
}).popover("show");
$.ajax({
async : true,
url : url,
dataType : 'json',
success : function(d) {
$("#phover" + id).attr('data-original-title', d['heading']);
$('.popover-title').html(d['heading']);
$('.popover-content').html(d['body']);
},
beforeSend : function() {
var loadingimage = '<div align="center"><img src="assets/pre-loader/Whirlpool.gif"></div>';
$('.popover-title').html(loadingimage);
$('.popover-content').html(loadingimage);
}
});
my solution is based upon the previous solutions here, with a bit more.
i needed (as usually), all the complexity:
here's how you can create the popover content on demand when the event triggers,
and have the selected element passed to the creating function.
function displayProductPrice(a, tag) {
var div = a.closest('div');
var secs = ['aggregated', 'compare', 'list', 'saved', 'details'];
var title = '';
for (var c in secs) {
var obj = $('.product-price-' + secs[c], div);
if (obj.length) {
if (title) {
title += '<br />';
}
title += obj.html();
}
}
return '<' + tag + '>' + title + '</' + tag + '>';
}
$( document ).ready(function() {
$(".product-price-expand").popover({
content: function() {return displayProductPrice(this, 'h6')},
title: function() {
return $('.product-id', this.closest('div')).html();
},
html: true,
trigger: 'click focus',
placement: 'auto'
});
});
enjoy, hope this helps.

Customizing JavaScript Visualization Toolkit Spacetree Node

I saw many people recommend JavaScript Visualization Toolkit (The JIT) for org chart. I am trying to use SpaceTree of JavaScript InfoVis Toolkit for org chart. The nodes in my org chart is like a component in itself that has employee profile pic, two different icons that show up overlays on click and some 3 lines of simple text having name, title, and number of reports ... each line is separated by a light horizontal line. Something like:
My question is, is it possible to customize the spacetree nodes to such an extent? Can I have Node almost like another "component" or JavaScript object that has its own render method?
I researched on forums and some options I considered are:
$jit.ST.NodeTypes.implement() ... but based on examples I saw, this
seem to be helping in customizing node in terms of shapes etc but
not like layout drawn above. I am referring to customization
something like:
http://groups.google.com/group/javascript-information-visualization-toolkit/browse_thread/thread/a4a059cbeb10ba23/ebf472366cdbbdef?lnk=gst&q=spacetree+nodetype#ebf472366cdbbdef
I tried to set innerHtml in onCreateLabel method in example5.js at:
but it seems to be doing nothing. Although, I'm not sure if that
will be a good way of node customization. Example5 is at the JIT website (I am not allowed to post more than one hyperlink)
Extending Graph.Node ... I am still looking into this option and it
this point of time, I don't know how complicated it is to have space
tree use Graph.myNode and what will Graph.myNode even look like? I
need to think more on those lines and see if it is even feasible.
The Spacetree can be customized very much. The nodes can display images or anything we want. We can have custom click events for the nodes. To have custom events, you will have to redraw the whole tree in the onclick event.
Here is an example. On the success function of the click event. Here I have called the click event on the class "clickable"
$.ajaxSetup({ cache: false });
$(".clickable").live("click", function () {
$.ajax({
url: url + "?id=" + parentId + "&ts=" + new Date().getMilliseconds(),
type: "POST",
cache: false,
dataType: "html",
success: function (html) {
init(html);
}
});
});
The name property can be used to give the image like this:
{id:"90", name:"<a href='javascript:;' class='clickable' name='90'><img src='images/picture.gif' width='30' height='30' alt='pic' /></a>", data:{}, children:[]}
Mark as Answer if useful. thanks.
You could make yourNode the prototype ancestor of Graph.node, set up the slots you want, then add the appropriate render / force code customizations.
I'm using spacetrees and I just set the label type to HTML (which is the default) and you can just use regular HTML and CSS to style your labels. I have images, links, text, etc.
Note that you're working with the label and not the node. The node is the graph component; the label is the visual that you see which represents the node.
When you initialize the spacetree pass in a function for "onCreateLabel":
var myOnCreateLabel = function(label, node) {
label.onclick = function(event) {/* setup onclick handler */};
label.innerHTML = "<img src='myImage.png' />"; // use image in label
};
var myST = new $jit.ST({/*other settings*/ onCreateLabel: myOnCreateLabel});
if you don't mind working with HTML5/Canvas only, try this as well http://orgplot.codeplex.com, simple interface support image node as well.
this.st=new $jit.ST(
{
onCreateLabel: function (label, node)
{
var labelContent = $('<table cellpadding="0" cellspacing="0" class="nodeContainer"><tr><td>' +
'<div class="buttonContainer">' +
'</div></td></tr><tr><td>' +
'<table class="nodeBox" cellpadding="0" cellspacing="0">' +
'<tr>' +
'<td class="iconTd"></td>' +
'<td class="center nodeName">' + node.name + '</td>' +
'</tr></table>' +
'</td></tr></table>');
thisObject.onCreateLabel.raise(thisObject, { labelContent: labelContent, node: node });
if (node.data && node.data.Icon && node.data.Icon != "")
{
labelContent.find(".iconTd").append($("<img src='" + node.data.Icon + "' alt=''>"));
}
else
{
labelContent.find(".iconTd").remove();
}
var lblCtl = $(label).append(labelContent);
if (node.data.Data.ChildrenCount)
{
labelContent.append("<tr><td class='subnode'></td></tr>");
}
if (node.name.length > 40)
{
lblCtl.attr("title", node.name);
node.name = node.name.substr(0, 37);
node.name = node.name + "...";
}
lblCtl.click(function (sender)
{
//thisObject.isNodeClicked = true;
var target = $(sender.target);
if (!target.hasClass("subnode"))
{
if (thisObject.currentSelectedNode)
{
thisObject.currentSelectedNode.buttonContainer.hide();
}
var btnContainer = labelContent.find(".buttonContainer");
thisObject.currentSelectedNode = { nodeElement: lblCtl, node: node, buttonContainer: btnContainer, event: sender };
btnContainer.append(thisObject.$globalButtonContainer.show()).show();
var button = target.closest(".chartActionButton");
if (button.length > 0)
{
thisObject.onNodeAction.raise(thisObject, { name: button.attr("name"), nodeElement: lblCtl, node: node, button: target });
}
else
{
thisObject.onNodeClick.raise(thisObject, thisObject.currentSelectedNode);
}
}
else
{
thisObject.st.onClick(node.id);
}
});
label.id = node.id;
//set label styles
thisObject.setNodeStyle(node.data.Style, label.style);
}
});

Categories

Resources