Here's my jsFiddle: https://jsfiddle.net/wsounka3/
When I change the font size within the WYSIWYG and then delete all of the written text and begin writing again it retains the last font size instead of starting fresh again.
How can I make the iframe "forget" the last font size?
Code:
function iwrap(elem,iwin,idoc){
var element = idoc.createElement(elem);
var sel = iwin.getSelection();
if(sel.rangeCount){
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(element);
sel.removeAllRanges();
sel.addRange(range);
}
}
$('#smaller').click(function(){
iwrap('small',iwin,idoc);
update_code();
});
$('#larger').click(function(){
iwrap('big',iwin,idoc);
update_code();
});
Side question: I find it strange that by encasing the text in <big> and <small> tags, it decides to translate that into pixels. Can anyone explain why it does this?
Because when you click delete you are deleting the textual content and not the wrapping tag. You can clear the markup when there is no textual content - plus there is a Chrome bug that retains the last element size, so wrapping in a [span] tag prior to removing seams to fix that
Since you call update_code on keyup, simply add a cleanup check there
function update_code(){
var $body = $(idoc).contents().find('body');
if ($.trim($body.text()).length == 0) {
iwrap('span', iwin, idoc); // chrome bug
$body.empty();
}
var icontent = $body.html();
$('div#code').html(icontent);
}
BIG/SMALL to SPAN:size also appears to be an automatic chrome thing
Related
I need to copy the content of a popup into the clipboard as is inside a canvas (it's Openlayer 4 stuff, you add an overlay to the map and then you can use a div to parse it as a content once is created) and is not directly accessible.
to display the popup you need to click on a street restriction.
here the project:
https://www.traffwebdev.uk/parking/test.html
This code works in Chrome, Internet explorer and in Edge but not in Firefox.
Here the code I'm using to copy the content into the clipboard:
const copyEv = () => {
let max = ''
if ($('#numofdivs').length > 0) {
max = $('#numofdivs').val()
}
else {
max = $('#popup-content').children().length
}
for (let i = 0; i < max; i++) {
document.getElementById(`Copy_Btn_${i}`).addEventListener('click', () => {
// We will need a range object and a selection.
let contentHolder = document.getElementById(`info_${i}`)
let range = document.createRange()
let selection = window.getSelection()
// Clear selection from any previous data.
selection.removeAllRanges()
// Make the range select the entire content of the contentHolder paragraph.
range.selectNodeContents(contentHolder)
// Add that range to the selection.
selection.addRange(range)
// Copy the selection to clipboard.
document.execCommand('copy')
// Clear selection if you want to.
selection.removeAllRanges()
})
}
}
I found a different method but neither is working, in the codepen is working and if I modify the text to copy with the content of the popup also is working (you can inspect the popup and copy the whole info_0 in the codepen) but in a real life doesn't work.
https://codepen.io/chriscoyier/pen/OXAwvq
The copyEv function is called after the popup is displayed on the map with a delay of 300ms to make sure the popup is shown
The code is converted with webpack once is on production.
Try this: make the element containing the text editable by adding the contenteditable attribute prior to selecting/copying text. You can remove the attribute just after the copy command is executed.
Firefox is finicky about selecting content from non-content-editable elements in the DOM.
I can not come up with a suitable solution...
<p class="session" contenteditable="true">
Everything contained <b>**within**</b> this div is editable in browsers
that support <code>`HTML5`</code>. Go on, give it a try: click it and
start typing.
</p>
I want to add the appropriate HTML-tags while typing.
Of course it is no problem doing it by simple regex replacements. But I have problems setting the caret at the right place.
Say, in the example above, I want to emphasize the word "try". While typing the right * first and then the left star *, the text is converted to <i>*try*</i> but I want to preserve the position of the caret (set the the caret after the left *). And of cource vice versa, where the right * is set at last.
I find it more difficult to set the part contained <b>**within**</b> this say underlined. _contained <b>**within**</b> this_ becomes <u>_contained <b>**within**</b> this_</u>. So we are not in the same node.
I can think of complicated solutions, but since I am no expert in these text conversions techniques (range, window selection etc.) I wonder if there is a well known pratice of doing it.
Check out the Fiddle
I have tried to get the caret position as a first step and in the second step i have tried to put the caret back to the position .
$('.session').keyup(function(){
//alert("happening");
var sel = window.getSelection();
var offset=sel.anchorOffset;
// you can change the text in div by uncommeting the line below and replace your text with mathcing regex .
//$('.session').text($('.session').text().replace('/(\*.\*)+/','<i>$1<i>'));
setCaret(offset);
$('.session')
});
function setCaret(offset) {
var el = $('.session');
//alert();
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el[0].childNodes[0],offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
el.focus();
}
You need to figure out how to change the text in the div as per your needs. While replacing the text inside the div also maintain the formatting so that the solution works.
I'm using Froala 2 and the documentation doesn't seem to have anything that implies a simple way to set the location of the caret, let alone at the beginning or end. I'm trying to seed the editor instance with a little content in certain cases and when I do using html.set, the caret just stays where it is at the beginning and I want to move it to the end. The internet doesn't seem to have anything helpful around this for v2.
Froala support provided an answer for me that works:
var editor = $('#edit').data('froala.editor');
editor.selection.setAtEnd(editor.$el.get(0));
editor.selection.restore();
As far as I know, Froala 2 doesn't provide any API to do this, but you can use native JavaScript Selection API.
This code should do the job:
// Selects the contenteditable element. You may have to change the selector.
var element = document.querySelector("#froala-editor .fr-element");
// Selects the last and the deepest child of the element.
while (element.lastChild) {
element = element.lastChild;
}
// Gets length of the element's content.
var textLength = element.textContent.length;
var range = document.createRange();
var selection = window.getSelection();
// Sets selection position to the end of the element.
range.setStart(element, textLength);
range.setEnd(element, textLength);
// Removes other selection ranges.
selection.removeAllRanges();
// Adds the range to the selection.
selection.addRange(range);
See also:
How to set caret(cursor) position in contenteditable element (div)?
Set caret position at a specific position in contenteditable div
I am using WYMEditor on my forum and users have the ability to "quote" messages of others. In such cases WYMEditor is loaded with content wrapped in blockquote tag.
Unfortunately usually the contents of the quote take more space than the input box size and when users click on the box end up entering their text inside the blockquote. This results in messy messages.
What I want is to scroll the contents of WYMEditor to the bottom, put cursor in the end and focus on the wym box. Unfortunately there is no such functionality in the WYMEditor api. There are some undocumented functions that provide selection management in the source, but my JavaScript/jQuery skills are not good enough to utilize them - I've tried but failed.
A combination of the postInit option and the jQuery scrollTop function should do the trick. I would also recommend inserting a placeholder paragraph for them along with scrolling to the bottom. For example:
jQuery('.wymeditor').wymeditor({
postInit: function (wym) {
var $contents,
$p,
$blockquote = jQuery(wym._doc).find('blockquote');
// Insert a placeholder empty paragraph
// so that users will be encouraged to not type inside the blockquote
$blockquote.after("<p>");
// Scroll the iframe to the bottom
$contents = $(wym._iframe).contents();
$contents.scrollTop($contents.height());
// Move the selection to the paragraph
$(wym._iframe).focus();
$p = jQuery(wym._doc).find('p');
var sel = rangy.getIframeSelection(wym._iframe),
range = rangy.createRange(wym._doc);
range.setStart($p[0], 0);
range.setEnd($p[0], 0);
range.collapse(true);
sel.setSingleRange(range);
if (jQuery.browser.msie) {
wym.saveCaret();
}
}
});
Well,
I need to replace a word, in a div contentEdible property on, by the same word but formatted...
Like this:
<div> My balls are big </div>
To this (replace the word: balls):
<div> My <font style="color:blue;">balls</font> are big </div>
In a contentEditable this happens dinamically, while the user type the text the replacements happens. I think that a simple event onkeydown, onkeyup, or onkey press, can solve this part.
But, the trouble is with the caret, that after all that i tryed, it stay before the word replaced, when should be stay after. I tryed write some js code, tryed find some jquery scripts, but all them failed in this situation...
Any one has some ideia, or trick ?
I think:
--> Record the length of the word unformatted.
--> Delete this word
--> Put new word formatted.
--> Walk with the caret, to position based this formatted word length.
--> Is it?
PS: I have to considerate a word in any place of this div.
I don't know how to write this code that do what i say above.
Correct me, if i'm wrong.
Since yet, thanks!
Edit[1]: I want that this works on Mozilla Firefox, specificlly;
I only have IE6/7 on this machine, but maybe you can apply the concept to other browser versions of Ranges (or maybe this is cross-browser?).
Basically we store the cursor position, make our search/replacement, then put the cursor back where it was:
html:
<div id="content" contentEditable="true" onkeyup="highlight(this)">This is some area to type.</div>
and the script:
function highlight(elem) {
// store cursor position
var cursorPos=document.selection.createRange().duplicate();
var clickx = cursorPos.getBoundingClientRect().left;
var clicky = cursorPos.getBoundingClientRect().top;
// copy contents of div
var content = elem.innerHTML;
var replaceStart = '<font style="color:blue">';
var replaceEnd = '</font>';
// only replace/move cursor if any matches
// note the spacebands - this prevents duplicates
if(content.match(/ test /)) {
elem.innerHTML = content.replace(/ test /g,' '+replaceStart+'test'+replaceEnd+' ');
// reset cursor and focus
cursorPos = document.body.createTextRange();
cursorPos.moveToPoint(clickx, clicky);
cursorPos.select();
}
}