Events not firing inside mapboxgl popup - javascript

I'm attempting to do something custom with clusters, where when you click down on a cluster that cannot be expanded further (eg. two objects with the same or very similar location data), a list of what is contained in that cluster should appear, which you can then interact with. I am able to retrieve the objects, create the list and place it on the correct spot on the map, but I am unable to bind any events to those list entries. I have created similar functionality in other parts of the map application, and these seem to be working as expected. Those were not created using the Popup library, so I could try reusing that technique, but the ease of placing popups makes me want to at least try to get those working with events.
I've tried using addEventListener with the click, mouseup and mouseenter events, but nothing is triggering.
How can I use eventListeners in mapbox popups? Is the HTML passed to the popup being sanitized somehow?
I am currently using mapboxgl 1.2.0.
How the popup is generated:
new mapboxgl.Popup({offset:25}).setHTML(generateListPopup(myEntries).outerHTML)
.setLngLat(coords[0])
.addTo($scope.map);
How the content is generated:
function generateListPopup(entries){
var container = document.createElement('div');
container.maxHeight = "240px";
container.overflowY = "auto";
var ul = document.createElement('ul');
ul.style.listStyle = "none";
ul.style.padding = "0";
container.style.background = "blue"; // does set the color to blue
container.addEventListener('mouseenter', function () { // does not trigger
console.log("by golly"); // does not show
});
angular.forEach(entries, function (e) {
var li = document.createElement('li');
var entry = document.createElement('p');
var f = document.createElement('button');
entry.innerHTML = e.name;
entry.style.cursor = "pointer";
f.addEventListener('mouseup', function () {
console.log("hello"); // nope
});
li.appendChild(f);
li.appendChild(entry);
ul.appendChild(li);
});
container.appendChild(ul);
return container;
}
Any help is greatly appreciated!

I just typed out this whole question before figuring it out, so might as well post it in case anyone ever has the same issue:
use setDOMContent on the returned container instead of setHTML on the returned container's outerHTML. I'm guessing the bound events are lost when the elements are serialized using outerHTML.

Related

How to add a custom button to video js player

I want to make a button which is a link to another page to the video js video player which I am using but nothing seems like working. After adding the button it got added to the control panel of the player but the button is not visible to the user. Also, I want to add a link to that button once it got pressed it should open a new page. I couldn't find good documentation of the same the code which I am trying is posted here.
var player = videojs('my-video');
var button = player.addChild('button');
var myButton = player.controlBar.addChild('button', {
text: "Press me",
// other options
});
How to extent this fuction such as onclick events like that. I guess there will be some methods which i can define inside player.controlBar.addChild('button' This itself
Text you pass in your option is available as a controlText and not a display text. ControlText creates a span in you button which is displayed when hovered. This control text is present in all the components in video js.
To add a text in videojs here is a simple way.
var player = videojs('my_video_1');
// When you pass text in options it just creates a control text,
// which is displayed as tooltip when hovered on
// this button viz the span in you div,
var myButton = player.controlBar.addChild("button");
// There are many functions available for button component
// like below mentioned in this docs
// https://docs.videojs.com/button.
// You can set attributes and clasess as well.
// Getting html DOM
var myButtonDom = myButton.el();
// Since now you have the html dom element
// you can add click events
// Now I am setting the text as you needed.
myButtonDom.innerHTML = "Hello";
myButtonDom.onclick = function(){
alert("Redirecting");
window.location.href = "https://www.google.com"
}
Instead of setting an inner html you can play around and add any html DOM attribute since at the end it is only a button.
Adding Codepen link for code demonstration
https://codepen.io/vaibhav281128/pen/NWawWjr
In case if you want to register your button as a custom component
https://codepen.io/vaibhav281128/pen/bGoYGPR
My solution in case you also want to control the position of your button:
addButtonToPlayer() {
let myButton = player.controlBar.addChild('button');
myButton.controlText('tooltip text');
player.controlBar
.el()
.insertBefore(
myButton.el(),
player.controlBar.getChild('fullscreenToggle').el()
);
let buttonDom = myButton.el();
buttonDom.innerHTML = '⬇'; // button text/emoji
buttonDom.onclick = function() {
alert('Hey');
};
}

Iframe nomenucontext - Modify img tag after creation

Hi I am adding a iframe dynamically, It displays an image from a server. I need to disable the context menu for this item. In chrome I can inspect element and if I add oncontextmenu="return false" I do get the wanted affect. However I am unable to do this while the page is generated. Here is an example of the working html.
However I can not reproduce this when i frame is being created. Here is my code.
$(window).scrollTop(0);
$('#secVerify').show();
$("#popWaitLoad").modal("hide");
imgLoading.hide();
dvIframe.empty();
//else load deposit data into interface
$("#spanType").text(deposit.DepositType);
$("#spanReference").text(deposit.Reference);
$("#spanAmount").text("R " + deposit.Amount.toFixed(2));
$("#spanDate").text(deposit.DateCreatedOffsetS);
imageID = deposit.Deposit_Doc_imageID;
var url = imageUrl + '/' + deposit.Deposit_Doc_imageID + '/false';
var imgFrame = document.createElement("iframe");
imgFrame.src = url;
imgFrame.frameBorder = '0';
imgFrame.scrolling = 'no';
imgFrame.width = '100%';
imgFrame.height = '100%';
imgFrame.align = 'middle';
imgFrame.id = "iframeImg";
dvIframe.append(imgFrame);
I have tried examples like.
$("#iframeImage").contents().find("img").attr("oncontextmenu", 'return false');
$('#iframeImage img').on('contextmenu', function (e) {
e.stopPropagation();
// Your code.
return false;
});
But because the img element seems to be only created is done after page load it seems to not work. I know disabling the the menu will not help much and I have explained all the other methods of obtaining the image that is still available but the client really wants this.
I have added nocontextmenu to the body tag and it works everywhere except for the iframe.
So let me clarify, My iframe is working like it should however I would like to disable the right click aka context menu on the specific iframe.
I have used setAttribute to set the attributes and targeted a container to appendChild.
function example(){
var target = document.getElementById('container');
var element = document.createElement('img');
element.setAttribute('src', 'http://gopalshenoy.files.wordpress.com/2011/04/product_demos.jpg');
//element.setAttribute('width','100%');
//element.setAttribute('height','100%');
element.setAttribute('id','iframeImage');
element.setAttribute("oncontextmenu","return false;");
target.appendChild(element);
}
// Demo-Snippet use.
window.onload=example;
<!-- Demo Snippet use -->
<div id="container"></div>
If you build more than one element using this function you might find further issues due to duplicated ID's.
ID's are used to target a specific element 'one of' so if you want to build multiple elements I would recommend giving them unique ID's.
I hope this helps. Happy coding!

set focus on newly created div in javascript

So I am creating a new div using javascript and then I am trying to set the focus on the new div but it just isn't working. I have looked at this post Difficulty setting focus on newly created object in javascript but I still can't get it to work Here is my function:
function overlayDIV(clickedId) {
// see if div already exists if not create it
if (!document.getElementById("overlay" + clickedId)) {
var div = document.createElement("div");
div.id = "overlay" + clickedId;
div.style.width = "12px";
div.style.height = "12px";
div.style.background = "red";
div.style.position="absolute";
div.style.zIndex = "1";
//added this line after reading the other post,
div.setAttribute('tabindex', '0');
document.getElementById(clickedId).appendChild(div);
}
document.getElementById("overlay" + clickedId).focus();
}
I have no idea what Im doing wrong if anyone can help that would be awesome thanks.
EDIT:
So I made a JSfiddle of it: http://jsfiddle.net/m7cQA/ Now what I want to be able to do is let the user click on the div and have a new div be created (this is happening already) and the user should be able to just start typing in the newly created div (this is the part that isn't working) when you start typing the text goes in the parent div behind the new div. You have to re-click on the divs to get the cursor to move to the new div in order to start typing in it.

function for dynamically created <a> tag is not working

i am working on a mobile website with html,js and css.i have created tag through HTML5 DOM & assigned functions to it. It's not working.
My html code(which i have tried thro' DOM method);
<script>
var addExhibits = document.getElementById('mycontent');
function mytest()
{
var div = document.createElement('div');
div.id = 'rateMe';
var anchor = document.createElement('a');
anchor.id="_1";
anchor.onclick = rateIt(this);
anchor.onmouseover=rating(this);
anchor.onmouseout=off(this);
div.appendChild(anchor);
addExhibits.appendChild(div);
}
</script>
<body><div id='mycontent' title="Rate Me..."></body>
Code(statically created tag - works fine)
<div id="rateMe" title="Rate Me...">
<a onclick="rateIt(this)" id="_1" onmouseover="rating(this)" onmouseout="off(this)"></a>
</div>
rate(this) is a function in external JS(http://reignwaterdesigns.com/ad/tidbits/rateme/)
Your event handler just assign the result of the respective function calls here:
anchor.onclick = rateIt(this);
anchor.onmouseover=rating(this);
anchor.onmouseout=off(this);
I assume you want them to execute in case of the event instead:
var that = this;
anchor.onclick = function(){ rateIt(that); };
anchor.onmouseover = function(){ rating(that); };
anchor.onmouseout= function(){ off(that); };
You don't call your mytest() function anywhere. That's the first thing I see. The other thing is that you are putting your script above your div (mycontent) so the div has not yet been created when your script is read. But I don't completely understand what your aim is here or what exactly your problem is.
You don't need to pass this.
you can access your element inside the function in many ways.
var addExhibits=document.getElementById('mycontent'),
rateIt=function(e){
e=e||window.event;
var target=e.target||e.srcElement;//polyfill for older browser
console.log(this,target);
},
rating=function(e){
console.log(this,e.target);
},
off=function(e){
console.log(this,e.target);
},
mytest=function(){
var div=document.createElement('div'),
a=document.createElement('a');
div.id='rateMe';
a.id="_1"; // id's shouldn't contain _ - & numbers(1st letter) even if it works.
a.onclick=rateIt;
a.onmouseover=rating;
a.onmouseout=off;
div.appendChild(a);
addExhibits.appendChild(div);
};
this way you also don't create memory leaks.
ps.: that external js example you using is written very bad.
to make your example work you need to change the strange me/num/sel variables in the external js with the proper one (this/e.target/e.srcElement).

Z-Index on Absolute Positioned Element Shows Above Higher Z-Index Elements

I am trying to create some javascript that when an object is added to the window, a listener listens for any click on the body except for the placed object and removes the object if anywhere on the window except the actual object itself is clicked.
Through numerous unsuccessful attempts, the idea I came up with is to dynamically add an overlay div to the screen called overlay2 (or whatever, it doesnt matter) and then listen for clicks on that div. When I add the overlay to the window and set the zIndex to a higher number than the top element already placed (say 5000) and then set the zIndex of the only object to be placed above the overlay to an even higher number (say 6000), the overlay still appears on top of everything and I cannot select any of the objects in the div I meant to place above it.
var overlayDiv = document.createElement('div');
overlayDiv.setAttribute('id', 'overlay2');
overlayDiv.style.zIndex = '5000';
overlayDiv.style.width = '100%';
overlayDiv.style.height = '100%';
overlayDiv.style.left = '0';
overlayDiv.style.top = '0';
overlayDiv.style.position = 'absolute';
document.body.appendChild(overlayDiv);
$(container).append(template);
template.style.zIndex = '6000';
//Listeners
//Page click listener. Closes the tool when the page is clicked anywhere but inside the parent.
var initialClick = false;
$('body').on('click.editObjectListeners', function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
console.log(target.id);
if(target.id == 'overlay2' && target.id != '') {
$(overlayDiv).remove();
finish();
};
}
initialClick = true;
});
I've determined that this has everything to do with the absolute positioning of the overlayDiv. While testing, if I used absolute positioning to place the template and if I append the template object directly to the body like I did the overlayDiv, the zIndex works above the overlayDiv as I originally anticipated. Unfortunately absolutely positioning this element doesn't make much sense for me beyond testing purposes. Is there a way to get around this?
Turns out that z-index can really only be used successfully with absolute placed elements. Therefore the original plan to solve the body click listener will not work. Instead, I decided to use jQuery and listener objects to listen for the click instead. Its a much cleaner solution, I just had to wrap my head around it. You can view my other solution here.
I don't know how much this will help your particular problem, but I just happened to notice that you may have a problem with your use of jQuery's "on()" method.
First off, you are using jQuery version 1.7+ with that, correct?
Unlike "live", I believe that the on() parameters are event, selector, function.
So where you have this:
$('body').on('click.editObjectListeners', function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
console.log(target.id);
if(target.id == 'overlay2' && target.id != '') {
$(overlayDiv).remove();
finish();
};
}
initialClick = true;
});
I think you want this:
$('body').on('click.editObjectListeners', [SOME SELECTOR], function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
console.log(target.id);
if(target.id == 'overlay2' && target.id != '') {
$(overlayDiv).remove();
finish();
};
}
initialClick = true;
});
Hope that helps in some small way.
Good luck!
Try setting the zIndex before appending it to container.
template.style.zIndex = '6000';
$(container).append(template);

Categories

Resources