I have a deeply-nested form where levels of elements get added and removed dynamically by the user (using the Jquery-deep branch in Ryan Bates' Complex Forms Examples). I have attached to each of these elements some Javascript functions and I am having trouble getting them to stay .live() when new elements are added.
I'm trying to get this to work with James Padolsey's Autoresize:
# This code functions but only for existing elements. How to make it .live()?
<%= javascript_include_tag "autoresize.jquery.min" %>
<script type="text/javascript">
$('#notes, textarea, .optionBox').autoResize({
onResize : function() {
$(this).css({opacity:0.8});
},
// After resize:
animateCallback : function() {
$(this).css({opacity:1});
},
animateDuration : 150,
extraSpace : 0,
limit : 210
});
</script>
I've tried inserting the .live() function a few ways but they haven't worked. How can I get it to function here?
Check out plugin livequery
Example of usage
$('textarea').livequery(function(){
if ($(this).attr("class") != "resized"){
$(this).attr("class","resized");
$(this).autoResize({
// On resize:
onResize : function() {
$(this).css({opacity:0.8});
},
// After resize:
animateCallback : function() {
$(this).css({opacity:1});
},
// Quite slow animation:
animateDuration : 300,
// More extra space:
extraSpace : 40
});
}
});
Have you looked at the more preferred method, delegate
you can use live function in fallowing way
$('#notes, textarea, .optionBox').live('click',autoResize({
onResize : function() {
$(this).css({opacity:0.8});
},
// After resize:
animateCallback : function() {
$(this).css({opacity:1});
},
animateDuration : 150,
extraSpace : 0,
limit : 210 }););
event can be onclick,onfocus...etc.
even you can attach the handler and call autoResize through that handler.
same issue like yours, working with event 'click' but required extra mouse click on textarea, with event 'focus' working excellent but text dissapiar after living textarea(for my case)
$('textarea').live('click', function() {
$(this).autoResize({
// On resize:
onResize : function() {
$(this).css({opacity:0.8});
},
// After resize:
animateCallback : function() {
$(this).css({opacity:1});
},
// Quite slow animation:
animateDuration : 300,
// More extra space:
extraSpace : 10
});
});
my working solution :
$('textarea').live('focus blur', function(event) {
if (event.type == 'focus') {
$(this).autoResize({
// On resize:
onResize : function() {
$(this).css({opacity:0.8});
},
// After resize:
animateCallback : function() {
$(this).css({opacity:1});
},
// Quite slow animation:
animateDuration : 300,
// More extra space:
extraSpace : 10
});
}
else
{
$(this).die();
}
});
better solution for this case:
use this plugin link text
then code is:
$('textarea').live('focus', function() {
$(this).elastic();
});
Related
for some reason I can't input text in my newsletter input field now that I display it in a fancybox popup window. Any idea what the issue is and how to fix this? See http://jsfiddle.net/6G8YR/
Many thanks,
function openFancybox() {
setTimeout( function() {$('#newspopup').trigger('click'); },1000);
}
$(document).ready(function() {
var visited = $.cookie('visited');
if (visited == 'yes') {
return false;
} else {
openFancybox();
}
$.cookie('visited', 'yes', { expires: 0.0001 });
$('#newspopup').fancybox({
helpers : {
overlay : {
css : {
'background' : 'rgba(58, 42, 45, 0.3)'
}
}
}
});
});
$(document).on('click', function(e) {
if(e.target === $('.visitwebsitebtn')[0]) {
$.fancybox.close();
}
});
Ok I figured out the problem, but only ran into other kinds of issues. The problem is that, there is an event that exists that causes your fancybox to refresh everytime someone happens to click on it.
This is why you are unable to write anything in the input. I have a temporary solution that is really ugly but it works.
$('#email').on('click', function(e){
e.stopPropagation();
});
Upon clicking the email input, your fancybox won't refersh. I tried applying this to your #newspopup but it blocs $('#newspopup').trigger('click'); so your fancybox never opens at the start.
Here is a Demo
Additional information:
I've worked with fancybox plugin before and I've never encountered this problem. You might want to think of adding options to your fancybox.. for example add this line :
'type':'iframe',
I would have tried on jsfiddle, but unfortunately they don't allow it, it seems.
You can optimize your code and get rid of unnecessary click events and triggers (so you won't need unnecessary e.stopPropagation() methods either) like :
function openFancybox() {
setTimeout(function () {
$.fancybox('#newspopup', {
modal: true, // this prevents fancybox to close unless close unless ".visitwebsitebtn" is clicked
helpers: {
overlay: {
css: {
'background': 'rgba(58, 42, 45, 0.3)'
}
}
},
afterShow: function () {
// enables a way to close fancybox
$(".visitwebsitebtn").on("click", function () {
$.fancybox.close()
});
}
});
}, 1000);
};
$(document).ready(function () {
var visited = $.cookie('visited');
if (visited == 'yes') {
return false;
} else {
openFancybox();
}
$.cookie('visited', 'yes', {
expires: 7
});
});
See JSFIDDLE
I am currently using the following code to initialize a lazy initialization version of Bootstrap tooltip. After the first hover everything works fine in regards to the delay, but on the initial hover it shows right away. I know this is because of the $(this).tooltip('show'); method, but I dont know how to use the delay and show at the same time. I have to use the $(this).tooltip('show'); because once hovered the element doesnt show the tooltip unless I move out and back in.
$(element).on('hover', '.item', function () {
matchup = ko.dataFor(this).Matchup;
if (matchup) {
if ($(this).attr('data-original-title') != '') {
$(this).tooltip({ title: matchup.Title, html: true, delay: 1000 });
$(this).tooltip('show');
}
}
});
Updated Answer
$(element).on('mouseenter', '.item', function (e) {
matchup = ko.dataFor(this).Matchup;
if (matchup) {
if ($(this).attr('data-original-title') != '') {
$(this)
.addClass('tooltip-init')
.tooltip({ title: matchup.Title, html: true, delay: { show: 1000, hide: 0 } })
.trigger(e.type);
}
});
try use trigger
try the following code
$(this).tooltip({
title: matchup.Title,
html: true,
trigger: 'hover',
delay: delay: { show: 2000, hide: 3000 }
}).trigger('hover');
I found Holmes answer using delay to work, but not reliably. When moving through a series of items, the hover seemed to stop showing. With the help of another stackoverflow answer leading to this jsfiddle by Sherbrow, I simplified the code and got it working in this jsfiddle. Simplified code below:
var enterTimeout = false;
$('[rel="tooltip"]').tooltip({trigger:'manual'}).on('mouseenter', function() {
var show = function(n) {
enterTimeout = setTimeout(function(n) {
var isHovered = n.is(":hover");
if (isHovered) n.tooltip('show');
enterTimeout = false;
}, 750);
};
if(enterTimeout) clearTimeout(enterTimeout);
show( $(this) );
});
$('[rel="tooltip"]').on('mouseout click',function() {
$(this).tooltip('hide');
});
I am using the following functions to grow the text box and display the submit button on focus and shrink and hide the button on blur.
But the button shows and hides before the animation is complete.
I am looking to create a neat slide down and slide up animation.
$('#venue-write-review').focus(function() {
$(this).animate({ height: '96px' }, 500);
$('#submit-review').show();
});
$('#venue-write-review').blur(function() {
$(this).animate({ height: '48px' }, 500);
$('#submit-review').hide();
});
You can specify a callback to the animate function to be executed once the animation is done.
$('#venue-write-review')
.focus(function() {
$(this).animate({ height: '96px' }, 500, function () {
$('#submit-review').show();
});
})
.blur(function() {
$(this).animate({ height: '48px' }, 500, function () {
$('#submit-review').hide();
});
});
This is all you need And don't forget to use .stop()!
$('#venue-write-review').on('focus blur',function(e){
$(this).stop().animate({ height: e.type[0]=="f"?96:48 }, 500, function(){
$('#submit-review').toggle();
});
});
e.type[0]=="f" ij just to check in a Conditional Operator (?:) if the passed event's first [0] character is f (focus; else logically it's blur)
Read the jQuery docs about the methods: .on(), .toggle(), stop() .animate() callback and on the MDN website read about Conditional operator
Also in jQuery if you don't need to animate by % or some other measure, you don't need to specify 'px' cause it's default.
You can use complete callback. Check the docs (under options section):
A function to call once the animation is complete.
Like this:
$('#venue-write-review').focus(function() {
$(this).animate({
height: '96px'
},
{
duration: 500,
complete: function() {
$('#submit-review').show();
}
}
});
});
$('#venue-write-review').blur(function() {
$(this).animate({
height: '48px'
},
{
duration: 500,
complete: function() {
$('#submit-review').hide();
}
}
});
});
Since toggle is deprecated I used this to toogle div:
$("#syndicates_showmore").on("click", function () {
if (!clicked) {
$('#syndicates').fadeTo('slow', 0.3, function () {
$(this).css(
{
'height': 'auto',
'overflow': 'none'
});
}).fadeTo('slow', 1);
setTimeout(function () {
$("#syndicates_showmore").text("Show less");
}, 500);
clicked = true;
}
else {
$('#syndicates').fadeTo('slow', 0.3, function () {
$(this).css(
{
'height': '290px',
'overflow': 'hidden'
});
}).fadeTo('slow', 1);
setTimeout(function () {
$("#syndicates_showmore").text("Show more");
}, 500);
clicked = false;
}
});
Is there any cleaner way to do this?
According to the jQuery 1.9 Upgrade Guide:
.toggle(function, function, ... ) removed
This is the "click an element to run the specified functions" signature of .toggle(). It should not be confused with the "change the visibility of an element" of .toggle() which is not deprecated. The former is being removed to reduce confusion and improve the potential for modularity in the library. The jQuery Migrate plugin can be used to restore the functionality.
In other words, you can still use .toggle like this:
var clicked = false;
$("#syndicates_showmore").on("click", function () {
clicked = !clicked;
var showText = "Show " + (clicked ? "more" : "less");
$('#syndicates').toggle(function () {
$("#syndicates_showmore").text(showText);
});
});
Taken from jQuery API
$("#clickme" ).click(function() {
$( "#book" ).toggle( "slow", function() {
// Animation complete.
});
});
The best alternative is to use .toggleClass():
$("#syndicates_showmore").on("click", function () {
$('#syndicates').toggleClass("newClass, 1000", "easeInOutBounce")
});
jQuery .toggleClass() API Documentation:
Description: Add or remove one or more classes from each element in the set of matched elements, depending on either the class's
presence or the value of the switch argument.
If using with jQuery UI you can easily animate it with using different easing options.
Easings:
Easing functions specify the speed at which an animation progresses at
different points within the animation. jQuery UI provides several additional
easing functions, ranging from variations on the swing behavior to
customized effects such as bouncing.
Example online
I'm building a simple photolog using jQuery, jflickrfeed and jQuery.Masonry - but I'm having some trouble getting the event chain right in Safari.
Here's some example code:
$(document).ready(function() {
$('#container').jflickrfeed({
limit: 20,
qstrings: {
id: '58201136#N00'
},
itemTemplate: '<div class="box"><img src="{{image_m}}" /><h3>{{title}}</h3>{{description}}</div>'
}, function(data) {
console.log("1st");
});
});
$(window).load(function() {
console.log("2nd");
$('#container').masonry({
singleMode: true
});
});
So, jflickrfeed pulls a photo from my flickr feed, wraps it in the template code and appends it inside #container, and repeats this until the limit is reached. After all photos are inserted, Masonry kicks in and arranges the divs.
This works beautifully in Chrome and Firefox, but not in Safari - where the .load event fires before all photos are finished loaded, thus breaking the layout.
I've updated the example to better show illustrate what I mean.
In Chrome/Firefox the console output is "1st, 2nd" while in Safari it is "2nd, 1st"
Any tips?
You can pass the load callback as the second parameter to "jflickrfeed" call and this will ensure that the "masonry" will be invoked only when the images from Flickr have been loaded.
here is a possible sample:
$('#container').jflickrfeed({
limit: 20,
qstrings: {
id: '58201136#N00'
},
itemTemplate: '<div class="box"><img src="{{image_m}}" /><h3>{{title}}</h3>{{description}}</div>'
},
function () {
$('#container').masonry({
singleMode: true
});
});
Hope it helps.
I'm not sure how useful this will be, or if if will make any difference at all. But for a guess, if the issue is that #container is not available when $(window).load fires, you could try setting up a timer to repeatedly check for its existence, and when it is detected, set up masonry, then kill the timer:
$(window).load(function () {
var i = setInterval(function() {
if($("#container").length) {
$('#container').masonry({
singleMode: true
});
clearInterval(i);
}},
20);
});
Solved it myself by adding a counter:
var counter = 0;
$(document).ready(function () {
$('#container').jflickrfeed({
limit: 20,
qstrings: {
id: '58201136#N00'
},
itemTemplate: '<div class="box"><img src="{{image_m}}" /><h3>{{title}}</h3>{{description}}</div>',
itemCallback: function () {
counter++;
}
});
});
$(window).load(function () {
var i = setInterval(function () {
if (counter = 20) {
$('#container').masonry({
singleMode: true
});
clearInterval(i);
}
}, 20);
});
Ugly, but it works..