Say I want to have the 'bold' option selected by default when the editor is initialized. How would I do that?
EDIT: A solution working with what Thariama answered is the following. I discovered that having the <p> tag left in there screwed with selecting other options, like with different headlines, and as I have no need for a <p> tag in this particular editor I did this in order to get <h1> by default:
setup: function(ed) {
ed.onInit.add(function(ed) {
if ($('p', ed.getDoc()).length > 0) {
$('p', ed.getDoc()).remove();
$('<h1><br mce_bogus="1" /></h1>').appendTo($('body', ed.getDoc()));
}
});
}
This works great even when the user jumps between selection options in a select.
EDIT2: This seems to work if you do need the <p> tag. This makes it bold by default:
setup: function(ed) {
ed.onInit.add(function(ed) {
if ($('p', ed.getDoc()).children().length == 1 && $('p', ed.getDoc()).children(':first').is('br')) {
$('p', ed.getDoc()).html('<b><br mce_bogus="1" /></b>');
}
});
}
Rather than doing it when the user enters it, why not output the values inside a bold tag when you output the data to the user outside of tinyMCE? That way, the user has no ability to override the option as they would if you simply had a tag inside.
As an aside, if you're using TinyMCE for a wysiwg web editor in an environment where users first generate code in Microsoft Word, there are significant issues with getting "junk" word code in via paste. Tiny's solution is a "paste from word" button, which users seem to often ignore -- I've deployed Tiny in 50+ business websites, and it's been a major issue with a majority of the clients using those sites. I switched over to CKEditor, which does word code-stripping on the FRONT end, and all's been well. People have their preferences, and I even liked using Tiny more. But Word Code issues have become a dealbreaker for me and I won't install Tiny any more.
The procedure of choice depends on many factors. If you have an empty tinymce editor you can initialize your editor with the following content
<p><strong><strong></p>
Please update your question regarding your use case.
EDIT: This might work better for you. Add this handler to one of your own plugins.
It checks for all paragraphs (if your tinymce uses divs you need to alter this piece of code)
and wraps the inner HTML into b-tags (you might want to use strong-tags).
ed.onInit.add(function(ed){
ps = ed.getDoc().getElementsByTagName('p');
for (var i=0; i < ps.length ; i++) {
ps[i].innerHTML = '<b>'+ps[i].innerHTML+'</b>';
}
});
Another option you have is to not use an own plugin, but to use the setup parameter when initializing tinymce:
setup : function(ed) {
ed.onInit.add(function(ed){
ps = ed.getDoc().getElementsByTagName('p');
for (var i=0; i < ps.length ; i++) {
ps[i].innerHTML = '<b>'+ps[i].innerHTML+'</b>';
}
});
},
Related
i am currently using mark.js for a google chrome extension to highlight some text on a web page.
Now whenever i refresh the page or do a right click all my marking is lost.
Is there a way to keep that marking? As far as i see mark.js does not change the DOM.
I would like to mark the text but also be able e.g. when i print that page or save it as a pdf, to maintain the highlighting i did..
That is the way i mark. it is pretty much the same as instructed on https://markjs.io/:
function mark(text, label){
var paragraphs = Array.from(document.getElementsByClassName('description-line'));
switch(label){
case "strAdv":
for(var elem of paragraphs) { // loop through each element in paragraphs array
var instance=new Mark(elem);
instance.mark(text, {className: "strAdv",separateWordSearch:false});
}
break;
....
strAdv.css:
/*CSS to define diferent marking classes*/
.strAdv {
padding: 0;
background-color: chartreuse;
}
Found a way to overcome that problem.
Just store the text items you want to mark and mark them again every time a page gets refreshed.
I am designing crowdsourcing interface on crowdflower platform, during design, I need cml:text or cml:textarea to accept workers's text input. Here is an example:
<cml:textarea label="my_name" id="my_id" validates="required" default="123456"/>
The default value shown in this text box is "123456", however, it will disappear after user clicking. What if I want to preload some content which can be reused (doesn't disappear) by the workers? I tried the following methods:
document.getElementById('my_id').html() = "678910";
document.getElementById('my_id').innerHTML ="678910";
document.getElementById('my_id').value = "678910";
document.getElementById('my_id').default = "678910";
document.getElementById('my_id').placeholder = "678910";
document.getElementByName('my_name').html() = "678910";
...
None of them works. Is it doable to update text in cml:text or cml:textarea on crowdflower platform?
I ran into this today! It seems that document.getElementById or its alternatives do not work for cml input tags. Here is a workaround using jQuery that worked for me. Put your cml:textarea in a div, then use find to get the inputs inside the parent div.
require(['jquery'], function($) {
var my_element = $("#parent_element_id").find("input")[0]; // first input element in the list
my_element.value = "678910";
});
Hope this helps!
Is there a way in <select> list, for example, to make onClick activate a JavaScript function that will show the title of the element just as pattern in HTML 5 does?
I want to do that when you click on the <select>, it will activate a JavaScript function that under some condition (doesn’t matter—some if expression) will show a sentence (that I wrote) in a bubble like place (the place that the pattern shows the title when something isn’t according to the pattern (pattern in HTML5)).
You can set a custom validity error on a select element by calling the setCustomValidity method, which is part of the constraint validation API in HTML5 CR. This should cause an error to be reported, upon an attempt at submitting the form, in a manner similar to reporting pattern mismatches. Example:
<select onclick="this.setCustomValidity('Error in selection');
title="Select a good option">
(In practice, you would probably not want to use onclick but onchange. But the question specifically mentions onClick.)
There are problems, though. This only sets an error condition and makes the element match the :invalid selector, so some error indicator may happen, but the error message is displayed only when the form data is being validated due to clicking on a submit button or something similar. In theory, you could use the reportValidity method to have the error shown immediately, but browsers don’t support it yet.
On Firefox, the width of the “bubble” is limited by the width of the select element and may become badly truncated if the longest option text is short. There is a simple CSS cure to that (though with a possible impact on the select menu appearance of course).
select { min-width: 150px }
You might also consider the following alternative, which does not affect the select element appearance in the normal state but may cause it to become wider when you set the custom error:
select:invalid { min-width: 150px }
There is also the problem that Firefox does not include the title attribute value in the bubble. A possible workaround (which may or may not be feasible, depending on context) is to omit the title attribute and include all the text needed into the argument that you pass to setCustomValidity.
A possible use case that I can imagine is a form with a select menu such that some options there are not allowed depending on the user’s previous choices. Then you could have
<select onchange="if(notAllowed(this)) setCustomValidity('Selection not allowed')" ...>
where notAllowed() is a suitable testing function that you define. However, it is probably better usability to either remove or disable options in a select as soon as some user’s choices make them disallowed. Admittedly, it might mean more coding work (especially since you would need to undo that if the user changes the other data so that the options should become allowed again).
In my opinion Jukka's solution is superior however, its fairly trivial to do something approaching what you're asking for in JavaScript. I've created a rudimentary script and example jsFiddle which should be enough to get you going.
var SelectBoxTip = {
init : function(){
SelectBoxTip.createTip();
SelectBoxTip.addListeners();
},
addListeners : function(){
var selects = document.getElementsByTagName("select");
for (var i = 0; i < selects.length; i++){
var zis = selects[i];
if(zis.getAttribute('title')){//only if it has a title
zis.addEventListener("focus", SelectBoxTip.showTip, false);
zis.addEventListener("blur", SelectBoxTip.hideTip, false);
}
}
},
createTip : function(){
tip = document.createElement("div");
tip.id = "tip";
tip.style.position = "absolute";
tip.style.bottom = "100%";
tip.style.left = "0";
tip.style.backgroundColor = "yellow";
document.body.appendChild(tip);
},
showTip : function(e){
this.parentNode.appendChild(tip);
tip.innerHTML=this.title;
tip.style.display="block";
},
hideTip : function(e){
tip.style.display="none";
}
};
SelectBoxTip.init();
Let's say I have a contentEditable div, to the user can edit and change the text and elements inside it. How do I arbitrarily change the selection in this div with javascript? By "change" I don't mean "change the contents of whatever the user has selected", I mean actually change what is selected. The user should then be able to type over the selection, replacing it with something else.
This should take into account that I may want to select text across elements. For instance:
<p>Some text <span>goes</span> here.</p>
I may for instance want to select "Some text go", or everything inside the <p>.
This only needs to work in Safari/Webkit.
Thanks in advance. As a native code developer, I find the DOM and Javascript in general quite frustrating.
Just to answer my own question in detail so anyone searching for something similar doesn't have to go looking elsewhere...
The code I ended up using was something like this:
var range = document.createRange();
range.setStart( <get the node the selection starts in>, <char offset in that node> );
range.setEnd( <get the node the selection ends in>, <char offset in that node> );
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
Big thanks to James Black for pointing me in the right direction.
Unless you need to write your own, you may want to look at tinyMCE, http://tinymce.moxiecode.com/, as it is a nice WYSIWYG editor in javascript.
In order to do this you will probably want to look at something like this:
http://codingtricks.blogspot.com/2009/03/javascript-select-partial-text-in-div.html
These may also be helpful:
JavaScript ranging gone wrong
https://developer.mozilla.org/en/DOM/window.getSelection
What you are trying to do will be complex, as you will need to take the selected area, remove all the tags, then put in the tag that you want for the selected area.
You can use document.getElementById('your_text_id').setSelectionRange(start, end); and you can use Math.random() to generate random numbers for start and end
While #Lucas's answer is good, there is a lot missing that would allow you to successfully use this. The node the selection starts in has to be the exact node, not a parent. In our case we were trying to put some text into a TextAngular control, then select text that looked liked ____ so the user could "fill in the blank".
Our input was html of the order <p>Some text goes here: _____</p> or
<p>Some partial goes here
<ul>
<li>Option 1</li>
<li>_____</li>
</ul>
To get this to work, we had to write something to find the underscores in the right element
function find_(node) {
var i, n;
// return the node with the _'s
for(i=0; i < node.childNodes.length; ++i) {
n = node.childNodes[i];
console.debug(n);
if(n.textContent) {
console.debug(n, n.textContent);
if(n.textContent.search(/___+/) > 0) {
return n;
}
}
if(n.childNodes) {
console.debug(n, n.childNodes);
n = find_(n);
if(n) {
return n;
}
}
}
return null;
}
So in the end, finding the node to satisfy <get the node the selection starts in> was a lot more work than that simple sentence led me to believe.
In the <ul> case. the node that contains the ____ is firstChild of the li node.
I've put this here to help others that need to do this not wonder why they are getting the error message
IndexSizeError: Failed to execute 'setStart' on 'Range': There is no child at offset 65.
When the problem is they are just looking at the wrong node.
I am trying to write a JavaScript script to add to greasemonkey that adds a button after an element. The onClick for this button should copy the parents element text to the keyboard. I have seen plenty of examples that copy already selected text to the clipboard such as this:
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
function copyit(theField) {
var selectedText = document.selection;
if (selectedText.type == 'Text') {
var newRange = selectedText.createRange();
theField.focus();
theField.value = newRange.text;
} else {
alert('Alert: Select The text in the textarea then click on this button');
}
}
// End -->
</script>
<input onclick="copyit(this.form.text_select)" type="button" value="Click Here to Copy the Highlighted Text" name="copy_button">
Found here.
I have also found that you can select text in input elements. I have tried combining both techniques, as well as many others with no viable solution yet. I am not even sure why the code above copies to the clipboard. Does anyone have a solution to this?
If you took the time to read the full article, the author states this doesn't work for Firefox...
Actually, I think it doesn't even work for IE, as it does nothing related to the clipboard!
There is a technique using Flash, because by default, Firefox inhibits clipboard access for security reasons.
Otherwise, the classical way to do copy is:
var tc = textToCopy.replace(/\n\n/g, '\n');
if (window.clipboardData) // IE
{
window.clipboardData.setData("Text", tc);
}
else
{
unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const clipboardHelper = Components.classes
["#mozilla.org/widget/clipboardhelper;1"].
getService(Components.interfaces.nsIClipboardHelper);
clipboardHelper.copyString(tc);
}
after enabling copy (for a given site).
Are you sure your example works? It does not in my browser. But take a look at the following page: http://www.jeffothy.com/weblog/clipboard-copy/