Why is jQuery .prop not working, seemingly? - javascript

Sql Fiddle example
$('#myBox').click(function(e){
e.preventDefault();
e.stopPropagation();
$('#myBox').prop("checked", !$('#myBox').prop("checked") );
});
I'm attaching this to a checkbox so that the check toggling is controlled by my javascript instead of by the default behavior, and it just won't work. I can't figure out why!
My reason for doing this: IE has a double-click filter, so to speak, so that double-clicking checkboxes only registers as a single click. This happens to stop people from toggling checkboxes really fast, which is a feature I need for my application, strangely enough. So I'm just canceling its default functionality and catching clicks by hand with JavaScript/jQuery and toggling it that way, thus eliminating the "speed limit." Except I don't know how to stop the clicks from toggling it in the first place, hence this question.

setTimeout(function() {
$('#myBox').prop("checked", !$('#myBox').prop("checked") );
}, 1);
The delayed timer of 1 millisecond is all it takes.
See this in your jsFiddle, modified.

I'm guessing you want to run something when your checkbox changes...
In that case you should be catching the change event:
$('#myBox').bind('change', function() {
// Do checks here, if you don't want it to change, then deal with it then
});

Related

Preventing queues with JQuery effect() with fixed position elements

The Situation
I am using the effect() function of JQuery UI. The type of effect doesn't really matter but for the purpose of this question lets use "bounce". This effect is called when a link is clicked, so my complete example code is as follows:
$('#button').click(function (e) {
e.preventDefault();
$('#box').effect('bounce');
});
Here is a demo
The Problem
The problem I have, or more the behavior I want to get rid of, is that when you click the link multiple times in quick succession then it queues up the animations. (See the demo, click the link 10 times fast, then release and watch it continue to animate)
The Requirement
I just want to prevent effects/animations from being queued. In other words, I am looking for clicks to be ignored if the box is already bouncing. Is there anyway I can do this?
The Failed Attempts
I have already done some research, and I tried a couple of method below but to no success:
$('#box').stop().effect('bounce');
stop() just doesn't seem to have any effect in this case.
$('#box').clearQueue().effect('bounce');
clearQueue actually works in the sense that the effects don't queue, however there are side-effects which causes the layout to mess up. I assume this is because it prevents the effect from returning the styles to their defaults. It may also be related to using a fixed position for the box.
This should do the trick.
$('#button').click(function (e) {
e.preventDefault();
if( !$('#box').is(':animated') ){
$('#box').effect('bounce');
}
});
Yes you are right, clearQueue makes position changes in div but i tried that and it looks like working
$('#button').click(function (e) {
e.preventDefault();
if ($("#box").is(':animated')) {
$('#box').effect = null
}
else {
$('#box').effect('bounce');
}
});
js fiddle example
Try this:
$('#button').click(function (e) {
e.preventDefault();
$('#box').stop(true).effect({
effect: 'bounce',
complete: function() {
$('#box').removeAttr('style');
}
});
});
stop(true) stops and clears the queue immediately but when stopped, effect() leaves inline styles after completion. They just need to be removed afterwards.
The benefit of this approach is that the clicks feel a little more responsive (for the lack of a better word). The box will seem to react quickly to user's clicks.
However, if you cannot afford to simply remove the style attribute upon completion of animation, say you have previously applied inline styles on your object, you can cache them beforehand and re-apply them upon completion, which is demonstrated in this fiddle.
Hope this helps.

Reset bootstrap switch state

Firstly, here is a JsFiddle: http://jsfiddle.net/VTv2j/76/
This is what I want to happen:
Switch starts in the indeterminate / in-between state (this works)
Event fires when user chooses either state (this works)
When use clicks RESET the switch goes back to the indeterminate / in-between state (this works)
Event fires when user chooses either state (this DOES NOT work)
What is happening is if the user goes back to whatever the previous state was then no event fires. So say it was on YES, they click RESET, then click YES again - no event fires (but if it was previously on YES, and the reset then went to NO then the event would fire).
I've got no idea how to approach this. I've tried things like destroying and recreating the switch:
$('input[name=test]').bootstrapSwitch('destroy');
$('input[name=test]').bootstrapSwitch();
To no avail unfortunately.
Here is the important thing for me - all I need to know is when the user moves from the indeterminate state to ANY state. I don't actually care what they choose, as long as they choose something. So if anyone can think of a different type of workaround with that in mind (maybe it makes it easier) that would definitely be welcome.
Any help is appreciated, this is driving me crazy.
Here's a working version of the code above: http://jsfiddle.net/byzwng4t/1/
function initializeSwitch(selector) {
$(selector).bootstrapSwitch('destroy', true);
$(selector).bootstrapSwitch({
'state': null
});
$(selector).on('switchChange.bootstrapSwitch', function(event, state) {
console.log('change event' + (new Date()).getTime());
});
}
$(function() {
initializeSwitch('input[name=test]');
$('.reset').click(function() {
initializeSwitch('input[name=test]');
});
});
The trick is to bind the events again after destroying the switch.
$('input[name=test]').bootstrapSwitch('state', $('input[name=test]').is(':checked'), true);
Refer: http://bootstrapswitch.site/methods.html
Stackoverflow: Bootstrap Switch - Change state after clicking on button

Sharing an event across two scripts or using change is visibility state as an event trigger

OK I am lost here. I have read numerous postings here and else where on the topic of how to check for the state of a given element in particular whether it is visible or hidden and make the change of state trigger an event. But I cannot make any of the suggested solutions work.
Firstly, as every one seems to leap on this point first, the need to do this has arisen as I have one jQuery script which deals with displaying an svg icon in a clickable state. And another which already has functions to perform relevant actions when the form is made visible by clicking the icon and obviously I want to reuse these.
What I have tried:
Initially I tried have both the scripts acting on a single click event (this remains the ideal solution)....
Script 1:
$(".booked").on("click", function() {
$("#cancellation_Form_Wrapper").css("visibility","visible");
}).svg({loadURL: '../_public/_icons/booked.svg'});
Script 2:
$(".booked").on("click", function() {
// do stuff
});
This did not work so I tried to research sharing an event across two scripts but couldn't make any head way on this subject so I tried triggering another event for the second script to pick up....
Script 1:
$(".booked").on("click", function() {
$("#cancellation_Form_Wrapper").css("visibility","visible");
$("#cancellation_Form_Wrapper").trigger("change");
}).svg({loadURL: '../_public/_icons/booked.svg'});
Script 2
$("#cancellation_Form_Wrapper").on("change", function(event){
// do stuff
});
This did not work again I am unclear why this didn't have the desired effect.
Then I tried is(:visible) ....
Script 1
$(".booked").on("click", function() {
$("#cancellation_Form_Wrapper").css("visibility","visible");
}).svg({loadURL: '../_public/_icons/booked.svg'});
Script 2
$("#cancellation_Form_Wrapper").is(":visible", function(){
// do stuff
});
So I am a bit lost. The ideal would be to return to the first notion. I do not understand why the click event on the svg cannot be handled by both scripts. I assume that this has something to do with event handlers but I am not sure how I could modify the script so they both picked up the same event.
Failing that I could use the fact the visibility state changes to trigger the action.
Any guidance welcomed.
Edit Ok I have just resolved the issue with script 2 picking up the triggered event from script 1. Sad to say this was a basic error on my part ... the form was preventing the display of the alert. However I still cannot get the is(:visible) to work.
Your syntax may be off:
$("#cancellation_Form_Wrapper").is(":visible", function(){
// do stuff
});
should be:
if($("#cancellation_Form_Wrapper").is(":visible")){
// do stuff
});
EDIT: If you want something to happen after a div is made visible, you may want to use the show() callback rather than toggling visibility:
$('#cancellation_Form_Wrapper').show(timeInMilliseconds, function(){
// do something
});
However, this needs to take place in the same function, which I don't think improves your position.
The problem is probably that your second on() script is firing at the same time as your first, meaning the wrapper is not yet visible. You could try wrapping the second on() in a short timeout:
$(".booked").on("click", function() {
setTimeout(function(){
if($("#cancellation_Form_Wrapper").is(":visible")){
// do stuff
});
}, 100);
});
That should introduce enough of a delay to make sure the wrapper has been shown before trying to execute the second statement.

Google chrome, infinite loops and selecting text

This question comes with a bit of background. Please see two other questions I've recently posted that relate:
How to select text in a textbox cross-browser
Infinite loops created in google chrome
Word of warning: it's possible that the second link is a red herring.
Ok so my problem is that I'm trying to have it so when a user first clicks or tabs in to a textbox, all the text should become selected. If the textbox has focus, subsequent clicks on the text inside the textbox should behave normally (ie. doesn't re-select all the text). The answer I choose in the first link above is the one I found worked across all browsers. Code posted below for your convenience:
$('input[type="text"]').live('focus', function (event) {
var inp = this;
setTimeout(function () {
inp.select();
}, 1);
event.stopPropagation();
event.preventDefault();
return false;
});
Now my second link above is what I seem to be running in to with this approach. It seems that intermittently, google chrome gets stuck somewhere and starts changing the focus between textboxes really fast. You can see what I think is happening here: http://jsfiddle.net/ajbeaven/XppG9/14/
Like I said, it seems to be an intermittent problem so you might have to try reloading the page a couple of times in order to see what I think might be causing the changing of focus. Remember, it only seems to happen in chrome.
Thanks to anyone who can shed some light!
Put any additional work in the setTimeout function. And add a clearTimeout() before you setTimeout():
var focusTimeout = 0;
$('input[type="text"]').live('focus', function(event) {
var inp = this;
clearTimeout(focusTimeout);
focusTimeout = setTimeout(function() {
$('#message-container').html($('#message-container').html() + "*\u200b");
inp.select();
}, 1);
});
http://jsfiddle.net/XppG9/19/
In Chrome, writing the html to the page is (apparantly) causing the field to lose focus, and select() is causing it to receive focus 1ms later, thus triggering the focus event and causing the infinite loop. Moving the write html call into the function that selects the text seems to do the trick.
Oh man, I just figured it out. This bug probably won't happen to you on a real website. It's happening because you are updating the DOM adding a "*" to the message div. When you do this, it pushes the content of the page down. This moves the top text box to where the mouse is, and the mouseup event is triggered on the top text box, causing both text boxes to fire a setTimeout and getting in an infinite loop. Total dibs on reporting this.
edit: it's probably not the mouseup event. looks like chrome thinks you are legit focusing on both. Here's the bug test case for Chrome: http://jsfiddle.net/delvarworld/AnBE8/
edit2: This happens in Safari too. Most likely a webkit issue.
tldr simple workaround is to not update the dom in a way that causes reflow on the focus event, as in get rid of the html() line
You could also try:
$('input[type="text"]').live('mouseup', function (event) {
Which works in Chrome for me

How do I force a blur event to occur in JavaScript?

Here's what I want to do. I want to trigger an event every time a select element changes. I have a multiline select and when I make changes (click on elements), it does not change until the select box loses focus. So I'm trying to force a blur every time the select box is clicked. That way if it changes, it will trigger the changed event. If it doesn't change, nothing will happen.
How do I do this? Am I even approaching this the right way? Jquery answers are okay as well.
In addition to Ender the full code could be something like this.
$('#mySelectBox').change(function() {
$('#thingToBlur').blur();
})
Reference: http://api.jquery.com/blur/
This will find the element with the focus and trigger the blur event.
function blur(){
document.querySelectorAll('input,textarea').forEach(function(element){
if(element === document.activeElement) {
return element.blur();
}
});
}
Using jQuery do:
$('#mySelectBox').change(function() {
//do things here
});
According to the documentation at http://api.jquery.com/change/, the event is triggered immediately when the user makes a selection.
Check out this demo to verify that this works: http://jsfiddle.net/AHM8j/
You could attach an onclick handler to the select and the individual options. basically onclick="this.blur();". I've always found that click events on <select> elements to be a pain, as nothing happens at the point you expect it to.
Okay, Here's what was going on. I was including the -vsdoc version of JQuery instead of the actual JQuery library. This also fixes some issues I was having with some plugins such as blockUI.

Categories

Resources