Enable and disable jquery knob dynamically - javascript

I'm using the excellent jQuery knob plugin. However, I need to dynamically enable/disable the element depending on user input. There is support for having a disabled state on page load which have the effect that no mouse (or touch) events are bound to the canvas element. Does anyone know how to resolve this issue, that is, how to (after page load) bind and unbind these mouse event listeners?
Ideally I would like to do something like this (on a disabled knob)
$('.button').click(function() {
$('.knob').enable();
});
Edit:
I ended up rewriting the source which binds/unbinds the mouse and touch events. The solution is not perfect so I leave the question open if someone perhaps have a better (cleaner) solution.

html
<input class="knobSlider" data-readOnly="true">
<button id="testBtn">clickHere</button>
script
in doc ready,
$(".knobSlider").knob();
$("#testBtn").click(function(){
$(".knobSlider").siblings("canvas").remove();
if($(".knobSlider").attr("data-readOnly")=='true'){
$(".knobSlider").unwrap().removeAttr("data-readOnly readonly").data("kontroled","").data("readonly",false).knob();
}
else{
$(".knobSlider").unwrap().attr("data-readOnly",true).data("kontroled","").data("readonly",true).knob();
}
});
For reference you can use my jsfiddle link > http://jsfiddle.net/EG4QM/ (check this in firefox, because of some external resource load problem in chrome)

If someone doesn't like how the accepted answer destroys and recreates the internal canvas element, then checkout my approach:
https://jsfiddle.net/604kj5g5/1/
Essentially, check the draw() implementation (I also recommend listening on value changes in the draw method instead of the change and release, which work for and click and mousewheel events respectively, which imo is inconvenient).
var $input = $("input");
var knobEnabled = true;
var knobPreviousValue = $input.val();
$input.knob({
draw: function () {
if (knobPreviousValue === $input.val()) {
return;
}
if (!knobEnabled) {
$input.val(knobPreviousValue).trigger("change");
return;
}
knobPreviousValue = $input.val();
console.log($input.val());
},
});

Try this to disable the control.
I'm still trying to find a way to enable it back
$("#btnDisable").click(function(){
$("#knob").off().prev().off();
});

Related

Prevent child event from firing

I have a slider that I am currently making. I am making slow progress, but I am making progress nonetheless!
Currently I have this:
http://codepen.io/r3plica/pen/mEKyGG?editors=1011#0
There are 2 things you can do with this control, the first thing is you can drag left or right. The second thing you can do is click a "point" and it will scroll to the center.
The problem I have is that if I start dragging from a point, when I let go it will invoke the moveToCenter method.
I have tried to prevent this by adding
// Stop from accessing any child events
e.preventDefault();
e.stopPropagation();
to the end of the dragEventHandler, but this did not work.
I also have 2 boolean values options.drag and options.start. I though I might be able to use them somehow (if the drag has started and is enabled then don't perform the moveToCenter but this didn't work either.
Do anyone have any idea how to get this to work?
Maybe this will help. You can register your events in bubbling or capturing mode, using addEventListener method. It defines orders of processing your events - child -> parent (bubbling), or vice versa (capturing).
http://www.quirksmode.org/js/events_advanced.html
So, if you use addEventListener(event, handler, true), it will use capturing event mode.
Codepen:
http://codepen.io/anon/pen/bZKdqV?editors=1011
divs.forEach(function (div) {
div.addEventListener('click', function(e) {
e.stopPropagation();
console.log('parent');
}, true);
});
Be aware of browser support (IE9+). All modern browsers - yes, of course.
http://caniuse.com/#search=addeventlistener
Update
So it turned out to be easier than first approach. (no need for capturing)
Check out codepen:
http://codepen.io/anon/pen/QExjzV?editors=1010
Changes from your sample:
At the beginning of moveToCenter: function(e, options, animate) function
if (options.started) {
return;
}
In if (['mouseup', 'mouseleave'].indexOf(e.type) > -1):
setTimeout(function() {
options.started = false;
} , 100);
instead of
options.started = false;
Hope this helps.

Doubletap event on input text on mobile [duplicate]

I'm looking for the best solution to adding both "doubletap" and "longtap" events for use with jQuery's live(), bind() and trigger(). I rolled my own quick solution, but it's a little buggy. Does anyone have plugins they would recommend, or implentations of their own they'd like to share?
It has been reported to jQuery as a bug, but as doubletapping isn't the same as doubleclicking, it does not have a high priority. However, mastermind Raul Sanchez coded a jquery solution for doubletap which you can probably use!
Here's the link, works on mobile Safari.
It's easy to use:
$('selector').doubletap(function() {});
-edit-
And there's a longtap plugin here! You can see a demo on your iPad or iPhone here.
rsplak's answer is good. I checked out that link and it does work well.
However, it only implements a doubletap jQuery function
I needed a custom doubletap event that I could bind/delegate to. i.e.
$('.myelement').bind('doubletap', function(event){
//...
});
This is more important if you're writing a backbone.js style app, where there is a lot of event binding going on.
So I took Raul Sanchez's work, and turned it into a "jQuery special event".
Have a look here: https://gist.github.com/1652946 Might be useful to someone.
Just use a multitouch JavaScript library like Hammer.js. Then you can write code like:
canvas
.hammer({prevent_default: true})
.bind('doubletap', function(e) { // Also fires on double click
// Generate a pony
})
.bind('hold', function(e) {
// Generate a unicorn
});
It supports tap, double tap, swipe, hold, transform (i.e., pinch) and drag. The touch events also fire when equivalent mouse actions happen, so you don't need to write two sets of event handlers. Oh, and you need the jQuery plugin if you want to be able to write in the jQueryish way as I did.
I wrote a very similar answer to this question because it's also very popular but not very well answered.
You can also use jQuery Finger which also supports event delegation:
For longtap:
// direct event
$('selector').on('press', function() { /* handle event */ });
// delegated event
$('ancestor').on('press', 'selector', function() { /* handle event */ });
For double tap:
// direct event
$('selector').on('doubletap', function() { /* handle event */ });
// delegated event
$('ancestor').on('doubletap', 'selector', function() { /* handle event */ });
Here's a pretty basic outline of a function you can extend upon for the longtap:
$('#myDiv').mousedown(function() {
var d = new Date;
a = d.getTime();
});
$('#myDiv').mouseup(function() {
var d = new Date;
b = d.getTime();
if (b-a > 500) {
alert('This has been a longtouch!');
}
});
The length of time can be defined by the if block in the mouseup function. This probably could be beefed up upon a good deal. I have a jsFiddle set up for those who want to play with it.
EDIT: I just realized that this depends on mousedown and mouseup being fired with finger touches. If that isn't the case, then substitute whatever the appropriate method is... I'm not that familiar with mobile development.
based on latest jquery docs i've written doubletap event
https://gist.github.com/attenzione/7098476
function itemTapEvent(event) {
if (event.type == 'touchend') {
var lastTouch = $(this).data('lastTouch') || {lastTime: 0},
now = event.timeStamp,
delta = now - lastTouch.lastTime;
if ( delta > 20 && delta < 250 ) {
if (lastTouch.timerEv)
clearTimeout(lastTouch.timerEv);
return;
} else
$(this).data('lastTouch', {lastTime: now});
$(this).data('lastTouch')['timerEv'] = setTimeout(function() {
$(this).trigger('touchend');
}, 250);
}
}
$('selector').bind('touchend', itemTapEvent);

Jquery on mousedown not working on dynamically generated elements

So i'm trying to create a js/css "wave game" like tower defense ones.
When all the pre-generated enemys from first wave are dead, it spawns the second wave and so on.
So far so good.
The problem is that i just can't attack mobs dynamically spawned within second wave.
I used to try .live() in similar cases, but its deprecated, so i'm trying .on(), as instructed
$('.enemy').on('mousedown' , function(event) {
//attack code
}
Its working fine for initial mobs (1st wave) but it still just not working on dynamic mobs (>= 2nd wave)
Help, guys, please?
You need to specify an element that is already there when the DOM is created. In the parameters, you specify the elements you want to add the mousedown method. By simply assigning $('.enemy'), it will attach the method to those that are already present in the DOM.
$('body').on('mousedown', '.enemy', function(event) {
//attack code
}
As Wex mentioned in the comments, instead of writting $('body') you should use the container's name (the container which wraps the .enemy elements. This way, when a .enemy element is added, the event doesn't need to bubble all the way up to the body tag.
The binding '.on()' works only with the content that created earlier then the script ran.
So one solution could be you bind the event to the parent element.
$('.PARENT_ELEMENT').on('mousedown', '.enemy', function(event){
// your code here
}
That should do it.
I made this google like drop down suggestions search box and I faced a problem similar to yours where there was suggestions disappearing before the re-direct happened. I overcame it by using and modifing vyx.ca answer:
var mousedownHappened = false;
var clicked_link;
$("#search-box").blur(function(e) {
if (mousedownHappened)// cancel the blur event
{
mousedownHappened = false;
window.location.href = clicked_link;
} else {
// no link was clicked just remove the suggestions box if exists
if ($('#search-btn').next().hasClass('suggestions')) {
$(".suggestions").remove();
}
}
});
//attaching the event to the document is better
$(document).on('mousedown', '.suggestions a', function() {
clicked_link= $(this).attr('href');
mousedownHappened = true;
});

how do I know if the mouse pointer is on the HTML element?

I have a timed event I want to behave differently accordingly to what HTML element the mouse pointer is on.
Is there a way, assuming I have the HTML element, to know if the mouse pointer is currently on top of it.
I am well aware of the onmouseover/onmouseout events and how to use them.
I am using JQuery.
I am obviously looking for some kind of flag, as I need to check a state and not handle an event.
again, I know how to implement this with events.
I'm not aware of any built-in way to ping an element for the status of mouse hovering.
However, you can create one by updating a flag at mouseenter and mouseleave -- which is where Brian Driscoll's suggestion of .hover comes in:
jQuery.fn.tracking = function () {
this.data('hovering', false);
this.hover(function () {
$(this).data('hovering', true);
}, function () {
$(this).data('hovering', false);
});
return this;
};
jQuery.fn.hovering = function () {
return this.data('hovering');
}
You'll need to initialize tracking for each element you care about:
$('#elem1,#elem2').tracking();
But then you can get the status of any of them:
if ($('#elem1').hovering()) {
// ...
} else if ($('#elem2').hovering()) {
// ...
}
Demo: http://jsbin.com/amaxu3/edit
Have you looked into jQuery.hover()? http://api.jquery.com/hover/
You need to give name to html andme and on mouseover you need to check document.getelementsbyName. Then check what your are getting as output. Now you can take decision is it html control or asp.net.
When you use collObjects = object.getElementsByName("htmlcontrol") then compare id of both.
1 morething why you needed to check this in javascript. there may be some other solution for that. Just share with us.
You might have some luck with document.elementFromPoint, although I believe there are some inconsistencies in older browser implementations (http://www.quirksmode.org/dom/w3c_cssom.html#documentview).
$('#elem').mousemove(function(e){
if (this == document.elementFromPoint(e.clientX, e.clientY)) {
// Do stuff
}
});
Or outside of a handler
if ($('#elem').get(0) == document.elementFromPoint(x, y)) {
// Do stuff
}
Aside from that, the only other option that comes to mind is using event handlers to keep track of which element the mouse is over.

jquery tipsy plugin

Tipsy jquery plugin is installed in my app
This is in my load function
$(function() {
tipsy();
});
Below code is in a js file
var htm = '<div id="new_div" onmouseover="tipsy(this);">' ;
function tipsy(tip)
{
if ( '' != sumtitle )
{
tip.title = tip.innerHTML;
}
else if(tip)
{
tip.title = tip.innerHTML;
}
$(tip).tipsy({gravity: 'w'});
}
How is that the normal title shows up first and then the jquery tip later.
This is a known bug and will be fixed in the next version. For now please use the "Download Source" link on this commit:
http://github.com/jaz303/tipsy/commit/88923af6ee0e18ac252dfc3034661674b7670a97
The tipsy plugin seems to remove the title attribute and assign its value to a custom attribute called original-title to avoid the default browser tooltip from showing. Maybe in your case, this happens too late: The mouse hovers over the element, this initiates the native browser tooltip. Then, tipsy() is executed on the element and switches the attribute name, but that is too late because the timeout for the native tooltip has already started.
You should probably prevent the default action of the event, for example:
$('#new_div').bind('mousover', function (e) {
tipsy(this);
e.preventDefault();
});
EDIT: As this does not seem to have the desired effect, please call tipsy($('#new_div')) right after the div is created and remove the mouseover handler. What you have been doing might be a bit problematic anyway: The tipsy plugin probably uses the mouseover event, and you call .tipsy( { gravity: 'w' } ) in an onmouseover event handler. Repeatedly, if you mouseout and then mousover again. That's a lot of unnecessary event assignments.
You're doing it wrong.
Try this:
$('#new_div').tipsy();
jQuery is designed for using the selectors in JS code. No onsomething events in HTML, please.
Another way is, instead of using the 'title' attribute, use 'original-title' attribute.

Categories

Resources