Select text inside editable field in CKEditor widget [duplicate] - javascript

I have made a plugin for CKEditor, but it relies on the currently selected text.
In FF and Chrome I can use:
var selectedText = editor.getSelection().getNative();
but this doesn't work in IE and I only get [object Object]
Any suggestions?

This is what I use:
var mySelection = editor.getSelection();
if (CKEDITOR.env.ie) {
mySelection.unlock(true);
selectedText = mySelection.getNative().createRange().text;
} else {
selectedText = mySelection.getNative();
}

Use:
editor.getSelection().getSelectedText();
Or:
CKEDITOR.instances["txtTexto"].getSelection().getSelectedText()
"txtTexto" = ID of textarea tag

To those who want to prefill fields with a selection, just do it like that and safe yourself a long journey.
onShow: function() {
this.setValueOf( 'tab-id', 'field-id', editor.getSelection().getSelectedText().toString() );
},
Have a nice day!

In the newer versions of CKEDITOR, there seems to be a way easier method:
var selectedHTML = editor
.getSelectedHtml()
.getHtml(); //result: <p>test</p>

#TheApprentice
You put it like this:
( function(){
var getSelectedText = function(editor) {
var selectedText = '';
var selection = editor.getSelection();
if (selection.getType() == CKEDITOR.SELECTION_TEXT) {
if (CKEDITOR.env.ie) {
selection.unlock(true);
selectedText = selection.getNative().createRange().text;
} else {
selectedText = selection.getNative();
}
}
return(selectedText);
}
...
with a call like this:
onShow: function() {
// Get the element currently selected by the user
var editor = this.getParentEditor();
var selectedContent = getSelectedText(editor);

Related

How to mark as selected the default text of multiple textarea on tabindex?

I have few textarea on which I want to get the default text selected when I tabbing upon it.
For a single textarea I've found a script which I adapted to my situation but is not an elegant solution.
How can I shorten it.
<script type="text/javascript">
var textBox1 = document.getElementById("textarea_1");
var textBox2 = document.getElementById("textarea_2");
var textBox3 = document.getElementById("textarea_3");
textBox1.onfocus = function() {
textBox1.select();
// Work around Chrome's little problem
textBox1.onmouseup = function() {
// Prevent further mouseup intervention
textBox1.onmouseup = null;
return false;
};
};
textBox2.onfocus = function() {
textBox2.select();
textBox2.onmouseup = function() {
textBox2.onmouseup = null;
return false;
};
};
textBox3.onfocus = function() {
textBox3.select();
textBox3.onmouseup = function() {
textBox3.onmouseup = null;
return false;
};
};
</script>
You can add a dedicated class name and refactor the code to be more generic using class name as selector an make it work for multiple textareas like this:
// Add the class 'auto-selectable' to the desired <texarea/> elements
var textBoxes = document.getElementByClassName('auto-selectable');
for(var i = 0; i < textBoxes.length; i++) {
var textBox = textBoxes[i];
textBox.select();
// Work around Chrome's little problem
textBox.onmouseup = function() {
// Prevent further mouseup intervention
textBox.onmouseup = null;
return false;
};
}
a small correction to Plamen's answer: Elements not Element
var textBoxes = document.getElementsByClassName('auto-selectable');
instead of:
var textBoxes = document.getElementByClassName('auto-selectable');

Adding javascript causing divs not getting displayed on website

I have a select field ('5f01264e722ae') with which I would like to change the color of a text print ('.sw_poster_text2'). With a little help from another member, I uploaded the script below. However, as soon as I undo the // from the .change function my website no longer displays the print, image on which to print, and then select options. Any idea how to fix this? Here is a link of the working page: https://www.horseglamour.com/product/pagony-concours-zadeldek/
Thank you for your help.
<script>
jQuery(document).ready(function() {
var fieldId = "5f0124e773aa8"; // Change this
var defaultText = "my name"; // Change this
if (!jQuery('input[data-field-id="' + fieldId + '"]').length)
return;
var $el = jQuery('<div class="sw_poster_text2">').html(defaultText);
$el.appendTo(jQuery('.woocommerce-product-gallery--with-images'));
jQuery(document).on('change keyup', 'input[data-field-id="' + fieldId + '"]', function() {
var v = jQuery(this).val() || defaultText;
jQuery('.sw_poster_text2').html(v);
}).trigger('change');
//$("select[data-field-id='5f01264e722ae']").change(function() {
//var color = $(this).find('option:selected').data('wapf-label')
//$(".sw_poster_text2").css("color", color);
//});
});
</script>
You can alter commented out part of your script to following:
jQuery("select[data-field-id='5f01264e722ae']").change(function() {
var color = jQuery(this).find('option:selected').data('wapf-label')
jQuery(".sw_poster_text2").css("color", color);
});
or if you perfer $ to access jQuery you can reference to it in callback https://api.jquery.com/jquery.noconflict/
jQuery(document).ready(function($) {
var fieldId = "5f0124e773aa8"; // Change this
var defaultText = "my name"; // Change this
if(!jQuery('input[data-field-id="'+fieldId+'"]').length)
return;
var $el = jQuery('<div class="sw_poster_text2">').html(defaultText);
$el.appendTo(jQuery('.woocommerce-product-gallery--with-images'));
jQuery(document).on('change keyup','input[data-field-id="'+fieldId+'"]',function(){
var v = jQuery(this).val() || defaultText;
jQuery('.sw_poster_text2').html(v);
}).trigger('change');
$("select[data-field-id='5f01264e722ae']").change(function() {
var color = $(this).find('option:selected').data('wapf-label')
$(".sw_poster_text2").css("color", color);
});
});

How to get the text of a textarea with a prototype click event?

There are several textareas on my page and I need the text of the one someone is clicking on. I would know how to do it in jQuery but I need a prototype/javascript solution. What I tried so far:
$$("textarea").each(function (el) {
el.observe('click', respondToClick);
function respondToClick(event) {
var element = Event.element(event);
var text = element.innerHTML();
console.log(text);
}
});
There are no errors in the console but also not the text I need. So how to get it?
EDIT:
That's the solution. I forgot the document.ready-equivalent in prototype and thanks to bruchowski I could edit the correct prototype method to get the text:
document.observe("dom:loaded", function () {
$$("textarea").each(function (el) {
el.observe('click', respondToClick);
function respondToClick(event) {
var element = Event.element(event);
var text = element.value;
console.log(text);
}
});
});
P.S.: Prototype Vesion is 1.7.0
You can use Form.Element.getValue(), or its $F() alias:
var element = Event.element(event);
var text = $F(element);
console.log(text);

Toggling two events on one button

I'm trying to add some functionality to be able to edit comments inline. So far it's pretty close, but I'm experiencing issues trying to trigger a second event. It works the first time, but after that, fails.
$(function() {
var $editBtn = $('.js-edit-comment-btn');
var clicked = false;
$editBtn.on('click', $editBtn, function() {
clicked = true;
var $that = $(this);
var $form = $that.closest('.js-edit-comment');
var $commentTextBody = $that.closest('div').find('.js-comment-body');
var commentText = $commentTextBody.text();
var $editableText = $('<textarea />');
if ($that.text() === 'Save Edits') {
$that.text('Saving...').attr('disabled', true);
} else {
$that.text('Save Edits').attr('alt', 'Save your edits');
}
// Replace div with textarea, and populate it with the comment text
var makeDivTextarea = function($editableText, commentText, $commentTextBody) {
$editableText.val(commentText);
$commentTextBody.replaceWith($editableText);
$editableText.addClass('gray_textarea js-edited-comment').width('100%').css('padding', '4px').focus();
};
makeDivTextarea($editableText, commentText, $commentTextBody);
var saveEdits = function($that, $editableText) {
$that.on('click', $that, function() {
if (clicked) {
var comment = $that.closest('div').find('.js-edited-comment').val();
$editableText.wrap('<div class="js-comment-body" />').replaceWith(comment);
$that.text('Edit').attr('alt', 'Edit Your Comment').attr('disabled', false);
$('#output').append('saved');
clicked = false;
return false;
}
});
};
saveEdits($that, $editableText);
return false;
});
});​
jsfiddle demo here
Hiya demo for your working solution: http://jsfiddle.net/8P6uz/
clicked=true was the issue :)) I have rectified another small thing. i.e. $('#output') is set to empty before appending another saved hence text **saved** will only appear once.
small note: If I may suggest use Id of the button or if there are many edit buttons try using this which you already i reckon; I will see if I can write this more cleaner but that will be sometime latter-ish but this should fix your issue. :) enjoy!
Jquery Code
$(function() {
var $editBtn = $('.js-edit-comment-btn');
var clicked = false;
$editBtn.on('click', $editBtn, function() {
clicked = true;
var $that = $(this);
var $form = $that.closest('.js-edit-comment');
var $commentTextBody = $that.closest('div').find('.js-comment-body');
var commentText = $commentTextBody.text();
var $editableText = $('<textarea />');
if ($that.text() === 'Save Edits') {
$that.text('Saving...').attr('disabled', true);
} else {
$that.text('Save Edits').attr('alt', 'Save your edits');
}
// Replace div with textarea, and populate it with the comment text
var makeDivTextarea = function($editableText, commentText, $commentTextBody) {
$editableText.val(commentText);
$commentTextBody.replaceWith($editableText);
$editableText.addClass('gray_textarea js-edited-comment').width('100%').css('padding', '4px').focus();
};
makeDivTextarea($editableText, commentText, $commentTextBody);
var saveEdits = function($that, $editableText) {
$that.on('click', $that, function() {
if (clicked) {
var comment = $that.closest('div').find('.js-edited-comment').val();
$editableText.wrap('<div class="js-comment-body" />').replaceWith(comment);
$that.text('Edit').attr('alt', 'Edit Your Comment').attr('disabled', false);
$('#output').text("");
$('#output').append('saved');
clicked = true;
return false;
}
});
};
saveEdits($that, $editableText);
return false;
});
});​

Why document.execCommand('paste') is not working in my extension

I am creating a Google chrome extension which can read the contents of clipboard.
But I am unable to get the documentation for this. I want to get the clipboard content as in IE's clipboard API.
In the manifest file i gave permissions to
clipboardRead and clipboardWrite.
I have created a function in Background page as below
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == "getClipData")
sendResponse({data: document.execCommand('paste')});
else
sendResponse({}); // snub them.
});
And in Content Script I am calling the function like this
chrome.extension.sendRequest({method: "getClipData"}, function(response) {
alert(response.data);
});
But this returns me undefined...
document.execCommand('paste') returns success or failure, not the contents of the clipboard.
The command triggers a paste action into the focused element in the background page. You have to create a TEXTAREA or DIV contentEditable=true in the background page and focus it to receive the paste content.
You can see an example of how to make this work in my BBCodePaste extension:
https://github.com/jeske/BBCodePaste
Here is one example of how to read the clipboard text in the background page:
bg = chrome.extension.getBackgroundPage(); // get the background page
bg.document.body.innerHTML= ""; // clear the background page
// add a DIV, contentEditable=true, to accept the paste action
var helperdiv = bg.document.createElement("div");
document.body.appendChild(helperdiv);
helperdiv.contentEditable = true;
// focus the helper div's content
var range = document.createRange();
range.selectNode(helperdiv);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
helperdiv.focus();
// trigger the paste action
bg.document.execCommand("Paste");
// read the clipboard contents from the helperdiv
var clipboardContents = helperdiv.innerHTML;
If you want plain-text instead of HTML, you can either use helperdiv.innerText, or you can switch to using a textarea. If you want to parse the HTML in some way, you can walk the HTML dom inside the DIV (again, see my BBCodePaste extension)
var str = document.execCommand('paste');
You will need to add the clipboardRead permission too.
We cant access clipboard from javascript instead IE for chrome and other browsers.
The hack for this is very simple: create own custom clipboard which store text on cut and from where we paste it directly
function copy(){
if (!window.x) {
x = {};
}
x.Selector = {};
x.Selector.getSelected = function() {
var t = '';
if (window.getSelection) {
t = window.getSelection();
} else if (document.getSelection) {
t = document.getSelection();
} else if (document.selection) {
t = document.selection.createRange().text;
}
return t;
}
var mytext = x.Selector.getSelected();
document.getElementById("book").innerHTML =mytext;
}
function cut(){
if (!window.x) {
x = {};
}
x.Selector = {};
x.Selector.getSelected = function() {
var t = '';
if (window.getSelection) {
t = window.getSelection();
} else if (document.getSelection) {
t = document.getSelection();
} else if (document.selection) {
t = document.selection.createRange().text;
}
return t;
}
var mytext = x.Selector.getSelected();
document.getElementById("book").innerHTML =mytext;
x.Selector.setSelected()="";
}
function paste()
{
var firstDivContent = document.getElementById('book');
var secondDivContent = document.getElementById('rte');
secondDivContent.innerHTML += firstDivContent.innerHTML;
rte.focus();
}
function clear()
{
document.getElementById('rte').innerHTML="";
rte.focus();
}
<button id="cut"onclick="cut();">Cut</button>
<button id="copy"onclick="copy();">Copy</button>
<button id="paste"onclick="paste();">Paste</button>
Working Div
<div id="rte" contenteditable="true" style="overflow:auto;padding:10px;height:80vh;border:2px solid black;" unselectable="off" ></div>
Own Clipboard(hack)
<div id="book" contenteditable="true"style="background-color:#555;color:white;"> </div>

Categories