Im confuse on how the event methods/functions related to each other when they are use at the same time.
For Example:
$("#searchInput").blur(function(e) {
var isClicked = false;
$("#sresult").click(function(e) {
isClicked = true;
});
if(isClicked) {
$("#sresult").show(150);
} else {
$("#sresult").hide(150);
}
});
The code above shows when I blur on the #searchInput, it will either show #sresult when you click it or hide it when when you did'nt click it.
But there is something wrong in my code that I don't know why it keeps hiding even if I clicked the #sresult.
Is it that maybe when you click the #sresult, the $("#searchInput").blur(function(e) is fast enough that he didnt want to wait in $("#sresult").click(function(e) to function? are event methods are waiting for each other? are they synchronize? correct me if im wrong.
Thanks in advance.
The Problem
It's important to understand what .blur() and .click() functions really do. They attach event listeners to a certain element. (Better use .on() btw)
The Explanation
To your code: blur fires, prepares a variable and attaches another event listener. as the if-else statement is also in the blur callback it's executed immediately and thus not waiting for the click, meaning isClicked will never be true.
Using nested event listeners is almost never a good idea, you just saw why in your own case.
The Solution
Am I right with the assumption you're trying to hide a search results field until the search button is clicked? If yes I could help you with code. Though, the easiest approach might be to simply attach a listener for the button and then .toggle() the results.
Related
I have an APEX application where there are many drop down items. I've bound change event handlers to them using the bind function of jQuery.
Now when I load the content of a drop-down programmatically using $('#ELEMENT').trigger('apexrefresh'), the drop-down reloads but the change event handler fires automatically.
How do I prevent this from happening? I tried avoiding binding the event handler using bind and instead adding the onChange attribute to the element. The incorrect behaviour was still present.
Here is the skeletal code:
$(document).ready(function()
{
$('#P7021_MSG_DEF').bind('change', function(e)
{
console.log('bound function onChange() msg_def');
updateStartWord();
}
);
});
function updateMsgDef()
{
console.log('function updateMsgDef() ');
$('#P7021_MSG_DEF').one('apexafterrefresh', function()
{
if( $x('P7021_RESTORE_CHK').value == 'Y')
{
setdefault('P7021_MSG_DEF', vJson.msg_def);
}
updateStartWord();
}
).trigger('apexrefresh');
}
In the above code, when the updateMsgDef is called from another function the function updateStartWord() gets called twice - once by updateMsgDef() itself and again by the onChange handler that was bound to P7021_MSG_DEF item.
If anyone could help on this?
Calling $('#ELEMENT').trigger('apexrefresh') is going to trigger the change event. Short of going back to the drawing board altogether, the solution is going to be a hack whatever you do. You could poke about in (and quite possibly break) Oracle's javascript. You could write your own AJAX to populate the select list.
The easiest way might be to check in your onChange event which element currently has focus, eg:
onChange = "if($( document.activeElement).attr('id')=='YOUR_PAGE_ELEMENT')
{ $( document.activeElement).trigger('apexrefresh'); };"
If the user has changed the select list, it should still have focus. There's no guarantee that will work in all browsers, but I think it should be ok in current Chrome and IE versions.
I've been in a similar situation to yours, and have come to accept that if the page logic is too complicated to implement using DAs, maintaining it is likely going to be a nightmare whatever happens. Much as I like "proper" programming, Apex is really all about the declarative controls.
This is a bit of an abstract question, but I've been pondering its usefulness, and maybe it's either already been solved or inspires someone to do something based on it.
Well recently I ran across an issue whereby three browser events were fired, all as the result of a single user interaction: click, blur and focus. When the user clicks from one input to another, these events occur; and a similar set occur when the user tabs from one to another.
The trouble I had was that they fired in this order: blur, focus, click. It meant that, if the blur event caused DOM changes, the click event could be affected. I really wanted click, blur, focus - but that's not what the browser gave me.
I figured a general utility could be produced, capturing and cancelling browser events, then synchronising them and firing a single handler for all three. Perhaps extending the Event class so that the event could be reinstated.
Is there a more abstract design pattern I can use here? Something that will allow me to set up an arbitrary number of event listeners, and then fire a single event when all are complete? Does it have an implementation already? All advice welcome.
Dont need to break head around this! you can always trigger these events Programmatically
Note: object referenced here is any element selected using javascript selector.
Initially onBlur & onFocus do event.preventDefault which allows onClick to do its job first
var clicked=false;
object.onblur = function(e) {
if (!clicked) {
e.preventDefault
}
};
object.onfocus = function(e) {
if (!clicked) {
e.preventDefault
}
};
inside click event undo the above preventions and trigger the events in the order you wanted
object.onclick=function(){
clicked=true;
//Do anything
object.unbind('blur'); //this do undo prevent default
object.unbind('focus'); //this do undo prevent default
object.blur(); //in order you want
object.focus();
//make sure to put condition if click clicked
};
Thats it ! Hope it helps
Is there any way to know, in a jQuery onmouseup handler, if the event is going to be followed by a click event for the same element?
I have an event handler for a menu hyperlink which unbinds itself when the user either clicks on an element or "drops" (as in drag-n-drop) on an element. I want to avoid prematurely unbinding the handler on mouseup if a click is coming next.
I realize I can track mousedown and mouseup events myself or otherwise hack up a solution (e.g. wait 50 msecs to see if a click comes soon), but I was hoping to avoid rolling my own implementation if there's something built-in for this purpose.
There is nothing built-in because it's really specific to your needs. Thus, there would kilometers of code and documentation to maintain if jQuery would handle any combination of clicks, long clicks, moves, etc.
It's also hard to give you a snippet that satisfies your needs, but a setTimeout is usually the first step to take, with something like that :
obj.mouseup = function (){
obj.click = action; // do action
setTimeout ( function() {
obj.click = functionOrigin // after 500 ms, disable the click interception
}, 500);
};
you can use $(selector).data('events') for that
$('div').mouseup(function(){
if($(this).data('events').click){
console.log('Has a click event handler')
}
});
So on Friday I asked this question and it wasn't well written, let me explain this in better detail:
So this might sound remedial, but I have this container that I include a mousedown event and all I want to do is toggle it without destroying the properties of it.
If it do :
$("#div").unbind("mousedown") // This will just destroy the event.
I was thinking I could move the event to a dom element that isn't being used? And then just switch it back when I'm done...
So this is whats happening : I have a plugin lets just call it Vinny for now
$("#div").vinny(settings);
vinny has a mousedown event that I want to enable/disable via a trigger.
I was thinking I would have a $fn.disableMouseDown function that could disable it, but was curious if theirs a way to unbind a mouseDown on the dom but not destroy it?
If you know of a quick way of doing it help me out! Thanks, Vinny
Put your command inside a function, so you can bind/unbind with one line only, i.e:
function some() {
// some commands
}
$("#div").bind("mousedown", some);
$("#div").unbind("mousedown");
One approach is to just use a named function, bind it when it's needed and unbind it when it's not:
function foo () {
// do something on mousedown
}
// When needed:
$("#div").bind("mousedown", foo);
// When not needed:
$("#div").unbind("mousedown", foo);
I would just stick an if(toggle) statement inside the event. Any reason you can't do that? (only thing i can think of is you wouldn't want to have the event being continually fired over and over, which makes sense - is that the case?)
here is a working example http://jsfiddle.net/samccone/ENzyk/
I think this is a simple and elegant solution
Hey guys thanks for all the ideas, but I kinda did a hacky way of approaching this.
I explainz:
So this plugin on the mousedown is binded in the plugin.init() and in their i defined a local function checks disableValue and in their I just check the dom for a or do a bool return and run that against the other function that was already present in exiting the mousedown event.
Make sense? I hope so too
Thanks,
I am wondering if you guys know different approach to disable an event for a while. Let me elaborate this more :
Lets say I have a div or button which has a subscriber to its onclick event. To prevent the double click when the the methods are doing some ajax things, these are the some of the ways we can do :
Disable the button till the method finishes its job
Unbind till the methods finishes its job and then bind it again.
Use some kind of flagging system like boolean so it will prevent method from working more than once.
So is there any other ways, maybe some javascript tricks or jQuery tricks which is more efficient and better practice.
Thanks in advance.
I just add some class like 'disabled' to that div or button. And in my function registered to the onclick event, I check if that class is present. If yes, just return.
Can't think of any other way other than what u have stated.
I think the boolean flag is quite an elegant solution, and you can keep it "contained" by using a property of the handler, like so:
$(someElement).click(myHandler);
function myHandler() {
if (!myHandler.inProgress) {
myHandler.inProgress = true;
// Do stuff
// Set it back to false later
}
}
I can't think of a more 'tricky' or 'elegant' solution, than the ones you listed.
what is so inefficient in disabling an element or removing a binding?