I have a GeoExt map panel with a zoom control. I'd really like to disable some of the nodes in a tree panel when the layers on my map are "out of range" aka their setVisibility is set to false. I have my zoomend event working and I also have a checkchange event working, but the checkchange event gets evaluated more than once if the user pushes the zoombar more than one level and the other problem is that even after the zoomend event is over the checkchange still gets fired every time the user merely clicks the node's checkbox on or off. I really need a way to control this checkchange event to only run once and to stop it from firing if the user is not using the zoombar...
map.events.on({ "zoomend": function (e) {
layerTree.on("checkchange", function (node, checked) {
alert(node.text + "Inside event");
if(checked == false)
node.disable();
else if(checked == true)
node.enable();
});
if (this.getZoom() > 7) {
tib_villages.setVisibility(true);
tib_lakes.setVisibility(true);
tib_townships.setVisibility(true);
}
else {
tib_villages.setVisibility(false);
tib_lakes.setVisibility(false);
tib_townships.setVisibility(false);
if (this.getZoom() > 5) {
infrastructure.setVisibility(true);
geography.setVisibility(true);
geography2.setVisibility(true);
tib_countys.setVisibility(true);
}
else{
infrastructure.setVisibility(false);
geography.setVisibility(false);
geography2.setVisibility(false);
tib_countys.setVisibility(false);
}
}//end else
}//end function (e)
}); //end map.events.on
Thank you for all your time and feedback :)
elshae
It turns out that the work has already been done for us :). There is a patch at http://trac.geoext.org/attachment/ticket/235/autoDisableLayerNode.patch which will automatically disable/enable nodes based on their minScale/maxScale properties etc. I applied the patch by putting this file in my GeoExt directory and running the following command in my GeoExt directory:
patch -p0 < autoDisableLayerNode.patch
I hope this helps! It worked wonders for me :)
elshae
Related
I have a jQuery change event for when a user changes a given SELECT element. However the event may also be triggered by a third party script. What I want to do is detect whether the event was triggered programmatically or by the user.
I have tried the accepted solution in this question Check if event is triggered by a human
But note the JSFiddle in this answer is for a click event rather than a change event.
To demonstrate I amended the fiddle and created this one: http://jsfiddle.net/Uf8Wv/231/
If you try this in latest Firefox or Chrome, you will see that the alert human is being shown even when the event was triggered programmatically.
I have tried event.originalEvent.isTrusted but that doesn't work in all browsers. Can anyone help?
I have added mouseenter and mouseleave events. The idea is that it's a human if the click coincided with a mousepointer being over the element. See:
http://jsfiddle.net/Uf8Wv/232/
$("#try").mouseenter(function(event) {
mouseover = true;
});
// ... etc.
I can't think of any other way.
You can find some vague difference between click and emulated click using this code:
$(document).on('change', "#try", function (event) {
//some difference appear in the next line
console.log(event.delegateTarget.activeElement);
//no difference
if (event.originalEvent === undefined) {
alert('not human')
} else {
alert(' human');
}
event.delegateTarget = null;//doesn't help
});
$('#click').click(function (event) {
$("#try").click();
});
Click on the checkbox logs <input id="try" type="checkbox">.
Click on the button logs <button id="click">.
But...
Run $("#try").click(); from console before any clicks logs <body> and after the click result of the last click.
Generally JS can always fake any client event. So isTrusted is never trusted.
You can listen to the click event as well, and modify a variable. The change event seems indeed to be quite similar wheter it's a real click or a script triggered click, but the click on #try event won't be the same. And since click is triggered before change, you have time to set a switch.
Like this for example:
var realClick;
$("#try").change(function(event) {
console.log('change')
if (!realClick) {
alert('not human')
} else {
alert(' human');
}
});
$("#try").click(function(event) {
console.log('click')
// originalEvent is one way, but there will be many differences
if (event.originalEvent) {
realClick = true;
} else {
realClick = false;
}
});
// Since this is called from outside, better not put
// any controls here.
$('#click').click(function(event) {
$("#try").click();
});
http://jsfiddle.net/2xjjmo09/3/
What really worked for me is:
if ((event.originalEvent.isTrusted === true && event.originalEvent.isPrimary === undefined) || event.originalEvent.isPrimary === true) {
//Hey hooman it is you
//Real CLick
}
Tested with jQuery version 3.5
You can easily detect whether the click event on the button is actually triggered by mouse click or not. By doing,
$('#click').click(function(ev) {
if (ev.which !== undefined && ev.button !== undefined) {
$("#try").click();
}
});
Here's the Fiddle
Note: Beware of either ev.which or ev.button could result in 0 on some browser for left-click.
You can check for if event.srcElement (which is source element on which event is triggered) is equal to event.currentTarget something like:
$("#try").change(function(event) {console.log(event,event.target,event.currentTarget,event.srcElement)
if (event.currentTarget=== event.srcElement) {
alert(' human')
} else {
alert(' not human');
}
});
Fiddle: http://jsfiddle.net/Uf8Wv/234/
I'm currently stuck at the following problem:
I need to create a delay when dragover happens en then check if current dragover object is still the same. When it's the same object -> execute code.
This is my code:
var draggedId = null;
var triggered = false;
function allowDrop(ev) {
draggedId = ev.target.id;
setTimeout(function () {
if (draggedId == ev.target.id && ev.target.id != "" && !triggered) {
triggered = true;
draggedId = "";
ev.preventDefault();
}
}, 2000);
}
function drop(ev) {
ev.preventDefault();
}
function dragLeave(ev) {
draggedId == "";
triggered = false;
}
Allowdrop function is the dragover event.
ev.preventDefault() to allow the drop can't happen there because that function is assync.
Any idea's?
Thanks,
Mathias
Can you explain more about what you are trying to achieve and I can answer more fully ?
It's generally the case that you cannot always say for certain whether a drop will work, the best you can do is to setup drop zones on your page and have them cancel the dragover event based on what you can tell about the drop. If you want to make your application work with cross window dragging, then you cannot rely on a global variable to store information about what is being dragged, and you cannot actually see what is inside the drag - you can only know what kind of thing is being dragged. So if the drop might be acceptable you need to cancel the event. See this question
I think that maybe you are confused about how dragevents propagate which is the reason you think you need a timeout ? But blocking the event queue to figure out whether you accept a drop, or trying to cancel the drag event after it has already bubbled to the top and been handled in the default way by the browser (which is to not accept the drop) isn't going to work.
I've encountered a situation where some script changes a select/radio/checkbox. That fires the change event. However I need, separately, an event to tell me the user changed the element, and obviously when change fires from the script it registers as a user change.
Is there a way to prevent a script from firing the change event when you alter the value of a select/radio/checkbox?
Use jQuery.trigger() and pass an additional parameter when triggering the event from code.
For example:
$('select').bind('change', function(e, isScriptInvoked) {
if (isScriptInvoked === true) {
// some code for when artificial
} else {
// some code for when organic
}
});
// Trigger the event.
$('select').trigger('change', [true]);
Try:
function changeEvent(){
if(this.type.toLowerCase()=='select' || this.type.toLowerCase()=='radio' || this.type.toLowerCase()=='checkbox')
return false;
else{
//Your code here
}
}
We all know that you can simulate click or any other event on an element using one of these ways:
$('#targetElement').trigger('eventName');
$('#targetElement').click();
I have encountered a situation in which, I should know how an element is clicked. I should know if it's been clicked automatically via code, or by pressing mouse button. Is there anyway I can do it without hacks or workarounds? I mean, is there anything built into browsers' event object, JavaScript, or jQuery that can tell us whether click has been initiated by a human action or by code?
Try this:
$('#targetElement').click(function(event, generated) {
if (generated) {
// Event was generated by code, not a user click.
} else {
// Event was generated by a user click.
}
});
Then, to make this work, you have to trigger them like this:
$('#targetElement').trigger('click', [true]);
See this jsfiddle.
Check out event.which, it'll be undefined if triggered with code.
$(document).click(function(event) {
if (event.which) {
// Triggered by the event.
} else {
// Triggered with code.
}
});
jsFiddle.
Here's one way I have found (tested in Chrome)
$('#foo').click(function(e) {
if (e.originalEvent)
alert('Has e (manual click)');
else
alert('No e (triggered)');
});
See here for testing: http://jsfiddle.net/ZPD8w/2/
In your immediate event handler, provide an e parameter. If the click is automated (via code), this e would be undefined (no need to check e.target as #alex has said):
$('#targetElement').click(function(e){
if(e)
{
// Click is triggered by a human action
}
else
{
// Click is triggered via code
}
});
I am using this code to dynamically change the text of a span element. It works in chrome, only changing the content of the span once, but does an infinite loop in IE (the count keeps updating and the html text keeps changing). Anyone know how I can fix it or why its happening?
bindFlagUpdate();
function bindFlagUpdate(){
$(document).bind('flagGlobalAfterLinkUpdate', function(event, data) {
var string = $('#like-' + data.contentId).html();
var getNum = string.match(/[0-9]+/g);
var count = getNum[0];
if(data.flagStatus == 'flagged') {
count++;
} else {
count--;
}
$('#like-' + data.contentId).html("1 user likes this");
$(document).unbind();
bindFlagUpdate();
return false;
});
}
Description of the event:
The flagGlobalAfterLinkUpdate event This event is triggered
immediately after a flag link has been updated. (Flag links appear in
two flavors: "Bookmark this!" and "Unbookmark this!", and when we
speak of "update" we mean this change in appearance).
The even is attached to a "flag" button
To answer this we need to know more about the event flagGlobalAfterLinkUpdate and how it is triggered. It sounds like something in the callback function for the event is triggering the event, so once it's triggered once, it triggers itself continuously.