Leaflet.js add button to marker popup - javascript

I am desperately trying to dynamically add buttons into leaflet.js marker popups and assign a callback. However, I seem not to be able to wrap my head around it.
I am using this example https://github.com/calendee/ionic-leafletjs-map-demo and add the following line into line 105 in js/controller/mapController.js
<button class="icon-left ion-information" ng-click="stationInfoButtonClick('+location.name+')"></button>
However, clicking / taping the button does not invoke the specified callback function. Ideas somebody?

You are trying to add HTML to AngularJS Code. This is not possible just like that.
You need to use $compileProvider for that.
On a previous version of leaflet, I managed to do that by calling the $compileProvider on popUp open.
$scope.$on('leafletDirectiveMap.popupopen', function(event, args) {
var feature = args.leafletEvent.popup.options.feature;
var newScope = scope.$new();
newScope.stream = feature;
$compile(args.leafletEvent.popup._contentNode)(newScope);
});
Never done it on ionic indeed, but I'm interested on your return.

Related

amCharts - amMap Home Button Method

I am creating an amMap through amCharts http://docs.amcharts.com/3/javascriptmaps/AmMap and it comes with its own home button which you can click and reverts to the map default.
I would like to do this externally through my own button, but can't quite find the methods that amCharts uses to achieve this.
A few methods I've used are:
chart.zoomTo(), chart.zoomToLongLat(), chart.zoomToXY() using the correct values of when the chart is initialized. This works fine when the chart is not resized ever, but when the chart is resized (not re-initialized), those values become undependable, yet the home button is still able to bring me back to the default zoom.
What method does this home button use? Or I can use to replicate what the home button does?
You need to call zoomToLongLat and pass in your map object's initialZoomLevel, initialZoomLongitude and initialZoomLatitude. From the demo on AmChart's knowledge base for its custom external home button:
function centerMap() {
map.zoomToLongLat(map.initialZoomLevel, map.initialZoomLongitude, map.initialZoomLatitude);
}
You can resize the frame on the codepen demo to see that it resets itself correctly each time.
Yes.. it very simple,
I did it this way:
map.addListener("rendered", function(event) {
var map = event.chart;
map.initialZoomLevel = map.zoomLevel();
map.initialZoomLatitude = map.zoomLatitude();
map.initialZoomLongitude = map.zoomLongitude();
});
function centerMap() {
map.zoomToLongLat(map.initialZoomLevel, map.initialZoomLongitude, map.initialZoomLatitude);
}
<div onclick="centerMap();" class="icon-home"></div>

Proper Way Of Modifying Toolbar After Init in TinyMCE

I am extending a cloud-hosted LMS with javascript. Therefore, we can add javascript to the page, but cannot modify the vendor javascript for different components.
The LMS uses tinyMCE frequently. The goal is to add a new button on to the toolbar of each tinyMCE editor.
The problem is that since the tinyMCE modules are initialized in the vendor's untouchable code, we cannot modify the init() call. Therefore, we cannot add any text on to the "toolbar" property of the init() object.
So I accomplished this in a moderately hacky way:
tinyMCE.on('AddEditor', function(e){
e.editor.on('init', function(){
tinyMCE.ui.Factory.create({
type: 'button',
icon: 'icon'
}).on('click', function(){
// button pressing logic
})
.renderTo($(e.editor.editorContainer).find('.mce-container-body .mce-toolbar:last .mce-btn-group > div')[0])
});
});
So this works, but needless to say I am not totally comfortable having to look for such a specific location in the DOM like that to insert the button. Although this works, I do not believe it was the creator's intention for it to be used like this.
Is there a proper way to add the button to a toolbar, after initialization, if we cannot modify the initialization code?
I found a more elegant solution, but it still feels a bit like a hack. Here is what I got:
// get an instance of the editor
var editor=tinymce.activeEditor; //or tinymce.editors[0], or loop, whatever
//add a button to the editor buttons
editor.addButton('mysecondbutton', {
text: 'My second button',
icon: false,
onclick: function () {
editor.insertContent(' <b>It\'s my second button!</b> ');
}
});
//the button now becomes
var button=editor.buttons['mysecondbutton'];
//find the buttongroup in the toolbar found in the panel of the theme
var bg=editor.theme.panel.find('toolbar buttongroup')[0];
//without this, the buttons look weird after that
bg._lastRepaintRect=bg._layoutRect;
//append the button to the group
bg.append(button);
I feel like there should be something better than this, but I didn't find it.
Other notes:
the ugly _lastRepaintRect is needed because of the repaint
method, which makes the buttons look ugly regardless if you add new
controls or not
looked in the code, there is no way of adding new controls to the
toolbar without repainting and there is no way to get around it
without the ugly hack
append(b) is equivalent to add(b).renderNew()
you can use the following code to add the button without the hack, but you are shortcircuiting a lot of other stuff:
Code:
bg.add(button);
var buttonElement=bg.items().filter(function(i) { return i.settings.text==button.text; })[0];
var bgElement=bg.getEl('body');
buttonElement.renderTo(bgElement);

get the style of the marker I clicked on in mapbox

I'm trying to get the style of the icon which I clicked on, in order to get its translate values.
I'm doing this because I want to create a div that will have the same location on the map as the icon who got clicked on.
this is my website so far:
http://www.david-halfon.com/radio/index.html
Basically, each time someone presses the yellow circle, a div should appear around it.
this is the code for events that happen when an icon is being clicked:
locale.on('click', function(e) {
$("#music").attr("src", prop.Url);
$(".player").show();
play();
sendWithAjax(prop.Country, prop.City);
$("h1").html(prop.Station);
$("h2").html(prop.Country);
$("h3").html(prop.City);
//console.log($(this).css("transform"));
//console.log($(this).attr("style"));
console.log($(this));
setTimeout(function(){ $("h4").html(globalVar);}, 500);
$(".plusB").show();
$(".shareB").show();
map1.setView(locale.getLatLng(), 4);
playNow = prop.Station;
playNowCountry = prop.Country
playNowCity = prop.City;
});
The comments are what I have tried to do so far but it does'nt seems to work.
When I'm trying to consloe.log(this) I get 'undefined'.
Thank you!!
The reason why you don't get the expected $(this).css(...) informations is that this is not a regular DOM object, as it clearly appears using Firebug:
The <img> you want to get style from is contained in the _icon member of this object, so you can use e.g.:
console.log($(this._icon).css('transform'));
console.log($(this._icon).attr('style'));
// and so on
This way (tested using Firebug on your website), it works fine.
BTW, I couldn't figure out why the click event targets this object rather than the <img>...
BTW again, this website is a great idea: cool!

TinyMCE opened in jqueryUI modal dialog

When using tinyMCE in a jqueryUI modal dialog, I can't use the hyperlink or 'insert image' features.
Basically, after lots of searching, I've found this:
http://www.tinymce.com/develop/bugtracker_view.php?id=5917
The weird thing is that to me it seams less of a tinyMCE issue and more of a jqueryUI issue since the problem is not present when jqueryUI's modal property is set to false.
With a richer form I saw that what happens is that whenever the tinyMCE loses focus, the first element in the form gets focus even if it's not the one focused / clicked.
Does some JavaScript guru have any idea how I might be able to keep the dialog modal and make tinyMCE work?
This fixed it for me when overriding _allowInteraction would not:
$(document).on('focusin', function(e) {
if ($(event.target).closest(".mce-window").length) {
e.stopImmediatePropagation();
}
});
I can't really take credit for it. I got it from this thread on the TinyMCE forums.
(They have moved their bugtracker to github. tinymce/issues/703 is the corresponding github issue.)
It seems there are no propper solution for this issue yet. This is kind of a hack but it really worked for me.
Every time you open the Dialog remove the text area and re add it like following,
var myDialog = $('#myDialog');
var myTextarea = myDialog.find('textarea');
var clonedTextArea = myTextarea.clone(); // create a copy before deleting from the DOM
var myTextAreaParent = myTextarea.parent(); // get the parent to add the created copy later
myTextarea.remove(); // remove the textarea
myDialog.find('.mce-container').remove(); // remove existing mce control if exists
myTextAreaParent.append(clonedTextArea); // re-add the copy
myDialog.dialog({
open: function(e1,e2){
setTimeout(function () {
// Add your tinymce creation code here
},50);
}
});
myDialog.dialog('open');
This seems to fix it for me, or at least work around it (put it somewhere in your $(document).ready()):
$.widget('ui.dialog', $.ui.dialog, {
_allowInteraction: function(event) {
return ($('.mce-panel:visible').length > 0);
}
});

Customize OpenLayers Control

How can I easily customize OpenLayers map controls? Or at least, how can I minimize the controls' height?
Thank you.
PS. Is there any CSS override?
You can sub-class any of the openLayers controls. I just made a 'zoom-slider' by sub-classing PanZoomBar (panZoomBar.js), overriding the draw() method and commenting out all the button elements, just leaving the zoom slider.. like this:
function zoomSlider(options) {
this.control = new OpenLayers.Control.PanZoomBar(options);
OpenLayers.Util.extend(this.control,{
draw: function(px) {
// initialize our internal div
OpenLayers.Control.prototype.draw.apply(this, arguments);
px = this.position.clone();
// place the controls
this.buttons = [];
var sz = new OpenLayers.Size(18,18);
var centered = new OpenLayers.Pixel(px.x+sz.w/2, px.y);
this._addButton("zoomin", "zoom-plus-mini.png", centered.add(0, 5), sz);
centered = this._addZoomBar(centered.add(0, sz.h + 5));
this._addButton("zoomout", "zoom-minus-mini.png", centered, sz);
return this.div;
}
});
return this.control;
}
var panel = new OpenLayers.Control.Panel();
panel.addControls([
new zoomSlider({zoomStopHeight:11}),
new OpenLayers.Control.LayerSwitcher({'ascending':false}),
]);
map.addControl(panel);
There is a CSS file that comes with can controls all of the CSS commands for within openlayers generally .olZoombar { here}
It is probably the easiest way to edit those sorts of things otherwise you can edit the actual .js file for the control.
If you are talking about the PanZoomBar or ZoomBar, as has been mentioned, you need to edit the zoomStopHeight. However, You do not need to edit OpenLayers.js.
new OpenLayers.Control.PanZoomBar({zoomStopHeight: 7})
You could consider trying PanZoom, which has no bar.
To minimize the ZoomBar search for zoomStopHeight in OpenLayers.js and edit it as you wish.
Further reference: Link.
Take a look here - http://geojavaflex.blogspot.com/
I am in the process of showing how to do an involved customization of the LayerSwitcher. This might give you ideas on how to do what you are after.
There is a map on the page that shows how the control works, and subsequent posts will discuss the code in detail.
If you are just interested in code see the source of the page and look for the link to CustomLayerSwitcher.js for the customized version of the switcher.

Categories