Stop button from losing active state in jQuery UI buttonset - mouseleave

I'm trying to prevent my buttons from losing the active class on mouseleave, but I can't get it working.
So, my buttons are initialized with jQuery's buttonset(). They are buttons, not checkboxes. Checkboxes are out of the question because they require IDs to work.
This is my code:
$('.jquery_ui_buttonset', this.scope).buttonset();
$('.jquery_ui_buttonset > button', this.scope).each(function() {
$(this).bind('mouseleave keyup mouseup blur', function(e) {
if ($(this).hasClass('ui-state-persist')) {
e.stopImmediatePropagation();
if (e.type == 'blur') {
$(this).removeClass('ui-state-focus');
}
$(this).removeClass('ui-state-hover');
}
});
});
The idea is that if the button has the ui-state-persist class, it should not lose the ui-state-active class until both are explicitly removed. Switching of active buttons is done on click by this handler:
CMSPage.prototype.switchEditTab = function(e) {
if (e.data.params.id == null) {
return;
}
$('.editor .body', this.scope).hide();
$('.editor .header button', this.scope).removeClass('ui-state-active').removeClass('ui-state-persist');
$('.editor .body[data-tab-id=' + e.data.params.id + ']', this.scope).show();
$('.editor .header button[data-id=' + e.data.params.id + ']', this.scope)
.addClass('ui-state-active').addClass('ui-state-persist');
}
I've also tried adding e.stopPropagation() and e.preventDefault() and all their combinations, but it doesn't work. And this exact same code works for regular UI buttons (ones not in buttonset).
Any help would be appreciated.
EDIT
I still haven't resolved this problem. I would love to give you guys bounty for helping me out, but I can't since I'm a new member. Has noone ever encountered this problem in which he wanted to use buttonset() with persistently active buttons, and not checkboxes?

Related

Dropdown slideToggle if click anywhere except element that are cursor:pointer

So, i got a fancy dropdown that i want to slide back if clicks anywhere except on elements that are cursor:pointer..If you can understand me..
Currently I got this code:
$("html").click(function() {
if($(".user-dropdown").is(':visible')) {
$(".user-dropdown").slideToggle('fast');
}
});
You could simply verify the cursor type of element triggering event if its not pointer then slideback.
$("html").click(function() {
var cursorType = $(this).css('cursor');
if(cursorType!="pointer")
{
if($(".user-dropdown").is(':visible')) {
$(".user-dropdown").slideToggle('fast');
}
}
});
Try it out and see if it works for you.

closing an open div when body / html element is clicked in meteor

so i'm working on a meteor project and am trying to get a drop down menu to close when the user clicks outside of it. i've done this before using jquery and normal html but this time we're using velocity.js and meteor.
so on the link that opens the drop down div, i have this:
Template.layout.events({
'click #profile-btn': function () {
if (userTog == false) {
$('#user-menu').velocity("fadeIn", { duration: 150 });
userTog = true;
}
else if (userTog == true) {
$('#user-menu').velocity("fadeOut", { duration: 150 });
userTog = false;
}
},
.....
and then i use a meteor package to deal with events on the body as this isnt supported right now..
Template.body.events({
'click html': function(e, data, tpl) {
userTog = false;
$('#user-menu').velocity("fadeOut", { duration: 150 });
e.stopPropagation();
}});
however the above is just not working.. it basically just makes the menu appear then disappear straight away. is it something to do with velocity.js, meteor or am i just doing it plain wrong ?!?
any advice would be greatly appreciated!
I just had to make a material design select box, so I feel your pain :-). Here's how I solved it:
Normally, you can only focus an input or an anchor. A trick I stumbled upon is that using tabindex="0" in your element attributes allows it to gain focus, even if it's a div. What's this mean? Well, if you can focus() an element, that means you can blur() it. So, when you click the button for the dropdown, add a line at the end of the event handler like $('.dropdown-menu').focus(). Then, to escape that, just create an event handler like 'blur .dropdown-menu': function() {*..hide..*}. That way, you don't have these ugly global event watchers.
The downside is that you get a glowing blue outline (for accessibility reasons). You can get rid of this by having a line like outline: 0; in your css.
PS, the reason why yours wasn't working is because 'click #profile-btn' bubbles up to the body, so it executes both. To fix it, you need to stop that bubblin via e.stopPropagation();.

Hide Follow button Twitter Card Blockquote

I need to hide the follow button on Twitter card using :
<blockquote width="581" height="250" class="twitter-tweet"><p></p></blockquote></div>
How do you hide the follow button on a card ?
Thanks
The twitter widget expands into an iframe, so you would have to wait until it is fully loaded. Afterwards you could either fully remove the button or hide it. You will need a little JavaScript. The problem is that you would have to wait until it is loaded. I don't know how to catch when the tweet is fully loaded so I will be checking for the button every 100 milliseconds until it appears. You could of course change that to fit your needs.
JS:
window.setTimeout(removeButton, 100);
function removeButton() {
var iframe = document.querySelector('iframe.twitter-tweet');
if(iframe == undefined) {
window.setTimeout(removeButton, 100);
return;
}
var button = iframe.contentDocument.querySelector('.follow-button.profile');
if(button == undefined) {
window.setTimeout(removeButton, 100);
return;
}
//Hide
button.style.display = 'none';
//Or remove
button.parentNode.removeChild(button); //Note: Not using button.remove() because of compatibility
}
This of course right now only works for one single tweet. If you wanted to remove multiple Follow buttons, you would have to modify this script a little bit.

display:none hover trick on a touchscreen device

I am using a CSS hover trick to clean up my interface. Controls will only be shown when the cursor is hovering inside the element. I'm running into an issue when using the interface on a touch screen device. If the control button is not shown display:none and I touch where it should be, the event is still triggered for the button.
Try this fiddle both in your browser and on a touchscreen device to see what I mean...
http://jsfiddle.net/6PvCn/2/
On a touchscreen device, touch the red square and the alert should fire, without the button even showing up. I tested this on both the desktop Android Emulator and my real Android 2.3 phone.
The effect I'm going for is for the button to first be shown without firing, even if the user touches where the button "is".
I'd rather use a pure CSS solution before resorting to javascript.
Try pointer-events: none; along with display: none;
I just tested it on my real device, and it indeed executes the button's action.
You could maybe try to make the red box an image and change the image to a button by an onclick with Javascript. I would have provided you with some code if I wasn't short on time.
You can't do it with pure CSS, tapping the button will put the button into hover state and fire the click event. Instead you should fire the button off on active.
Here is the solution I came up with... http://jsfiddle.net/6PvCn/7/
On an Android touchscreen (don't know about IOS), the hover event for the hidden element is not fired if it is not shown. So basically I check to see if the element was hovered before it was clicked.
In a nutshell
$(".hidden").hover(function(e) {
if(e.type == "mouseenter") $(this).addClass("hovering");
else $(this).removeClass("hovering");
}).click(function(e) {
if(!$(this).hasClass("hovering") return false;
});
The fiddle explains the more complicated situation I had with form elements and dynamically added content. It provides a general solution as opposed to this element specific one.
I wrote a JS solution for you:
https://codepen.io/anon/pen/bmYROr
The trick is to prevent the button's click event getting fired for the first time the outer div is getting clicked because on touch devices click event has hover effect.
let isTouchDevice = true;
let isHovered = false;
document.getElementById('outer').addEventListener('click', (e) => {
if (isTouchDevice) {
if (!isHovered) {
e.stopPropagation();
}
isHovered = true;
}
}, true);
document.getElementById('outer').addEventListener('mouseleave', (e) => {
if (isTouchDevice) {
isHovered = false;
}
}, true);
document.getElementById('btn').addEventListener('click', () => {
alert("hi");
});

How can I disable all buttons and links on my page, but still let the postback occur?

I'm trying to prevent the user from clicking on more than one postback-causing element on the page. In other words, if they click the 'continue' submit button, they shouldn't be able to cause another postback before the original request comes back.
I've had a go with two versions of jQuery code. Neither does exactly what I want:
This version will disable all the postback elements, but in doing so, it stops the clicked element from firing. For the record, I don't think the .removeAttr('onclick') is really required, but leaving it out doesn't seem to change the behaviour.
$(function() {
$('a, :button, :submit').click(function() {
var elements = $('a, :button, :submit');
elements.attr('disabled', 'disabled').removeAttr('onclick');
});
});
This version disables all other postback elements, but it lets me reuse the same element that was clicked - I don't want to be able to hit the same button twice.
$(function() {
$('a, :button, :submit').click(function() {
var otherelements = $('a:not(#' + $(this).attr('id') + '), :button:not(#' + $(this).attr('id') + '), :submit:not(#' + $(this).attr('id') + ')');
elements.attr('disabled', 'disabled').removeAttr('onclick');
});
});
How can I prevent this behaviour?
I just tested your first approach without JQuery, and it worked fine, i.e. disabling the submit button didn't prevent the form submission.
<form method="get">
<input type="text" name="textfield" value="a" />
<input type="submit" onclick="this.disabled=true">
</form>
Maybe you want to double check is there is anything else, e.g. JQuery, going on?
Maybe you could put a flag or something that it could remember what button it was clicked and if that flag exist, you can remove the onclick event on that postback-causing element. But I think this cannot be done in client side scripting alone, since once the page is submitted, all client side elements and scripts are refreshed.
Perhaps instead of making this a click function make it onmouseup so it fires after the click event has occured.
Here's a final version that worked - just overriding the form submit event rather than looking at any individual elements.
var submitted = false;
$(function() {
$('form').bind('submit', function() {
if (!submitted) {
submitted = true;
return true;
} else {
return false;
}
});
});
Thanks all for your suggestions.

Resources