Ckeditor adds empty paragraphs when applying a style - javascript

My CKEditor is adding a lot of unnecessary tags when applying a style to a selected paragraph
I initiate CKeditor with the following html:
<p>
Hi, this a text!</p>
When I select the paragraph and apply a style using the toolbar, CKEditor formats my html to the following:
<p>
<span style="display: none;"> </span></p>
<p>
<span id="cke_bm_173S" style="display: none;"> </span>Hi, this a text!<span id="cke_bm_173E" style="display: none;"> </span></p>
<p>
<span style="display: none;"> </span></p>
Is there any way preventing CKEditor from adding the paragraphs with the non breaking space?
Things I've already tried are adding config.fillEmptyBlocks = false; and config.IgnoreEmptyParagraphValue = true; to my config file
Update
Turns out this problem was caused by the style itself which was a custom defined style. This piece of code was the problem: {name : 'Heading1', element : 'p class= "subheadingsecondlevel"}, once I changed it to: {name : 'Heading1', element : 'p', attributes : {class : 'subheadingsecondlevel'} }

You might want to consider these:
config.enterMode = CKEDITOR.ENTER_BR;
config.autoParagraph = false;
You can check out my post here for more info:
How to configure ckeditor to not wrap content in <p> block?
The following config setting will stop the editor from inserting a non-breaking space in empty paragraphs:
config.fillEmptyBlocks = false;
Was all of the additional code inserted after applying just one style?
What style did you apply, is all the extra code inserted regardless of the style you use?
What happens if you select the text and click the bold button?
Is the code you are showing being copied from the source view of the editor or from the final page that you use to display your content?
Be Well,
Joe

Or, if all fails, you can use the CSS selector pseudo-class ':empty' and give it a 'display:none'. In practice, you add this line to your CSS:
p:empty {
display:none
}
I understand it's a dirty solution but it works perfectly in most cases and has minimal inpact on design and functionality.

Related

How to change color of a search word in HTML?

So in my HTML file, I have
<p class = "result"> {{searchResult}} </p>
where {{searchResult}} is essentially my result.
So if I searched for the term "hot",
{{searchResult}} would contain a string containing the word "hot" in a document.
For example:
"This is hot"
Everything shows up in the webpage perfectly fine but I want to change the color of the search term within the string.
I tried modifying the part where it should output the content in my JS file:
content: result.replace(searchTerm, <span class= "search">searchTerm</span>)
where the class "search" is just changing the color of the word.
But it shows up as the webpage as:
This is <span class = "search">hot</span>
How would I make it so that it changes the color only of the search term?
You're looking to change the style of the html content. This is done using CSS. You can do this in one of three ways:
1) Edit the color of the paragraph using in-line CSS: <p class="result" style="color:red;"> {{searchResult}} </p>
2) Create an external .css file and link your html file to it in the <head> of the document. Use similar css there:
.result {
color:red;
}
3) Edit the DOM using Javascript to similarly change the color:
document.querySelector('.result').style.color='red';

Get the Text inside the element

<p class="MsoNormal" style="margin-bottom:0cm;margin-bottom:.0001pt;text-align:
justify;line-height:normal">
First Text
<span lang="EN-US" style="font-size:12.0pt;
font-family:"Times New Roman","serif"">
Second Text</span>
</p>
This is my code, how to get the content inside the paragraph tag. [The tag may change to div or ul]. I need all the content inside the paragraph tag by javascript.
The output should be :
First Text Second Text
Sorry I am new to javascript, searched but cant find answer for this relevant problem. Thanks
To get the value of a tag, you can get the element with a selector and use innerHTML to get the value. like this:
<p>hi there</p>
console.log(document.getElementsByTagName('p')[0].innerHTML);
n.b. in the code above it's selecting by tag name, so it returns an array of matching elements
So in your example, using .innerHTML with give you the P tags content, including any html tags etc.
if you want just the content, you can use .textContent
console.log(document.getElementsByTagName('p')[0].textContent);
This wont give you the inner html tags
n.b. there is also the innerText method, However this isnt supported accross browsers.
You can change according to the tag you need, but basically this will do the trick:
document.getElementsByTagName('p')[0].innerText
Fiddle
InnerText should be a good solution.
console.log(document.getElementsByTagName('p')[0].innerText);
<p class="MsoNormal" style="margin-bottom:0cm;margin-bottom:.0001pt;text-align:
justify;line-height:normal">
First Text
<span lang="EN-US" style="font-size:12.0pt;
font-family:"Times New Roman","serif"">
Second Text</span>
</p>

change visibility of span using jquery

I work on a durandal project.
I have span and button elements in html.
The span elements are hidden and I want to show these on button click.
My problem is that when I hide the span from html- it can't show it from javascript.
I saw this question (on link change visibility of label tag using jquery) and I tried all of the answers- nothing helped me.
(I tried using:
in html:
<span id="mySpan" hidden = "hidden">aaa</span>
or:
<span id="mySpan" style= "visibility:collapse">aaa</span>
or:
<span id="mySpan" style= "display:none">aaa</span>
in javascript:
$("#mySpan").show();
or:
$("#mySpan").css('visibility', 'visible');
I tried all of the optional combinations
)
Note: I want you to know that when I'm not hiding the span from the HTML, and try using toggle(), hide(), show() - it works well.
Example that does not work:
on html page:
<span id="mySpan" hidden = "hidden">aaa</span>
on javascript page:
$("#mySpan").show();
Your HTML is not OK!
Remember, spans are closed <span></span> this way, and not the way you are closing them! That way, only self-closing elements such as: input, img etc are closed!
Try to write this:
<span id="mySpan">Some text!</span>
The CSS would be:
#mySpan {
display: none; // you're using diaplay!
}
Now using jQuery either use this:
$('#mySpan').show()
Or this:
$('#mySpan').css('display', 'block');
Well, your code is all wrong.
The id attribute should only be used once per page. It is meant to be unique so that you can refer to it as a single point in the document. You should change it to class="mySpan" and then select them using $(".mySpan").
visible:collapse is invalid CSS. You probably meant to use visibility, yes?
diaplay:none is also invalid CSS. Probably a typo of display, yes?
There is a hidden attribute in the newest HTML spec (usually called HTML5). I am not sure if you are aware of it; if you are, and you are trying to use it, then you should put the following in your CSS file so that it works in browsers that have not yet implemented it:
*[hidden] {
display: none;
}
Follow-up:
Okay, you want to be able to toggle a span on and off by clicking on a button. This will do it:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<button id="myButton">Show/hide the span</button><br>
<span id="mySpan" style="display:none">This is a span with some text in it</span>
<script>
$(function() {
$("#myButton").click(function() {
$("#mySpan").toggle();
});
});
</script>
Seems to be an error in "diaplay"? Try to change:
<span id="mySpan" style="diaplay:none"/>
to:
<span id="mySpan" style="display:none"/>

jQuery highlight pieces of text in an element across tags

I want to select and return searched text using jQuery.
The problem is; parts of the text may be located in <span> or other inline elements, so when searching for 'waffles are tasty' in this text: 'I'm not sure about <i>cabbages</i>, but <b>waffles</b> <span>are</span> <i>tasty</i>, indeed.', you wouldn't get any matches, while the text appears uninterrupted to people.
Let's use this HTML as an example:
<div id="parent">
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
<span>
there's loads of
</span>
tortoises over there, OMG
<div id="child">
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
TURTLES!
</div>
</div>
With this (or similar) JavaScript:
$('div#parent').selectText({query: ['i like', 'turtles', 'loads of tortoises'], caseinsensitive: true}).each(function () {
$(this).css('background-color', '#ffff00');
});
//The (hypothetical) SelectText function would return an array of wrapped elements to chain .each(); on them
You would want to produce this output: (without the comments, obviously)
<div id="parent">
<span style="font-size: 1.2em">
<span class="selected" style="background-color: #ffff00">
I
</span> <!--Wrap in 2 separate selection spans so the original hierarchy is disturbed less (as opposed to wrapping 'I' and 'like' in a single selection span)-->
</span>
<span class="selected" style="background-color: #ffff00">
like
</span>
<span class="selected" style="background-color: #ffff00"> <!--Simple match, because the search query is just the word 'turtles'-->
turtles
</span>
<span>
quite a
</span>
lot, actually.
<span>
there's
<span class="selected" style="background-color: #ffff00">
loads of
</span> <!--Selection span needs to be closed here because of HTML tag order-->
</span>
<span class="selected" style="background-color: #ffff00"> <!--Capture the rest of the found text with a second selection span-->
tortoises
</span>
over there, OMG
<div id="child"> <!--This element's children are not searched because it's not a span-->
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
TURTLES!
</div>
</div>
The (hypothetical) SelectText function would wrap all selected text in <span class="selected"> tags, regardless of whether parts of the search are located in other inline elements like <span>, '', etc. It does not search the child <div>'s contents because that's not an inline element.
Is there a jQuery plugin that does something like this? (wrap search query in span tags and return them, oblivious to whether parts of the found text may be located in other inline elements?)
If not, how would one go about creating such a function? This function's kinda what I'm looking for, but it doesn't return the array of selected spans and breaks when parts of the found text are nested in other inline elements.
Any help would be greatly appreciated!
Piece of cake! See this.
Folded notation:
$.each(
$(...).findText(...),
function (){
...
}
);
In-line notation:
$(...).findText(...).each(function (){
...
}
);
Three options:
Use the browser's built-in methods for this. For the finding, IE has TextRange with its findText() method; other browsers (with the exception of Opera, last time I checked, which was a long time ago) have window.find(). However, window.find() may be killed off without being replaced at some point, which is not ideal. For the highlighting, you can use document.execCommand().
Use my Rangy library. There's a demo here: http://rangy.googlecode.com/svn/trunk/demos/textrange.html
Build your own code to search text content in the DOM and style it.
The first two options are covered in more detail on this answer:
https://stackoverflow.com/a/5887719/96100
Since I just so happened to be working on a similar thing right now, in case you'd like to see the beginnings of my interpretation of "option 3", I thought I'd share this, with the main feature being that all text nodes are traversed, without altering existing tags. Not tested across any unusual browsers yet, so no warranty whatsoever with this one!
function DOMComb2 (oParent) {
if (oParent.hasChildNodes()) {
for (var oNode = oParent.firstChild; oNode; oNode = oNode.nextSibling) {
if (oNode.nodeType==3 && oNode.nodeValue) { // Add regexp to search the text here
var highlight = document.createElement('span');
highlight.appendChild(oNode.cloneNode(true));
highlight.className = 'selected';
oParent.replaceChild(highlight, oNode);
// Or, the shorter, uglier jQuery hybrid one-liner
// oParent.replaceChild($('<span class="selected">' + oNode.nodeValue + '</span>')[0], oNode);
}
if (oNode.tagName != 'DIV') { // Add any other element you want to avoid
DOMComb2(oNode);
}
}
}
}
Then search through things selectively with jQuery perhaps:
$('aside').each(function(){
DOMComb2($(this)[0]);
});
Of course, if you have asides within your asides, strange things might happen.
(DOMComb function adapted from the Mozilla dev reference site
https://developer.mozilla.org/en-US/docs/Web/API/Node)
I wrote a draft as a fiddle. The main steps:
I made a plugin for jQuery
$.fn.selectText = function(params){
var phrases = params.query,
ignorance = params.ignorecase;
wrapper = $(this);
. . .
return(wrapper);
};
Now I can call the selection as a $(...).selectText({query:["tortoise"], ignorance: true, style: 'selection'});
I know you want to have iterator after the function call, but in your case it is impossible, because iterator have to return valid jQuery selectors. For example:
word <tag>word word</tag> word is not valid selector.
After sanitizing the content of wrapper, for each search makeRegexp() makes personal regular expression.
Each searched piece of html source goes to emulateSelection() and then wrapWords()
Main idea is to wrap in <span class="selection">...</span> each single piece of phrase not separated by tags, but not analyze the whole tree of nodes.
NOTE:
It's NOT working with <b><i>... tags in html. You have to make corrections in regexp string for it.
I not guarantee it will work with unicode. But who knows...
As I understood, we talking about iterators like $.each($(...).searchText("..."),function (str){...});.
Check the David Herbert Lawrence poem:
<div class="poem"><p class="part">I never saw a wild thing<br />
sorry for itself.<br />
A small bird will drop frozen dead from a bough<br />
without ever having felt sorry for itself.<br /></p></div>
Actually, after rendering, browser will understood it like this:
<div class="poem">
<p class="part">
<br>I never saw a wild thing</br>
<br>sorry for itself.</br>
<br>A small bird will drop frozen dead from a bough</br>
<br>without ever having felt sorry for itself.</br>
</p>
</div>
For example, I looking for the phrase: "wild thing sorry for". Therefore, I have to highligt the exerpt:
wild thing</br><br>sorry for
I can not wrap it like this <span>wild thing</br><br>sorry for</span>, then create jQuery selector by some temporary id="search-xxxxxx", and return it back -- it's wrong html. I can wrap each piece of text like this:
<span search="search-xxxxx">wild thing</span></br><br><span search="search-xxxxx">sorry for</span>
Then I have to call some function and return jQuery array of selectors:
return($("[search=search-xxxxx]"));
Now we have two "results": a) "wild thing"; b) "sorry for". Is it really what you want?
OR
You have to write you own each() function like another plugin to jQuery:
$.fn.eachSearch = function(arr, func){
...
};
where arr will be not an array of selectors, but array of arrays of selectors, like:
arr = [
{selector as whole search},
{[{selector as first part of search]}, {[selector as second part of search]}},
...
]

Can I use complex HTML with Twitter Bootstrap's Tooltip?

If I check official documentation, I can see a property called HTML:
Name | Type | default | Description
----------------------------------------------------------------------------
html | boolean | false | Insert html into the tooltip.
If false, jquery's text method
will be used to insert content
into the dom. Use text if you're
worried about XSS attacks.
It says, "insert html into the tooltip", but the type is boolean. How can I use complex html inside a Tooltip?
This parameter is just about whether you are going to use complex html into the tooltip. Set it to true and then hit the html into the title attribute of the tag.
See this fiddle here - I've set the html attribute to true through the data-html="true" in the <a> tag and then just added in the html ad hoc as an example.
Another solution to avoid inserting html into data-title is to create independant div with tooltip html content, and refer to this div when creating your tooltip :
<!-- Tooltip link -->
<p><span class="tip" data-tip="my-tip">Hello world</span></p>
<!-- Tooltip content -->
<div id="my-tip" class="tip-content hidden">
<h2>Tip title</h2>
<p>This is my tip content</p>
</div>
<script type="text/javascript">
$(document).ready(function () {
// Tooltips
$('.tip').each(function () {
$(this).tooltip(
{
html: true,
title: $('#' + $(this).data('tip')).html()
});
});
});
</script>
This way you can create complex readable html content, and activate as many tooltips as you want.
live demo here on codepen
Just as normal, using data-original-title:
Html:
<div rel='tooltip' data-original-title='<h1>big tooltip</h1>'>Visible text</div>
Javascript:
$("[rel=tooltip]").tooltip({html:true});
The html parameter specifies how the tooltip text should be turned into DOM elements. By default Html code is escaped in tooltips to prevent XSS attacks. Say you display a username on your site and you show a small bio in a tooltip. If the html code isn't escaped and the user can edit the bio themselves they could inject malicious code.
The html data attribute does exactly what it says it does in the docs. Try this little example, no JavaScript necessary (broken into lines for clarification):
<span rel="tooltip"
data-toggle="tooltip"
data-html="true"
data-title="<table><tr><td style='color:red;'>complex</td><td>HTML</td></tr></table>"
>
hover over me to see HTML
</span>
JSFiddle demos:
Bootstrap 2.x
Bootstrap 3.x
set "html" option to true if you want to have html into tooltip. Actual html is determined by option "title" (link's title attribute shouldn't be set)
$('#example1').tooltip({placement: 'bottom', title: '<p class="testtooltip">par</p>', html: true});
Live sample
As of bootstrap 5, you can just specify the contents of the tooltip to be html DOM nodes when configuring it. Sample config...
// setup tools tips trigger
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new Tooltip(tooltipTriggerEl, {
html: true // <- this should do the trick!
})
});
For bootstrap 5, you can use data-bs-html="true" with the title tag data-bs-original-title="Tooltip Title"

Categories