I'm trying to do what seems to be a simple task that would, in theory, return the "my" and "at" values of the position method for the tooltip based on the parent of the hovered element that initializes the tooltip but I'm not sure exactly how to do this.
var s,
TooltipController = {
settings: {
tooltips: '[data-tooltip]'
},
init: function () {
s = this.settings;
this.bind_ui_actions();
},
bind_ui_actions: function () {
$(s.tooltips).tooltip({
content: function () {
// Only return a tooltip if the content is truncated
return ((this.offsetWidth < this.scrollWidth) ? $(this).data('tooltip') : false);
},
items: '[data-tooltip]',
open: function (event, ui) {
// If tooltip resides in a <th /> then use animations else dontuse animations
var parent = TooltipController.get_tooltip_parent($(this));
return ((parent == 'TH') ? ui.tooltip.animate({ top: ui.tooltip.position().top + -10 }, "fast") : false);
},
position: function(event, ui) {
var parent = TooltipController.get_tooltip_parent($(this));
var top_pos = ((parent == 'TH') ? '+10' : '');
return { my: 'center bottom', at: 'center top' + top_pos };
},
show: { duration: 0 },
tooltipClass: 'tooltip'
});
},
get_tooltip_parent: function ($this) {
return $this[0].nodeName;
}
}
If I add console.logs to each of the methods I can see that the position method doesn't even get hit and I'm not exactly sure why. I'm sure this is a simple noob mistake but I'm just not understanding whats happening. Thanks in advance!
Related
Trying to get DOM-Autoscroller to work with Dragula.
We have Dragula up and running. I've managed to get the syntax to Autoscroller correct, so that it doesn't break Dragula. But Autoscroller doesn't appear to be doing anything.
Our Autoscroller call is reasonably close to the example.
$(document).ready(function () {
var drake = dragula({
containers: Array.prototype.slice.call(document.querySelectorAll('[id^="checklistItems-"')),
revertOnSpill: true,
direction: 'vertical',
accepts: function (el, target, source, sibling) {
return target == source;
}
})
.on('drop', function (el, target, sibling) {
var destinationIndex = [].slice.call(el.parentElement.children).indexOf(el);
// call AJAX with element id and destination index
$.ajax(
{
url: "#Url.Action("ReorderTicketChecklist", "Tickets")",
data: { checklist_ID: el.parentElement.dataset.checklistid, checklistItem_ID: el.dataset.id, destinationNum: destinationIndex+1 },
error: function () {
alert("Something went wrong reordering the list. Please refresh and try again.");
}
})
});
var scroll = autoScroll([
//Array.prototype.slice.call(document.querySelectorAll('[id^="checklistRow-"'))
document.querySelector('#checklistRow-100')
], {
margin: 20,
pixels: 10,
scrollWhenOutside: true,
autoScroll: function () {
return this.down && drake && drake.dragging && drake.drake && drake.drake.dragging;
}
});
})
I currently have the first list hard-coded, and I can work on the syntax for the rest, later.
I guess I mostly need some advice on how to debug this. What can I do to shake the box and get some behavior out of Autoscroller, so I can track down what's wrong?
I'm using jQuery UI to allow elements of a class. However i'd like the rest of the elements of a class to follow when one of them is being dragged. How can I do that?
So when one is dragged the rest of the class are also being dragged.
I attempted to trigger mousedown on start and mouseup on stop events on the elements so that the dragging would happen for the others when one of them is being dragged?
$('.dismissAllButton').draggable({ axis:'x', containment:'parent', start:function(){ upEvent = false; $(this).mousedown(); }, drag: function(){ $(this).mousemove(); }, stop:function(){ $(this).mouseup(); setTimeout(function(){ upEvent = true; }, 1000); }});
I also tried making itself the parent so that the others would also be dragged / follow when one of them was being dragged, but that didn't work.
$('.dismissAllButton').draggable({ axis:'x', containment:'parent', handle:'.dismissAllButton', start:function(){ upEvent = false; }, stop:function(){ setTimeout(function(){ upEvent = true; }, 1000); }});
Fiddles:
No following, just one element dragging: http://jsfiddle.net/7ta68xyt/
attempt 1, code sample 1 above, : http://jsfiddle.net/7ta68xyt/1/
attempt 2, code sample 2 above, : http://jsfiddle.net/7ta68xyt/2/
Update: I found a script on github that allows for this, but the other elements all lag behind a bit. How can I get them to lag at intervals and the end up at the same place when dragging stops or have them all drag the same ( no lag ).
Here is the fiddle: http://jsfiddle.net/7ta68xyt/3/
Here is the script: https://github.com/javadoug/jquery.drag-multiple
Here you are one option using jQuery ui http://jsfiddle.net/7ta68xyt/5/
$(".dismissAllButton").draggable({
axis: 'x',
containment: 'parent',
start: function (event, ui) {
posTopArray = [];
posLeftArray = [];
if ($(this).hasClass("group")) {
$(".group").each(function (i) {
thiscsstop = $(this).css('top');
if (thiscsstop == 'auto') thiscsstop = 0;
thiscssleft = $(this).css('left');
if (thiscssleft == 'auto') thiscssleft = 0;
posTopArray[i] = parseInt(thiscsstop);
posLeftArray[i] = parseInt(thiscssleft);
});
}
begintop = $(this).offset().top;
beginleft = $(this).offset().left;
},
drag: function (event, ui) {
var topdiff = $(this).offset().top - begintop;
var leftdiff = $(this).offset().left - beginleft;
if ($(this).hasClass("group")) {
$(".group").each(function (i) {
$(this).css('top', posTopArray[i] + topdiff);
$(this).css('left', posLeftArray[i] + leftdiff);
});
}
}
});
I'm using RequireJS to structure my JS which is why I'm using a $.proxy function. What I'm trying to do within the .each function is give each carousel on the page a unique data attribute. In order to do this I have to be able to target each carousel, but $(this) in this context doesn't target each carousel. I've tried using currentTarget but I think this only works on click events?
Below is the specific snippet which needs fixing.
getCarousels: function() {
$carousel.each($.proxy(function(index) {
$owl = (index.currentTarget);
$owl.attr('data-number', index);
this.initCarousel();
},this));
},
And here is the full file.
define(['owlcarousel'], function() {
var $ = jQuery,
$carousel = $('.carousel'),
$data = $('.carousel-data');
function updateResult(pos, value, carouselNumber) {
$(carouselNumber).find(pos).text(value);
}
function afterAction(el) {
var owl = el.data('owlCarousel'),
actualValue = this.owl.currentItem + 1,
carouselNumber = el.attr('data-number');
console.log(carouselNumber);
updateResult('.carousel-current', actualValue, carouselNumber);
updateResult('.carousel-items', this.owl.owlItems.length, carouselNumber);
}
return {
init: function() {
if($carousel.length >= 1) {
this.setUp();
} else {
return false;
}
},
setUp: function() {
this.getCarousels();
},
getCarousels: function() {
$carousel.each($.proxy(function(index) {
$owl = (index.currentTarget);
$owl.attr('data-number', index);
this.initCarousel();
},this));
},
initCarousel: function() {
$carousel.owlCarousel({
singleItem: true,
autoPlay: true,
slideSpeed: 400,
paginationSpeed: 800,
lazyLoad: true,
afterAction: afterAction
});
}
};
});
.each receive 2 parameters which is the index and the value. Usualy the value is the same as this, but well, you overrided it. Get that second parameter! :
$carousel.each($.proxy(function(index, el) {
$owl = $(el);
$owl.attr('data-number', index);
this.initCarousel();
},this));
But why not simply not use proxy?
var that = this
$carousel.each(function(index) {
$owl = $(this);
$owl.attr('data-number', index);
that.initCarousel();
});
I purchased a template from themeforest and am having a "Uncaught TypeError: Cannot call method 'each' of undefined" after I removed two of the three opening sliders. The error slows the page load time down to a crawl however the entire site is functional. Does 'each' reference the 3 original sliders and if so can I edit it to reference the 1 lone slider?
function init_main_slider(target) {
set_height();
jQuery(target).flexslider({
animation : 'fade',
controlNav : true,
directionNav : true,
animationLoop : true,
slideshow : false,
animationSpeed : 500,
useCSS : true,
start : function(slider) {
if(!isMobile) {
slider.slides.each(function(s) {
jQuery(this).find('.animated_item').each(function(n) {
jQuery(this).addClass('animate_item' + n);
});
});
slider.slides.eq(slider.currentSlide).find('.animated_item').each(function(n) {
var show_animation = jQuery(this).attr('data-animation');
jQuery(this).addClass(show_animation);
});
}
else {
slider.find('.counter').find('.num').each(function() {
var container = jQuery(this);
var num = container.attr('data-num');
var content = container.attr('data-content');
count_num(num, content, container, false);
});
}
},
before : function(slider) {
if(!isMobile) {
slider.slides.eq(slider.currentSlide).find('.animated_item').each(function(n) {
var show_animation = jQuery(this).attr('data-animation');
jQuery(this).removeClass(show_animation);
});
slider.slides.find('.animated_item').hide();
var counter_block = slider.slides.eq(slider.currentSlide).find('.counter');
if(counter_block.length > 0) {
setTimeout(function() {
counter_block.find('.num').each(function() {
jQuery(this).html('0');
});
}, 300);
}
}
},
after : function(slider) {
if(!isMobile) {
slider.slides.find('.animated_item').show();
slider.slides.eq(slider.currentSlide).find('.animated_item').each(function(n) {
var show_animation = jQuery(this).attr('data-animation');
jQuery(this).addClass(show_animation);
});
var counter_block = slider.slides.eq(slider.currentSlide).find('.counter');
if(counter_block.length > 0) {
counter_block.find('.num').each(function() {
var container = jQuery(this);
var num = container.attr('data-num');
var content = container.attr('data-content');
count_num(num, content, container, 1500);
});
}
}
}
});
function set_height() {
var w_height = jQuery(window).height();
jQuery(target).height(w_height).find('.slides > li').height(w_height);
}
jQuery(window).resize(function() {
set_height();
});
}
How did you "remove the sliders"? I noticed in the html that the slide still has a class of <li class="slide_3"> which might be causing issues for the plugin. Does it make a difference to remove that or change to just slide or slide_1? If you cant get it to cooperate one idea is that there really is no need for this slider when only have one image so you could count the number of <li> and only use that function when there is more than one image, otherwise insert the single image... something like.
jQuery(function() {
// count the list
var listSize = $(".slides li").size();
if (listSize < 2) {
$('#main_slider').prepend('<img src="images/pic_slider_1_3.png" alt="">')
} else {
init_main_slider('#main_slider');
}
});
I'm building my first ever jQuery plugin (it's just a simple experiment). Here's what I have so far:
(function($){
$.fn.extend({
auchieFader: function(options) {
var defaults = {
mask: '',
topImg : '',
}
var options = $.extend(defaults, options);
return this.each(function() {
var o = options;
var obj = $(this);
var masker = $(o.mask, obj);
masker.hover(function () {
$(o.topImg).stop().animate({
"opacity": "0"
}, "slow");
}, function () {
$(o.topImg).stop().animate({
"opacity": "1"
}, "slow");
});
});
}
});
})(jQuery);
I'm then calling the plugin using:
$('.fader').auchieFader({mask: ".mask", topImg: ".top"});
If I then add another request say:
$('.fader2').auchieFader({mask: ".mask", topImg: ".top"});
Then no matter what instance of my 2 faders I hover both of them will trigger. I know this is because my mask mask and topImg options have the same class - but how can I modify the plugin to allow for these items to have the same class? I know it's probably something really simple, but I'm still finding my way with jQuery and Javascript in general. Any other tips on improving my code would also be greatly appreciated!
Cheers,
Chris
You seem to already have the answer to your question in the code. For the masker you wrote this:
var masker = $(o.mask, obj);
Which scopes the class in o.mask inside of the dom element obj
I think you just need to do the same thing for o.topImg.
Try changing
masker.hover(function () {
$(o.topImg)
into
masker.hover(function () {
$(o.topImg, obj)
try this:
(function($){
$.fn.extend({
auchieFader: function(options) {
var
// defaults options
defaults = {
mask: null,
topImg: null
},
// extend options in defaults
o = $.extend(defaults, options);
if (!o.mask || !o.topImg) return this;
return this.each(function() {
var
masker = $(o.mask, this),
topImg = $(o.topImg, this);
if (masker.length == 0 || topImg.length == 0) return;
masker.hover(
function () { topImg.stop().animate({ "opacity": "0" }, "slow"); },
function () { topImg.stop().animate({ "opacity": "1" }, "slow"); }
);
});
};
});
})(jQuery);