so I have a leaflet map with lot of markers placed on it. I want to have a popup with like the status of asset etc on 'hover' over the marker. I see some examples on google and try to implement but none of them is firing any events. here is my code with my attempt. how can i achieve this feature? do i have to use somekind of tooltip instead of popup?
buildMarkerLayer = (rawAssetsObjects) => {
let markersGroup = null;
var self = this;
markersGroup = L.markerClusterGroup({
spiderfyOnMaxZoom: true,
showCoverageOnHover: true,
zoomToBoundsOnClick: true,
spiderfyDistanceMultiplier: 2
});
self.$localForage.getItem('showAllAreas').then((_showAll) => {
if(_showAll){
this.loadAllAreas();
}else{
this.hideAllAreas();
}
});
angular.forEach(rawAssetsObjects, function(_asset) {
if(_asset.latitude && _asset.longitude){
markersGroup.addLayer(L.marker(L.latLng(_asset.latitude,
_asset.longitude), {
id: _asset.id,
icon: L.divIcon({
html: self.siMarkers.createHTMLMarker(_asset)
})
}).on('click', function(e) {
//dismiss the event timeline
self.$mdSidenav('right').close();
self.centerOnClick(_asset);
//set the selected asset to a shared service for availability in
//other controllers
self.siMapRam.setActive(_asset);
//inform detail controller of a newly selected asset to query
self.$rootScope.$broadcast('ActiveAssetChange');
self.dgModal.display();
}).bindPopup('work').on('mouseover',function(ev) {
markersGroup.openPopup();
}));
};
});
return markersGroup
}
so I added the mouseover function and is responding on the console with error, so at least i know the listening part is working
I was close to the answer, while following many examples on google they made L.Marker into a variable like var marker = L.marker. Then call marker.openPopup(). My case, as you can see, I straight called L.marker. Problem was calling L.marker.openPopup() or L.marker(openPopup()) throws error saying openPopup is undefined. so the solution was pretty straight forward and make L.marker into a variable. like below. I also added small popup formatting like where pop-up should display using popAnchor and HTML formatting, for future flowers
angular.forEach(rawAssetsObjects, function (_asset) {
let marker = L.marker(L.latLng(_asset.latitude,
_asset.longitude), {
id: _asset.id,
icon: L.divIcon({
html: self.siMarkers.createHTMLMarker(_asset),
popupAnchor: [0,-80]
})
});
if (_asset.latitude && _asset.longitude) {
let content = "<b>"+_asset.name+"</b>"+"<br>"+"<b>"+'Status: '+"</b>"+_asset.status
markersGroup.addLayer( marker.bindPopup(content)
.on('mouseover', function (e) {
self.siMapRam.setActive(_asset);
self.$rootScope.$broadcast('ActiveAssetChange');
marker.openPopup()
})
.on('click', function (e) {
//dismiss the event timeline
self.$mdSidenav('right').close();
self.centerOnClick(_asset);
//set the selected asset to a shared service for availability in
//other controllers
self.siMapRam.setActive(_asset);
//inform detail controller of a newly selected asset to query
self.$rootScope.$broadcast('ActiveAssetChange');
self.dgModal.display();
}));
};
});
return markersGroup
}
Related
In the official TinyMCE docs is nothing written about the possibility to manually open/close the sidebar:
https://www.tinymce.com/docs/advanced/creating-a-sidebar/#editorsidebarapi
Can anybody help me? I think it must be something like this:
editor.getSidebar('mysidebar').close();
I need it, because I want to close my custom sidebar in my file browser callback.
Use tinymce.activeEditor.execCommand('togglesidebar', false, 'sidebarname'); to toggle the sidebar. You could place event dispacthers and listeners to know if it is currently opened or closed:
tinymce.PluginManager.add('cheminfo', function (editor, url) {
editor.ui.registry.addSidebar('cheminfo', {
tooltip: 'My sidebar',
icon: 'comment',
onShow: function (api) {
var event = new CustomEvent('tinymce-chem-sidebar', {'detail': true});
window.parent.document.dispatchEvent(event);
},
onHide: function (api) {
var event = new CustomEvent('tinymce-chem-sidebar', {'detail': false});
window.parent.document.dispatchEvent(event);
}
});
});
Then (I am using React):
// detect sidebar state open/close
document.addEventListener('tinymce-chem-sidebar', function (e) {
setOpen(e.detail);
});
PS: Make sure the sidebar's name is lowercase or it won't work
adding to #Kristiyan Tsvetanov's solution, an alternative to using event listeners in determining open/close state of sidebar, the following code can be used:
function is_sidebar_open() {
//class names taken from using inspect on the
//sidebar area of the editor in a browser session
if ($(".tox-sidebar__slider").hasClass("tox-sidebar--sliding-closed")) {
return false;
}
else {
return true;
}
}
function open_sidebar(){
if (is_sidebar_open() == false){
tinymce.activeEditor.execCommand('togglesidebar', false, 'sidebarname');
}
}
function close_sidebar(){
if (is_sidebar_open() == true){
tinymce.activeEditor.execCommand('togglesidebar', false, 'sidebarname');
}
}
I'm trying to use Canada Post's Address Complete on my form as such
var fields = [
{ element: "street_address", field: "Line1" },
{ element: "city_address", field: "City", mode: pca.fieldMode.POPULATE },
{ element: "postal_code", field: "PostalCode", mode: pca.fieldMode.POPULATE },
{ element: "country", field: "CountryName", mode: pca.fieldMode.COUNTRY }
],
options = {key: KEY},
control = new pca.Address(fields, options);
addressComplete.listen('load', function(control) {
control.listen("populate", function (address) {
if(address.ProvinceCode == "ON"){
console.log("ONTARIO");
document.getElementById('province').selectedIndex = 2;
}
else if(address.ProvinceCode == "QC"){
document.getElementById('province').selectedIndex = 3;
}
});
});
I'm able to search for an address and have some fields auto populate. The Province on my form is a dropdown which is where I want to use the listener as suggested in the website, but it doesn't work? Could someone please let me know what I'm doing wrong?
I tried playing with the API and I couldn't get any events to fire on the addressComplete object but the ready event. However, since we have all ready constructed a control instance, I just removed the load listener and attached the populate event handler directly to the control object we constructed. This seemed to work.
//addressComplete.listen('load', function (control) {
control.listen('populate', function (address) {
// TODO: Handle populated address here.
});
//});
I got error - Uncaught ReferenceError: control is not defined
Once the Canada Post JavaScript is loaded, then the control instance is created - addressComplete.controls[0]
To listen to populate event of the control:
addressComplete.controls[0].listen("populate", function (address) {
// TODO: Handle populated address here.
});
load() and reload() apis are also available.
addressComplete.controls[0].load();
addressComplete.controls[0].reload();
// destroy();
// load();
I'm working on an interactive map using the New Signature US map plugin. You can see my code here: http://codepen.io/ann_kwilinski/pen/EKdGYW
I'm also going to preface this with I am a beginner with javascript.
I need to add an active state to my state labels and I am really stuck on how to write that. The plugin has the hover state options but not active state.
'labelTextHoverStyles': {
fill: '#000000'
},
If any one can point me in a direction on how to do that it would be much appreciated.
Update
I need help binding the the stateSpecificLabelStyles to the click event I already have:
'click' : function(event, data) {
$('#clicked-state')
.text('Breathe Better Network partners in '+ data.name)
.stop()
.animate({backgroundColor: '#ddd'}, 1000);
// Populate List in Panel
//var stateSelected = data.name;
var stateContent = $('#'+data.name+'-li').html();
// alert(stateContent);
$("#state-list-response").html(stateContent);
//Open Panel List
$(".state-list-overlay").slideDown( "fast", function() {
$(".state-list-panel").slideDown( "fast", function() {
$(".state-list").fadeIn();
});
});
$("#map > svg > path").each(function(i){
$(this).css('fill', '');
});
$('#' + data.name).css('fill', '#26aedf');
},
});
I think you need to use stateSpecificStyles property of JQuery U.S Map:
$('#map').usmap({
stateSpecificStyles: {
'MD': {fill: 'yellow'},
'VA': {fill: 'teal'}
}
});
As 'MD' and 'VA' are your state codes in the MAP.
Update: And yes, you can also bind your own Click event like:
click: function(event, data) {
// Output the abbreviation of the state name to the browser's console. Press f12 in your browser to see this result.
console.log(data.name);
// And when you have the state abbreviation, you can use the above example like this:
stateSpecificStyles: {
data.name: {fill: 'black'}
}
}
I'm having problems to retrieve the argument passed to my eventHandler.
I'm using geous to put a map inside and activeadmin interface. The solution is working on the show page but I didn't get things working on the index page. The idea is to attach the handler to the dragend event on a marker with my model geographic coordinates.
What I do:
map.locations.add($fields.geousable('getLocation'), { draggable: true, on: { dragend: setFieldsLocation }});
and setFieldsLocation is defined below:
function setFieldsLocation (event) {
alert(setFieldsLocation.caller);
console.log(event);
$('.geousable').find("input")[0].value = event.data.lat;
$('.geousable').find("input")[1].value = event.data.lng;
};
So the first line bind the handler (for dragend) and a method inside the geous lib code attachs it and calls it when the event is fired, here is the snippet:
var _onAdd = function (locationMarker, opts) {
// not relevant code
if (options.on) {
for (event in options.on) {
eventHandler = function() {
var handler = options.on[event],
location = locationMarker.location;
return function() {
handler.call(location);
}
}();
google.maps.event.addListener(locationMarker.marker, event, eventHandler);
}
}
};
Debugger shows the location correct location variable when the handler is called, but I can't get the location variable inside my "setFieldsLocation" function. I tried a lot of things. I changed the header of the javascript function, I used event, e, arguments and this kind of things:
console.log("arguments.callee.caller.name = " +
arguments.callee.caller.name);
console.log("arguments.callee.caller.toString() = " +
arguments.callee.caller.toString());
But no luck.
Ideas with an explanation of what is occurring here will be very appreciated.
I am new to javascript, but I've been hired to give maintenance to an application which is developed in Sencha ExtJS 4. One of the modules I've been asked to modify, is of a component in which I show a tooltip whenever I hover over it. This component can be present in more than one view, it is something like "Customer Details" that is present in many screens of the application. If I hover over this data, I need to show a tooltip, this tooltip shows information retrieved by server (REST). I implemented some logic, but this logic involves the use of many listeners in each of the components that will show the information. For instance, I added a listener in all of the views that requires showing the tooltip:
this.listeners = {
boxready: {
fn: this.onAfterRender,
scope: this
}
And I had to implement this method for every view as well, which is a mess and, for sure, a very bad practice:
/**
* This method is executed after panels are rendered in order to set ToolTip listeners on
* users and workgroups.
*
* #param {Object} scope
*/
onAfterRender: function(scope) {
Ext.defer(function() {
var usElements = Ext.get(Ext.query('.usertooltip', scope.el.dom));
usElements.on({
click: function (e) {
var item = Ext.get(e.target);
if (Ext.isEmpty(item.dom.innerHTML.trim())) {
item.removeCls('usertooltip');
return;
}
if (item.hasCls('usertooltip-clicked')) {
return;
}
item.addCls('usertooltip-clicked');
var user = item.getAttribute('data-info');
UserInfo.getUserInfo(user, false);
if (UserInfo.errorResponse) {
UserInfo.getWGroupInfo(user);
}
UserInfo.displayToolTip(this);
}
});
var wgElements = Ext.get(Ext.query('.wgtooltip', scope.el.dom));
wgElements.on({
click : function (e) {
var item = Ext.get(e.target);
if (Ext.isEmpty(item.dom.innerHTML.trim())) {
item.removeCls('wgtooltip');
return;
}
if (item.hasCls('wgtooltip-clicked')) {
return;
}
item.addCls('wgtooltip-clicked');
var wgroup = item.getattribute('data-info');
WGroupInfo.getWGroupInfo(wgroup, false);
if (UserInfo.errorResponse) {
WGroupInfo.getUserInfo(wgroup);
}
WGroupInfo.displayToolTip(this);
}
});
}, 1000, this);
},
What I do is simply detect if the item is selected based a css class, if so, I handle the events and proceed with logic. But I've been doing some research and I think this can be achieved using a "delegator" but I am not sure how to implement this for my scenario.
What I've been thinking of, so far is to create a "js" class which have a method like an "observer" and whenever listen to someone asking for this tooltip functionality, delegate it to the executing object. But since I am new to javascript and this Sencha ExtJS, my tries have been frustrated. If someone can help me I would really appreciate it.
Thanks in advance.
Best regards.
The best way would be to declare a plugin:
Ext.define('TipPlugin', {
alias: 'plugin.tip',
init: function(c) {
c.on('boxready', this.onBoxReady, this);
},
onBoxReady: function(c) {
var els = this.el.select('.usertooltip');
// Do stuff!
}
});
var c = new Ext.Component({
plugins: ['tip']
});