So, basically, I want to create a richtextbox even if there is no <textarea> yet. I want to append the richtextbox myself. Not by tinyMCE. The problem is I think that after appending this, I wont have any tinyMCE events.
What I have in mind is like...
$("<textarea></textarea>").tinyMCE({options}) and this will return the html string of the richtextbox. That way, I can append the html string myself. Take note, it should work perfectly especially the events.
Is this even possible?
You can create a <textarea> through javascript and append it to the DOM just before you want to render the editor on screen. However you will need to use an id for the textarea.
//an editor id needs to be used in this method
var editorId = "#myId";
var options = {
//options
}
//Creates an editor instance and adds it to the EditorManager collection.
tinyMCE.createEditor(editorId, options);
//get the editor instance by its id
var editor = tinyMCE.get(editorId);
//get the root element you want insert the editor into. (E.g. body element)
var root = document.getElementsByTagName('body')[0];
//create a textarea element
var textarea = document.createElement("textarea");
//set its id
textarea.setAttribute("id", editorId);
//append it to the root element
root.appendChild(textarea);
//register your events
registerEvents(editor);
//display editor on screen
editor.render();
//set content of editor
editor.setContent("<h1>Hello World!</h1><p>Hello World!</p>");
//retrieve content from editor
var htmlContent = editor.getContent();
console.log(htmlContent);
function registerEvents(editor) {
editor.on("init", function(e) {
console.log("Init", e);
});
editor.on("focus", function(e){
console.log("Focus", e);
});
editor.on("blur", function(e){
console.log("Blur", e);
});
}
Here is the example on JSFiddle.
Related
I have appended dynamic iframe on document ready through jquery.
`
$( document ).ready(function() {
$("body").append(renderIframe());
});}
`
Well iframe rendered through this function
function renderIframe(){
return [
'<div id="mydiv">',
'<iframe id="frame" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px;display:none" height="120%" width="120%">',
'</iframe>',
'</div>'
].join("")
}
On Ajax call writing iframe content
`
var iFrame = $('#frame');
iFrame.contents().attr('target','_parent');
var htmlDoc = (new DOMParser()).parseFromString(data, "text/html");
var iFrameDoc = iFrame[0].contentDocument || iFrame[0].contentWindow.document;
iFrameDoc.write( htmlDoc.documentElement.outerHTML);
iFrameDoc.close();`
And trying to handle event like
$('document').on('load','#frame', function(){
console.log("frame loaded")
$(this).contents().find('body').on('click', '#btnClose', function(e){
e.preventDefault(e);
alert("link clicked!" );
});
});
There's several issues here.
iFrame.contents().attr('target','_parent'); will add the target attribute to every element in the DOM. I'm not sure what you're trying to do with that but it's not a good idea.
The iframe is empty at that point anyway, so nothing will happen and the line can be removed.
the renderIframe() logic doesn't really need it's own function; it only ever returns a single string, and contains no business logic.
You don't need to create a DOMParser instance to generate a DOM structure from your HTML string. Just set the innerHTML within the iframe directly using the string you receive from the AJAX request
iframes don't fire a load event, so that code block will never fire. A better idea is to just attach the event handler within the AJAX callback after the content is populated.
If you're expecting the content to be visible in the page you need to remove the display: none setting in the CSS.
On the topic of CSS, do not put it the inline style attribute of the HTML element. Use a external stylesheet.
With all that said, try this:
$("body").append(renderIframe());
function renderIframe() {
return '<div id="mydiv"><iframe id="frame"></iframe></div>';
}
// inside the AJAX callback:
var iFrame = $('#frame');
let data = '<p>Lorem ipsum</p><button id="btnClose">Close</button>'; // AJAX response
var iFrameDoc = iFrame[0].contentDocument || iFrame[0].contentWindow.document;
iFrameDoc.body.innerHTML = data;
$('#frame').contents().find('body').on('click', '#btnClose', function(e) {
e.preventDefault(e);
alert("link clicked!");
});
Note that SO Snippets disallow iframes, so here's a jsFiddle containing a working example.
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.
I'm new to javascript and css and I'm trying to develop a chrome extension which when the user clicks on an element of a specific class in the webpage, it automatically clicks also the next 5 elements.
I found that the css selectors of all the elements of that class are identical up to a number, so I tried the following:
for (i = 1; i <= 5; ++i) {
document.querySelector(
'#selector_first_part... > div:nth-child('+
i +
') > selector_second_part).click();
}
The code above works fine when I manually set i.
The problem is that I need to extract "i" from the clicked-on element, and in order to do that I thought that I need to get the css selector of the clicked-on element.
I tried to inject a script to the source code that adds an eventListener to each element of that class, which sends the ID of the clicked-on element, and using the ID i thought that I could extract the css selector. here is the code:
var actualCode = `
var elements = document.getElementsByClassName('someClass');
var onClickFunction = function() {
var id = this.getAttribute('id');
alert("This object's ID is " + id);
};
for (var i=0; i<elements.length; i++) {
elements[i].addEventListener('click', onClickFunction, false);
}
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
When running this code the alert says "This object's ID is null", meaning that I can't get the css selector using the ID, because it seems that the elements have no ID.
So my question is: how could I click (with JS) the surrounding elements of the clicked-on element?
Thanks!
1st of all, placing your code into a DOM load event like #eytienne already mentioned is used to make sure the page is loaded before attaching your event.
2nd: you should not need to attach several handler, just one click handler on document- then use the target to get the actual element that was clicked, e.g.
const handler = function(e) {
const elem = e.target;
}
document.addEventListener('click', handler, false);
3rd: you don't need an id, just compare all elements, e.g. (in your handler):
const target = e.target;
for (let i=0,elems=document.querySelectorAll(..);i<elems.length;i++) {
if(elems[i] === target) {
... do something ...
}
I did not test the code.. just to give you an idea.
I hope this will help you!
I think you should replace your script manipulation with that:
window.addEventListener('DOMContentLoaded', function(){
// put your actualCode here
});
Look at this ressource in detail (on Mozilla Developper Network, the official documentation):
https://developer.mozilla.org/fr/docs/Web/Events/DOMContentLoaded
I think you did not understand the purpose of an 'id' in the HTML context so discover it (MDN is always a good resource ;) ):
https://www.google.com/search?q=id+mdn
I have tried the following code to replace text character to the img tag inside div message.
However the code is working fine while i do in console. But when I try the same in my sticker.js is not working. Can anyone tell me the reason?
The idea to make sticker box for chat app codded with Javascript and jQuery.
User 1 will send :sticker1: to public room and replaced with img src inside the #div
Now I'm trying document to call the script when div is showing but still not working.
$(document).ready(function() is not working
And $(function() is not working either.
My chat app using template folder /template/*.php and web-cache folder to load the design. I am searching every where to find some solution but no luck.
I need help please
$("#chat-sticker-container").ready(function stickers() {
var emoCodes = [
':sticker1:',
];
var $this = $("body");
emoCodes.forEach(function(code) {
var image = '<img src="https://sevendays.co.in/wp-content/uploads/2019/02/' + code.replace(/:/g, "") + '.jpg">';
$this.find('p.chat-sticker').html(function(index, html) {
return html.replace(new RegExp(code, "g"), image);
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/sticker.js"></script>
<dive id="chat-sticker-container">
<p id="chat-sticker" class="chat-sticker">:sticker1:</p>
</dive>
Make sure your JS is executing AFTER the html is in the DOM, this includes putting your script at the end of your body tag.
Since the script is called before the html is defined its essentially working with nothing, putting the after the html should fix the issues.
By looking at your JSFiddle example I think you need to use the MutationObserver API. This way you can check if an element, or the children of an element have been changed, added or removed.
I'm not able to figure out what the container is where the chat divs are added to the page, so I can only instruct you. But based on your fiddle I'm selecting the chat-main-scroll-chatroom div.
// List of emoCodes
var emoCodes = [
':sticker1:',
];
// Select chat container. Change if necessary.
var chatContainer = document.getElementById('chat-main-scroll-chatroom');
// Create a new observer.
var observer = new MutationObserver(function(entries) {
// Check for emocodes whenever something has changed.
emoCodes.forEach(function(code) {
var image = '<img src="https://sevendays.co.in/wp-content/uploads/2019/02/' + code.replace(/:/g, "") + '.jpg">';
$('p.chat-sticker').html(function(index, html) {
return html.replace(new RegExp(code, "g"), image);
});
});
});
// Check if children are changed
var options = { childList: true }
// Observer the chat container and check if itself or children are changing.
observer.observe(chatContainer, options);
So I really hope that this will help you out. In the best case scenario you would be able to filter the text that has been sent before the message is sent. If the API of your chat app provides such controls, then please use them.
Best of luck!
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');
};
}