how to get a button in an Openlayers popup? - html

I am trying to put a button inside of an Openlayers popup. While the button appears to display correctly with the following code, the function 'handlerFunc' does not execute when the button is clicked. The segment of code I have posted is all within another function (so handlerFunc is actually a nested function). I'm using JQuery for the button itself. Any ideas on what might be going wrong? Thanks!
var feature = new OpenLayers.Feature(presences, ll);
feature.popupClass = popupClass;
feature.data.popupContentHTML = "<button id='popupButton'>Click me</button>";
feature.data.overflow = (overflow) ? "auto" : "hidden";
feature.data.icon = markerIcon;
$('#popupButton').button();
$('#popupButton').click(handlerFunc);
function handlerFunc() {
// do something
}

Most likely reason is that your button doesn't exist when you bind to a click event. $('#popupButton') returns null. Instead of using $('#popupButton').click(handlerFunc); try $('#popupButton').live('click', handlerFunc);. That means that we bind to an event not only when DOM is built, but when object appears.

Related

Wrong code in tutorial for event listeners

I am following this tutorial to build a store locator page with a Mapbox map.
I don't want to add custom markers because I already have custom map labels (symbols?), which means I don't need the optional last section of the tutorial and stop right after Add Event Listeners.
Once this is completed, the page should react to clicks in the side panel list, as well as on the map (2 event listeners). However, in the demo provided in the tutorial for that particular step, you can tell the code for the second event listener, the one making the map clickable, is not functioning, which makes me believe there is a mistake in the provided code:
// Add an event listener for when a user clicks on the map
map.on('click', function(e) {
// Query all the rendered points in the view
var features = map.queryRenderedFeatures(e.point, { layers: ['locations'] });
if (features.length) {
var clickedPoint = features[0];
// 1. Fly to the point
flyToStore(clickedPoint);
// 2. Close all other popups and display popup for clicked store
createPopUp(clickedPoint);
// 3. Highlight listing in sidebar (and remove highlight for all other listings)
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
// Find the index of the store.features that corresponds to the clickedPoint that fired the event listener
var selectedFeature = clickedPoint.properties.address;
for (var i = 0; i < stores.features.length; i++) {
if (stores.features[i].properties.address === selectedFeature) {
selectedFeatureIndex = i;
}
}
// Select the correct list item using the found index and add the active class
var listing = document.getElementById('listing-' + selectedFeatureIndex);
listing.classList.add('active');
}
});
Would anyone be able to tell what is wrong with this code?
Turns out the code is incomplete in that the cursor doesn't change to a pointer as you hover over a map label/marker so it doesn't clue you into realising you can click on it, hence my assumption it wasn't working at all. I assume the general users who would then face the map would be equally deceived unless the pointer shows up. So in the tutorial, if you do go ahead and click the marker, it will have the expected behaviour and display the popup, although no pointer is shown.
Here is how to create the pointer, based on this fiddle: https://jsfiddle.net/Twalsh88/5j70wm8n/25/
map.on('mouseenter', 'locations', function(e) {
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'locations', function() {
map.getCanvas().style.cursor = '';
});

AS3 set focus on specific component

I have a form with several component: datagrid, textArea, text input...
For each component FocusIn Event is available.
var objTarget:String;
protected function memo_focusInHandler(event:FocusEvent):void
{
objTarget=event.currentTarget.id;
}
With memo_focusInHandler, I know which has focus.
My goal is to backup last focus objet, and re open Windows with focus on this object.
I try to do this:
objTarget.setfocus();
But it doesn't work. Could you help to found the best way to reach my goal.
String is not a display object, thus it can't be in focus. The representation of string on the stage is a TextField.
In as3 you can set focus to the desired target by using stage method:
stage.focus = myTarget;
Please see the corresponding documentation section: https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Stage.html#focus
There is no need (that you've shown) to work with the string id reference. It would much simpler (and slightly more efficient) to work directly with the object reference.
var objTarget:Object; // Object instead of type :String
protected function memo_focusInHandler(event:FocusEvent):void {
objTarget = event.currentTarget; //instead of the currentTarget's id property, assign the current target itself
}
Then, when you want to reset focus, you can do:
if(objTarget is TextInput || objTarget is TextArea){ //make sure it's a text input or text area first - optional but recommended if you don't like errors
objTarget.selectRange(objTarget.text.length, objTarget.text.length); //set cursor to the end
objTarget.setFocus(); //focus the text input/area
}
I found a solution:
this[objTarget].selectRange(this[objTarget].text.length, this[objTarget].text.length);
this[objTarget].setFocus();

Tooltip-like Functionality in UiApp

I want to add tooltips to Labels in UiApp. I was thinking about MousOverHandlers on each (important) Label, as there is no function like Label.setTooltip().
Is there any way to implement this functionality? The only thing I can think of doing is:
Creating a hidden Label (eh, don't really want to)
Add a MouseOverHandler to the Label I want a tooltip on
Make the hidden Label visible in the event handler
I don't really like this solution - is there a better way?
Have you tried Label.setTitle("tooltip text") directly on your widget? (works also with other widgets of course)
I guess that's what you are looking for .
Basic example testable here :
function doGet() {
var app = UiApp.createApplication();
var abs = app.createAbsolutePanel().setStyleAttributes({"background":"#FFA","padding":"60px"});
var lab = app.createLabel('Hover your mouse over this label').setTitle('There it is !');
app.add(abs.add(lab));
return app;
}

Toggle widget visibility with single button

The following code should write the inverse of true/false as found in the textbox back into the textbox when the button is clicked - but it doesn't work correctly. It will work correctly one way, but not the other (the one that works is whichever ClickHandler was defined last). I've tried using validateNotMatches too but no joy.
If I change the code so that the label's text is updated instead of the textbox's then that works fine.
I am aware of suggested workarounds such as using two buttons, but I just want to know if I'm doing something wrong or if this looks like a bug in GAS. Thanks.
function doGet(e)
{
var app = UiApp.createApplication();
var tb = app.createTextBox().setText('true');
var button = app.createButton('button');
var label = app.createLabel().setText('-');
button.addClickHandler(app.createClientHandler()
.validateMatches(tb, 'true')
//.forTargets(label).setText('false')
.forTargets(tb).setText('false')
);
button.addClickHandler(app.createClientHandler()
.validateMatches(tb, 'false')
//.forTargets(label).setText('true')
.forTargets(tb).setText('true')
);
return app.add(app.createHorizontalPanel().add(tb).add(button).add(label));
}
It's not a bug... both events fire. The validation happens on the current state of the widget, not on the state when the event was fired, so after you flip it to "false" the second handler validates and flips it back to "true".

Flex DRAG_DROP Event - Is it possible to access the Image Being Dragged?

When you start a Flex drag action, you pass in a proxy image to be displayed when you drag across the screen. When the drop occurs, I want to be able to grab this proxy but I can't find a way to from the DragEvent object.
Is it possible? What I want is to actually drop the dragged image when the mouse button is released... Flex automatically does a nice shrinking animation on the proxy but I don't want that.
The Flex examples show what I don't want - the proxy is removed and a new image added but not in exactly the right place...
More info: I tried adding my Proxy Image as a data item to the DragSource. I was able to access this when the drop occurred and saw there is a class mx.managers.dragClasses.DragProxy which seems to have all the info I need... but this class is not documented?
So there's two questions really... how to get the proxy and find out the position of the mouse cursor within the proxy, and how to disable the Flex drop animation.
The dragProxy is a static getter on the DragManager and is scoped to mx_internal. So to reference it, you'd have to do something like this:
import mx_internal;
And in a drag event handler:
var p:* = DragManager.mx_internal::dragProxy;
I'm not sure how you could prevent the animation. If I find out, I'll let you know.
For disabling the animation in the s:List, in a dragCompleteHandler override, you can 'hack' into the DragManager to get the dragProxy and hide it.
override protected function dragCompleteHandler(e:DragEvent):void
{
DragManager.mx_internal::dragProxy.visible = false; // <- MAGIC!
super.dragCompleteHandler(e);
}
Probably applicable in other situations.
Only way to prevent the animation:
-You have to monkey patch the DragProxy class (i.e. create a new class with identical name, code, and package structure), and remove the effects code from the mouseUpHandler().
No other way to override it as far as I know, though the issue was been submitted as a bug to Adobe over a year ago.
As far as getting the mouse coords for the proxy to drop it in the correct location try this:
assuming you are initiating the drag on mouseDown get the coords using e.currentTarget.contentMouseX and e.currentTarget.contentMouseY in your handler. then add these to the dragSource ( I did it as an object ) like:
var drgSrc:DragSource = new DragSource();
drgSrc.addData( { x:e.currentTarget.contentMouseX, y:e.currentTarget.contentMouseY }, 'drgXY' );
then in your drop handler ( assuming you are dropping it into a Canvas named drpCvs ):
var newImg:Image = new Image();
newImg.x = drpCvs.contentMouseX - e.dragSource.dataForFormat( 'drgXY' ).x;
newImg.y = drpCvs.contentMouseY - e.dragSource.dataForFormat( 'drgXY' ).y;
I found this while looking for a way to get rid of the shrink animation, so thanks for that. Thought I'd RTF.
If you just want to prevent the animation, the easiest (hackiest) way is this: create you're own proxy and add a MOUSE_UP handler to the stage that when triggered sets the visible property of your proxy to false. It won't actually stop the animation, it will just hide the proxy while the animation is happening. Something like this:
var proxy:UIComponent = new UIComponent();
proxy.graphics.lineStyle(1);
proxy.graphics.beginFill(0xccddff);
proxy.graphics.drawRect(0, 0, main.width, main.height);
stage.addEventListener(MouseEvent.MOUSE_UP, function (e:MouseEvent):void {
proxy.visible = false;
});
#ykessler: Thank you, the monkey patch worked like a charm. SDK: DragProxy.as
#Alvaro: I believe this approach results in a race condition. I tried it, and it only worked sometimes.
Setting
event.dragInitiator.visible = false;
in the drag drop handler works for me!
My solution to turn off the animation, was to set visible=0 onMouseUp in my custom ListItemDragProxy component.
My solution is to remove the MouseUp-Handler on SandboxRoot and attach an own MouseUp-Handler in dragEnterHandler of the target like this:
protected function dragEnterHandler(event:DragEvent):void{
DragManager.acceptDragDrop(this);
this.dragProxy = DragManager.mx_internal::dragProxy;// get drag proxy
var sm:ISystemManager = event.dragInitiator.systemManager.topLevelSystemManager as ISystemManager;
var ed:IEventDispatcher = sm.getSandboxRoot();
this.sandboxRoot = sm.getSandboxRoot();
//remove
ed.removeEventListener(MouseEvent.MOUSE_UP, dragProxy.mouseUpHandler, true);
//attach own
ed.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);
ed.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
this.dragInitiator = event.dragInitiator;}
In mouseUpHandler I've implemented the copy of function mouseUpHandler from original DragProxy.as and removed the Drop-Effect.