I'm new to jQuery and I can't figure out a solution for my problem.
I'm using jQuery easytooltip on some SVG objects in my website. Everything is working fine but I need to change some attributes of the tooltip on runtime. My document.ready function is like this:
$(document).ready(function () {
$("polygon").easyTooltip({
tooltipId: "easyTooltip2",
content: 'hello'
});
});
I want to be able,( on mouseover on my polygons) to read out attributes from my polygons and pass them into the content attribute, which is showed when the tooltip is showing... How can I access the content value to change it on runtime?
my plugin code now looks like this:
(function ($) {
$.fn.content = function (_content) {
$(this).easyToolTip({ content: _content })
};
$.fn.easyTooltip = function (options) {
// default configuration properties
var defaults = {
xOffset: 10,
yOffset: 25,
tooltipId: "easyTooltip",
clickRemove: false,
content: "",
useElement: ""
};
var options = $.extend(defaults, options);
var content;
this.each(function () {
var title = $(this).attr("title");
$(this).hover(function (e) {
content = (options.content != "") ? options.content : title;
content = (options.useElement != "") ? $("#" + options.useElement).html() : content;
$(this).attr("title", "");
if (content != "" && content != undefined) {
$("body").append("<div id='" + options.tooltipId + "'>" + content + "</div>");
$("#" + options.tooltipId)
.css("position", "absolute")
.css("top", (e.pageY - options.yOffset) + "px")
.css("left", (e.pageX + options.xOffset) + "px")
.css("display", "none")
.fadeIn("slow")
}
},
function () {
$("#" + options.tooltipId).remove();
$(this).attr("title", title);
});
$(this).mousemove(function (e) {
$("#" + options.tooltipId)
.css("top", (e.pageY - options.yOffset) + "px")
.css("left", (e.pageX + options.xOffset) + "px")
});
if (options.clickRemove) {
$(this).mousedown(function (e) {
$("#" + options.tooltipId).remove();
$(this).attr("title", title);
});
}
});
};
})(jQuery);
You could do:
$("polygon").mouseover(function() {
$("polygon").easyTooltip({
tooltipId: "easyTooltip2",
content: 'changedContent'
});
});
this would recreate the tooltip: a better option would be to modify only the content, i'll look into the api to see if it's possible. (it's not possible to do with the api provided by the plugin i think, re-create the tooltip)
Check out .live():
$("polygon").live("mouseover", function() {
$("polygon").easyTooltip({
tooltipId: "easyTooltip2",
content: 'hello'
});
});
More info.
Related
I have a jquery function to turn my links into google map links. My links are dynamic and pulled from db. So some of the links will be blank depending if that post has that data or not.
PROBLEM: If the post does not have data for that link (field), my function will litteraly write "False" on the front end instead of just being left blank (I want it to just be blank if there is no data.
I think it just needs to be made into an if / else statement but im not very good with jquery and need help
Here is the function: ( (retailers_init['full_address']) ) is the hook for the data)
$('address').each(function () {
var link = "<a href='http://maps.google.com/maps?q=" + encodeURIComponent(retailers_init['full_address']) + "' target='_blank'>" + (retailers_init['full_address']) + "</a>";
$(this).html(link);
});
And here is the larger function that this function (that changes (retailers_init['full_address']) to a google map link) resides in.
function init(retailer) {
var retailers_init = (typeof (retailer) != 'undefined') ? retailer : (typeof (retailers[0]) != 'undefined') ? retailers[0] : 'undefined';
if (typeof (retailers_init) !== 'undefined') {
var image = $('.storeinfo ._image');
var phone_number = $('.storeinfo ._phone_number');
var email = $('.storeinfo ._email');
var website = $('.storeinfo ._website');
var title = $('.storeinfo ._title');
var full_address = $('.storeinfo .full_address');
image.stop().animate({
'opacity': '0'
}, 100, function() {
image
.removeAttr('style')
.attr('src', image.attr('data-load'))
.addClass('loading')
.animate({
'opacity': '1'
}, 200);
});
$('<img/>').load(function() {
image.stop().animate({
'opacity': '0'
}, 200, function() {
image.removeClass('loading');
image.attr('src', retailers_init['image']);
setTimeout(function() {
image.css({'margin-top': '-' + (image.height() / 2) + 'px'});
image.animate({
'opacity': '1'
}, 200);
}, 100);
});
}).attr('src', retailers_init['image']);
title.html(retailers_init['title']);
full_address.html(retailers_init['full_address']);
phone_number.html(retailers_init['phone_number']);
email.attr('href', 'mailto:' + retailers_init['email']).html(retailers_init['email']);
website.attr('href', retailers_init['website']).html(retailers_init['website']);
$('address').each(function () {
var link = "<a href='http://maps.google.com/maps?q=" + encodeURIComponent(retailers_init['full_address']) + "' target='_blank'>" + (retailers_init['full_address']) + "</a>";
$(this).html(link);
});
}
}
One of the issues I have with this script is that I have to have a link tag to get the rel from it. I am looking at doing descriptions when user mouseover's a table row.
What I need: If TD has desc, append text.
<td desc="blah blah blah">
this.screenshotPreview = function () {
xOffset = 20;
yOffset = 30;
$("tr:has(a[desc])").hover(function (e) {
var text = $(this).find('a').attr('desc');
$("body").append("<p id='screenshot'>" + text + "</p>");
$("#screenshot")
.css("top", (e.pageY - yOffset) + "px")
.css("left", (e.pageX + xOffset) + "px")
.fadeIn("fast");
},function () {
this.title = this.t;
$("#screenshot").remove();
});
$("a.screenshot").mousemove(function (e) {
$("#screenshot")
.css("top", (e.pageY - yOffset) + "px")
.css("left", (e.pageX + xOffset) + "px");
});
};
// starting the script on page load
$(document).ready(function () {
screenshotPreview();
});
JSFIDDLE: http://jsfiddle.net/zD99p/1/ (in jsfiddle, it still uses rel instead of desc. You can code it either way, I can change that with no problem)
You can use data- attributes:
http://jsfiddle.net/MWkXJ/
<td data-desc="..."></td>
$("td[data-desc]").hover(function (e) {
var text = $(this).data('desc');
//...
Maybe something like this:
...
$("td[desc]").hover(function (e) {
var text = $(this).attr('desc');
$("body").append("<p id='screenshot'>" + text + "</p>");
...
And change html to this:
<td desc="blah blah">content ...
http://jsfiddle.net/6yMNM/
in your JSFIDDLE you missed a closing </a>. I changed that and changed the <a>to a <div>and it worked. look here.
I'm trying to set the height, width and background image of a <ul> element.
Here's what I've got for my Backbone.View:
var RackView = Backbone.View.extend({
tagName: 'ul',
className: 'rack unselectable',
template: _.template($('#RackTemplate').html()),
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
attributes: function () {
var isFront = this.model.get('isFront');
var imageUrlIndex = isFront ? 0 : 1;
return {
'background-image': 'url(' + this.model.get('imageUrls')[imageUrlIndex] + ')',
'height': this.model.get('rows') + 'px',
'width': this.model.get('width') + 'px'
};
}
}
This doesn't work because the attributes are not written into a 'style' property of the element. Instead, they're treated like attributes... which makes sense because of the function name, but it has left me wondering -- how do I achieve something like this properly?
The image, height and width are immutable after being set, if that helps simplify...
Do I just wrap my return in a style? That seems overly convoluted...
Here's the generated HTML:
<ul background-image="url(data:image/png;base64,...)" height="840px" width="240px" class="rack unselectable">
</ul>
EDIT: This works, but I'm not stoked:
attributes: function () {
var isFront = this.model.get('isFront');
var imageUrlIndex = isFront ? 0 : 1;
var backgroundImageStyleProperty = "background-image: url(" + this.model.get('imageUrls')[imageUrlIndex] + ");";
var heightStyleProperty = "height: " + this.model.get('rows') + 'px;';
var widthStyleProperty = "width: " + this.model.get('width') + 'px;';
return {
'style': backgroundImageStyleProperty + ' ' + heightStyleProperty + ' ' + widthStyleProperty
};
},
You could just use the jquery css function in your render function:
render: function () {
this.$el.html(this.template(this.model.toJSON()));
var backgroundImageStyleProperty = "background-image: url(" + this.model.get('imageUrls')[imageUrlIndex] + ");";
var heightStyleProperty = "height: " + this.model.get('rows') + 'px;';
var widthStyleProperty = "width: " + this.model.get('width') + 'px;';
this.$el.css({
'height' : heightStyleProperty,
'width' : widthStyleProperty,
'background-image': backgroundImageStyleProperty
});
return this;
},
In Marionette, right in your view you can call:
onRender: function () {
this.$('yourElement').css('whatever', 'css');
},
The only way to do this is to pass in the attributes using a style attribute as described in the question. In backbone, the attribute map is passed directly into jQuery by this line of code:
var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
So, there is no way to pass in styles as a Javascript object.
im trying to create this function in javascript but its not working, im a bit new to js, so i don't what im really doing wrong here.
the code:
<div id="test">TESTING</div>
JS:
function animateDiv(div){
var text = $('#' + div + '"').text();
var doAnimate = function() {
$('span').each(function() {
var that = $(this);
setTimeout(function() {
that.animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
},that.index()*100);
});
}
$('#' + div + "'").html('');
for(i=0; i<text.length; i++) {
$('#' + div + "'").append('<span>'+text[i]+'</span>');
if(i==text.length-1) doAnimate();
}
}
// using the function here to run animation on div test from html
animateDiv(test);
the jsfiddle is here: http://jsfiddle.net/aA8Un/3/
This works now
function animateDiv(div){
var text = $('#' + div.id).text();
var doAnimate = function() {
$('span').each(function() {
var that = $(this);
setTimeout(function() {
that.animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
},that.index()*100);
});
}
$('#' + div.id).html('');
for(i=0; i<text.length; i++) {
$('#' + div.id).append('<span>'+text[i]+'</span>');
if(i==text.length-1) doAnimate();
}
}
animateDiv(test);
Actually you were trying to concatenate a string and an object by this $("#"+div), which is wrong, you should do this $("#"+div.id) which is legal.
You have to call the function using single/double quotes like
animateDiv("test");
instead of
animateDiv(test);
And remove '"' from your code everywhere
So Make it $('#' + div + '"') to $('#' + div)
Working Demo
var text = $('#' + div + '"').text();
replace with
var text = $('#' + div).text();
animateDiv('test')
subsitute $('#' + div + '"') with $('#' + div)
i created a jquery autocomplete it work true, but loading LOADING... it after removed value by Backspace don't work true. it not hide and Still is show.
how can after removed value by Backspace, hide LOADING... ?
EXAMPLE: Please click on link and see problem
my full code:
$(document).ready(function () {
/// LOADING... ///////////////////////////////////////////////////////////////////////////////////////
$('#loadingDiv')
.hide() // hide it initially
.ajaxStart(function() {
$(this).show();
})
.ajaxStop(function() {
$(this).hide();
});
/// autocomplete /////////////////////////////////////////////////////////////////////////////////////////
$('.auto_complete').keyup(function () {
var specific = '.' + $(this).closest('div.auto_box').find('b').attr('class');
var cl_list = '.' + $(this).closest('div.auto_box').find('ul').attr('class');
var id = '#' + this.id;
var url = $(id).attr('class');
var dataObj = $(this).closest('form').serialize();
$.ajax({
type: "POST",
dataType: 'json',
url: url,
data: dataObj,
cache: false,
success: function (data) {
//alert(url)
var cl_list = '.' + $('.auto_box '+ specific +' ul').attr('class');
var id_name = $(cl_list).attr('id');
$(cl_list).show().html('');
if (data == 0) {
$(cl_list).show().html('<p><b>There is no</b></p>');
}
else {
$.each(data, function (a, b) {
//alert(b.name)
$('<p id="' + b.name + '">' + b.name + '</p>').appendTo(cl_list);
});
$(cl_list + ' p').click(function (e) {
e.preventDefault();
var ac = $(this).attr('id');
$('<b>' + ac + '، <input type="text" name="'+id_name+'[]" value="' + ac + '" style="border: none; display: none;" /></b>').appendTo($('.auto_box ' + specific + ' span'));
$(this).remove();
return false;
});
$('.auto_box span b').live('click', function (e) {
e.preventDefault();
$(this).remove();
return false;
});
}
if ($(specific + ' input').val() == '') {
$(cl_list + " p").hide().remove();
$(cl_list).css('display','none');
$(".list_name").show().html('');
};
$('body').click(function () {
$(cl_list + " p").hide().remove();
$('.auto_complete').val('');
$(cl_list).show().html('');
$(cl_list).css('display','none')
});
},
"error": function (x, y, z) {
// callback to run if an error occurs
alert("An error has occured:\n" + x + "\n" + y + "\n" + z);
}
});
});
});
I recommend you to use jsfiddle next time you post code examples in a link.
Nevermind. The "loading" message keeps there because there's no fallback to empty values on results.
A quick fix could be just by test that there's a value in the input before making any post like if(this.value == ""){
$(cl_list).css('display', 'none');
return false;
}
Here's how it works with it