jquery: tooltip is not displaying data after space - javascript

I am trying to show on mouse hover event data using jquery tool tip. have data like this way:
{"description":"marry christmas","date":"2016-12-25"}` that I got from server as JSON string. I am parsing that on my calendar like this way
holi is a variable name that holds above JSON string
this is my import
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
$.each(JSON.parse(holi), function(i, item) {
var holidayDate=item.date+"";
var parts= holidayDate.split("-");
alert("parts:"+parts[2]);
document.getElementById(parts[2]+parts[1]).style.color="green";
var va= document.getElementById(parts[2]+parts[1]).innerHTML;
document.getElementById(parts[2]+parts[1]).innerHTML="<label id="+parts[2]+parts[1]+" title="+
item.description+">"+va+"</label>";
$("#"+parts[2]+parts[1]).tooltip();
});
}
Now when I hover on 25th December it is just showing me marry instead of "marry christamas" I tried this in chrome. please let me what's wrong in this??

You need to add quotes around the title attribute value. Try this:
document.getElementById(parts[2]+parts[1]).innerHTML
="<label id="+parts[2]+parts[1]+" title='"+item.description+"'>"+va+"</label>";
Notice the single quotes after the = and before the > around your item.description variable.
Also, as others have pointed out, avoid writing out the DOM from javascript. It is error prone and hard to maintain.

When constructing the title HTML, you need to take into account how the HTML will be parsed. If your title message has spaces, then the HTML attribute value has to be quoted.
You could clean up your code a lot by leveraging the jQuery APIs, since you're already using the library:
$.each(JSON.parse(holi), function(i, item) {
var holidayDate = item.date + "";
var parts = holidayDate.split("-");
var dayId = parts[2] + parts[1], day = $("#" + dayId);
day.css("color", "green")
.html($("<label/>", {
title: item.description,
html: day.html()
}))
.find("label").tooltip();
});
With jQuery, you can construct new HTML with less ugly quote-wrangling by using the form
$("<tagname/>" {
attribute: value,
attribute: value,
// ...
})
In this case, the code sets the "title" attribute and then the content; the "html" attribute works like the jQuery .html() method.
After that, it finds the just-added <label> element and invokes the .tooltip() method.

Related

How to reveal dynamic data on click with jquery

EDIT: This is a more sound approach, since provided answer may have bugs when implementing a tags, or img tags.
================================================================
I am calling blog data from an API. (I've reformatted the data into an array by month).
So far, the blog titles print to the web page. I'd like a user to be able to click a title and have its description revealed.
Here is some of my code so far:
var blogPosts = $('#blog-posts');
$.each(byMonth, function(key, value) {
var outer = byMonth[key]
$.each(outer, function(k, v) {
var inner = outer[k]
var monthBlogPosts = $('<div class = "month"> </div>').appendTo(blogPosts);
$.each(inner, function(i, obj) {
title = inner[i].Title
description = inner[i].Description
date = inner[i].DatePublished
$('<div class = "title-list"><h3 class = "unique-title">' + title + '</h3></div>').appendTo(monthBlogPosts)
// if a title is clicked, show its Description
showDescription(description);
})
})
});
function showDescription(d){
$('.unique-title').on('click', function(){
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
}
When I click a title, all descriptions print instead of the matching description. I understand this is because I called the function in a nested loop, but I've also had trouble calling the description variable outside of it.
I have also tried
showDescription(title, description)
//...
function showDescription(t, d){
$(title).on('click', function(){
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
}
but then nothing is printed to the html page.
Essentially, I'd like to grab the title index, and print it's respective description when its clicked.
you should use event delegation to attach a click event to the document that will bubble up and trigger when .title-list is the event target.
$(document).on('click', '.title-list', function(event) {
showDescription(event.currentTarget) // pass the element being clicked (we will need it later)
})
you would also need to modify the way you get the description.
you could store you description in a data attribute of .title-list like so:
$('<div class = "title-list" data-description="'+ description +'"><h3 class = "unique-title">' + title + '</h3></div>').appendTo(monthBlogPosts)
so you can now modify showDescription() so it would get the data from the element we pass to the function
function showDescription(element){
var d = $(element).data('description')
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
So ok. From whatever I could understand (by looking at your code). You cannot register an event with simple on for dynamically added element. You have to use on delegate.
Try this
1) remove the function call (inside a loop)
2) delete the entire function showDescription and add event as below:
$('#blog-posts').on('click', '.unique-title',function(){
alert('title clicked').
});
3) As to display the description I think the best way will be to add the description in a div and hide it. Display it later once the title is clicked.
(inside the loop)
$('<div class = "desc" style="display:none">' + description + '</div>').appendTo(monthBlogPosts);
then on #2 above. Replace with this.
$('#blog-posts').on('click', '.unique-title',function(){
$(this).next('.desc').show(); //I am assuming desc will be next to the clicked title here. You can modify it as needed.
});
Finally, this is just an overview of a code so might not work as expected but I am pretty sure this should give you an idea and get you started

Inserting elements to appended elements using JavaScript or jQuery

I am fairly new to JS, and have created a little piece of script and it does exactly what I want which is find some elements then adds elements with data populated from via ajax....
So I go from this...
<select><select/>
to this...
<select>
<option value="{ajax value data}"> {ajax text data} <option/>
...
<select/>
using this piece of script...
filteredSelectIds.forEach(function (item) {
let itemId = '#' + item;
let itemData = item.split('-')[0] + 's';
$.each(data[itemData], function (i, color) {
$(itemId).append($('<option/>', {
value: color.optionValue,
text : color.optionText
}));
});
});
Now, what I am trying to do is at the same time add a Font Awesome icon to each element so I need to end up with something like this,,,,
<select>
<option value="{ajax value data}"><i class="fa fa-icon"> {ajax text data} <i/><option/>
...
<select/>
How would I do that??
I'm also new at JS, try this.
element = '<i class="fa fa-icon"> {0} <i/>'.format("{ajax text data}")
$('<option/>').append( element );
So #brk gave me this solution which worked, and would work for putting an Element inside another
"Create the option tag & i tag & first append itag to option tag and then append option tag to item"
filteredSelectIds.forEach(function (item) {
let itemId = '#' + item;
let itemData = item.split('-')[0] + 's';
$.each(data[itemData], function (i, color) {
var selOption = $('<option value="' + color.optionValue + '"></option>');
selOption.append('<i class="fa fa-icon">'+color.optionText+'<i/>');
$(itemId).append(selOption); }); });
However, although this placed the element inside the element as I wanted, and this could principle could probably be used to place any element within another, Tibrogargan correctly pointed to a question that makes the point that elements cannot be place within elements (Not really the Point of my question, but helpful). My solution was simply using the unicode for the Font Awesome icon and escaping it with \u then used \xa0 for additional spaces as follows:-
filteredSelectIds.forEach(function (item) {
let itemId = '#' + item;
let itemData = item.split('-')[0] + 's';
$.each(data[itemData], function (i, color) {
$(itemId).append($('<option/>', {
value: color.optionValue,
text : '\ue905 \xa0\xa0\xa0' +color.optionText
}));
});
});
Thanks!

jquery storing dynamic innerhtml into usable jquery variable

var = cooldynamicelement
How could I store the inner html I grab with jQuery from my div ie. <div class="username"> </div> to store as an accessible variable in jQuery eg. cooldynamicelement so I can grab and use at different areas of my site by just calling ie. $cooldynamicelement and updates with the dynamic .username element value.
1. Store HTML into localStorage
var dynamicElementHTML = localstorage.dynamicElementHTML || $(".username").html() || "";
localstorage["dynamicElementHTML"] = dynamicElementHTML;
To make it available to other pages a way would be to use the power of localstorage
https://developer.mozilla.org/en/docs/Web/API/Window/localStorage
If you're actually interested in the whole element (not only it's inner HTML) than instead of .html() use .prop("outerHTML")
2. Binding using jQuery (essential idea)
If you only want a way to reflect some variable HTML as actual html and make it alive you could do like:
var $myElement = $("<div />", {
class : "userData",
append : $someDynamicElements,
appendTo : $someParentElement,
on : {
contentUpdate : function() {
$(this).html( $someDynamicElements );
}
}
});
than whenever your $someDynamicElements changes you can trigger a contentUpdate
$myElement.trigger("contentUpdate")
3. Binding using jQuery (concept)
Here's the same elements binding concept gone wild:
// Here we will store our elements
var EL = {};
// Create desired HTML elements like this:
var LIST = {
username: $("<b/>", {
html : "UNKNOWN",
click : function() {
alert( $(this).text() );
}
}),
email: $("<a/>", {
html : "test#test.test",
href : "mailto:"+ "test#test.test"
}),
// add more here, you got the idea.
// don't forget that you can assign any JS / jQuery propery to your element.
// You can go insane using .on() and later .trigger()
};
// Our small "program" that replaces data-bind elements
// with dynamic elements from our list
$("[data-bind]").replaceWith(function(i){
var bind = this.dataset.bind;
if(!LIST[bind]) return;
if(!EL.hasOwnProperty(bind)) EL[bind] = [];
var klon = LIST[bind].clone(true)[0];
EL[bind].push(klon);
return klon;
});
// That's it. Now goes your code ///////////////
$(EL.username).css({color:"red"}); // just to test if it works :D
$("[data-target]").on("input", function(){
var target = this.dataset.target;
$(EL[target]).html( this.value );
});
// P.S: Even having thousands of elements inside EL
// say you have "EL.tableRows" you can do fabulously
// quick stuff like i.e: sorting, cause you iterate over a plain JS array.
// After the sorting of EL.tableRows is done and you need a jQuery
// representation simply use $(EL.tableRows).
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Dynamic element Binding in jQuery</h2>
Enter some text and see the update trigger in different places<br>
<input data-target="username"><br>
Welcome <span data-bind="username"></span> !!<br>
You name is <span data-bind="username"></span> Click the red text!<br>
<span data-bind="email"></span>
Well if you want to have the jqueryObject in a variable, just do this:
$(function(){
window.$cooldynamicelement = $("div.username");
})
that way you're able to use $cooldynamicelement in a global context. If is that what you want. This way you're saving a reference to your .username element and thus every time you use it will be updated.
NOTE: If you decide to do this, be careful with polluting your global context.:

Replace certain html with other html using .html isn't working

I have this html
<div id="items-content">
<p><img class="fr-dib" src="http://i.imgur.com/bEDR9dc.png" data-imgslap="{{image-key}}" style="width: 214px;"></p>
</div>
And i want to replace src="http://i.imgur.com/bEDR9dc.png" with src="http://i.imgur.com/mJyABlG.jpg"
I have the following jquery
$(document).ready(function() {
$('#items-content').html( 'src="http://i.imgur.com/bEDR9dc.png"' ) {
return 'src="http://i.imgur.com/mJyABlG.jpg"';
}
} );
I'm learning JQuery still and I don't know where I have gone wrong. Would appreciate the help.
Update
I plan on using the same method of replacing the image to replace something like data-imgslap= with src=. Basically how do I replace html text 'x' with 'y' (They will only ever be html attributes text being replaced).
Use attr() to solve this problem
$(document).ready(function() { $('#items-content .fr-dib').attr('src', 'http://i.imgur.com/mJyABlG.jpg"'); } );
Or use regular expression
your_string.replace(/(<img\s class\=\"fr-dib\"\ssrc=")(.*?)("\s?\/>)/, "$1http://i.imgur.com/mJyABlG.jpg $3");
Update a DOM img tag's src
You're looking for jQuery's attr() method to update a single attribute's value:
$(document).ready(function() {
$('#items-content .fr-dib').attr('src', 'http://i.imgur.com/mJyABlG.jpg"');
} );
jsfiddle: https://jsfiddle.net/patrickberkeley/0wefe37t/
Update a DOM img src with a value from a data attr
To update one attribute with another attribute's value (in this example updating an image's src with a data attribute's value):
$(document).ready(function() {
var $img = $('#items-content [data-imgslap]');
var newSrc = $img.data('imgslap');
$img.attr('src', 'http://i.imgur.com/' + newSrc + '.jpg"');
} );
jsfiddle: https://jsfiddle.net/patrickberkeley/bx686410/2/
Regex to replace img src in a string
Based on the comments you've left though, it seems like your goal is to a value in a string (rather than updating an img element's src in the DOM).
In order to do that:
var str = '<div id="items-content"><p><img class="fr-dib" src="http://i.imgur.com/bEDR9dc.png" data-imgslap="mJyABlG" style="width: 214px;"></p></div>';
var newSrc = 'http://i.imgur.com/mJyABlG.png';
var newStr = str.replace(/<img(.*)src=[\"|\'](.*?)[\"|\'](.*)/, "<img$1src='" + newSrc + "'$3");
jsfiddle: https://jsfiddle.net/patrickberkeley/qrdt1esz/1/
Notice you *do not $(document).ready() because you're not selecting something from the dom. The above regex should handle: single and double quotes and any combination of attrs on either side of the img's src.

JQuery get calling <script> tag when dynamically loaded

How can I locate the tag which calls a JQuery script, when
the tag is dynamically loaded, so won't be the last
tag on the page?
I'm using the MagicSuggest autosuggest library. I want to give certain suggested items a different background color depending on their contents, which I'm currently doing by adding JQuery inside a tag, which I'm adding on to the String which is returned to be rendered inside the selection div. Then, to get the div the item is suggested in, I need to essentially get the parent() of the tag, and change it's css() properties. How can I get this current script tag however?
I'm currently assigned each new tag an id generated from incrementing a JS variable - which works, but isn't very 'nice'! Is there anyway I can directly target the tag with JQuery?
If it perhaps makes it clearer, here is my current selectionRenderer function.
selectionRenderer: function(a){
var toRet = a.english;
var blueBgScript = "<script id=ft" + freeTextFieldID + ">$('#ft" + freeTextFieldID + "').parent().css('background', 'blue');</script>"
if(a.id==a.english){
toRet += blueBgScript;
freeTextFieldID++;
}
return toRet;
},
Why don't you add some code at afterrender event instead? Add some tag to flag the options that need a different background, then detect the parents and add a class (or edit the bg property) or whatever you like:
var newMS = $('#idStr').magicSuggest({
data: 'states.php',
displayField: 'english',
valueField: 'id',
selectionRenderer: function(a){
var toRet = a.english;
if(a.id==a.english) toRet = "<span class='freetext'>" + toRet + "</span>";
return toRet;
},
});
$(newMS).on('selectionchange', function(event,combo,selection){
var selDivs = $(event.target._valueContainer[0].parentNode).children('div'); //Get all the divs in the selction
$.each(selDivs,function(index,value){ //For each selected item
var span = $(value).children('.freetext'); //It if contains a span of class freetext
if(span.length == 1) $(value).css('background','blue'); //Turn the background blue
});

Categories