Avoid linebreaks in dynamic text except after a certain character (jQuery) - javascript

I have given text strings which are displayed in containers of varying width. I want to allow linebreaks only after the character "·", which occurs two or three times in each of those text strings.
What I came up with (see below): With jQuery, I wrapped a span around the whole string with a css class that applies white-space: nowrap; to the string, and additionally I added a <br> tag after each "·", both using a replaceAll function: Now line breaks can only happen at the position of the inserted <br> tags.
My problem: This forces line breaks at all <br> tags. But if part one and two of the text string (i.e. the text up to the second "·" character) would fit into the parent container next to each other, I would like the line break only to happen after the second "·"!
var mytext = $('#wrapper2 .string1').text();
var search = " ·";
$('#wrapper2 .string1').each( function(index, element) {
$(element).html( $(element).html().replaceAll(mytext, '<span class="inner_wrapper">' + mytext + '</span>') );
$(element).html( $(element).html().replaceAll(search, search + '<br>') );
})
.wrapper1 {
width: 400px;
border: 1px solid #aaa;
padding: 0.5em;
font-size: 18px;
text-align: center;
}
#wrapper2 .inner_wrapper {
white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>The original text</h3>
<div id="wrapper1" class="wrapper1">
<p class="string1">The title of the event · day, month and year · at the end the location</p>
</div>
<p>The width of the above box can change. What I want: Linebreaks should only occur <b>after the "·" characters</b>.</p>
<h3>The text processed by jQuery</h3>
<div id="wrapper2" class="wrapper1">
<p class="string1">The title of the event · day, month and year · at the end the location</p>
</div>
<p>This comes close, but if there is enough space (as in the boxes above), the first linebreak should occur after the <b>second</b> "·" character, not after <em>all</em> of them.</p>

You could use the <wbr /> tag to add a word break only when needed, but unfortunately this does not work with a white-space: nowrap; style. The trick is to remove that style, replace all spaces with (non-braking space) entity, and restore spaces (or <wbr /> tags) where needed:
var $el = $('#wrapper2 .string1');
var html = $el.text()
.replace(/ /g, ' ')
.replace(/( ·)/g, '$1 '); // or replace with '$1<wbr />'
$el.html(html);
.wrapper1 {
width: 400px;
border: 1px solid #aaa;
margin: 3px 0;
padding: 0 0.5em;
font-size: 18px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<b>The original text</b>
<div id="wrapper1" class="wrapper1">
<p class="string1">The title of the event · day, month and year · at the end the location</p>
</div>
<b>The text processed by jQuery</b>
<div id="wrapper2" class="wrapper1">
<p class="string1">The title of the event · day, month and year · at the end the location</p>
</div>

To complete this question/answer set for anyone who's interested, here's the solution I came up with myself after reading #Nikkorian's comment concerning split() and wrapping the split substrings in <span> tags, to which I apply white-space: nowrap via CSS to avoid linebreaks inside them:
I split the text string using split('·') (var "parts", which is an array), looped through that array until the next-to-last part adding span tags around it and a · before span's end tag, then added the last part, also with a span tag around it, but without the · at the end.
$('#wrapper2 .string1').each( function(index, element) {
var parts = $(element).text().split(' · ');
var editedContent = '';
for(var i=0; i < parts.length - 1; i++) {
editedContent += '<span>' + parts[i] + ' ·</span> ';
}
editedContent += '<span>' + parts[i] + '</span>';
$(element).html(editedContent);
});
.wrapper1 {
width: 400px;
border: 1px solid #aaa;
padding: 0.5em;
font-size: 18px;
text-align: center;
}
#wrapper2 > .string1 > span {
white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>The original text</h3>
<div id="wrapper1" class="wrapper1">
<p class="string1">The title of the event · day, month and year · at the end the location</p>
</div>
<p>The width of the above box can change. What I want: Linebreaks should only occur <b>after the "·" characters</b>.</p>
<h3>The text processed with javascript/jQuery</h3>
<div id="wrapper2" class="wrapper1">
<p class="string1">The title of the event · day, month and year · at the end the location</p>
</div>
<p>This is the desired result: linebreaks can only occur after the "·" characters which appear between the substrings, but if the container is wide enough, two or more substrings can appear in the first line.</p>

Related

How can I change all text to Americanized spelling using Javascript/jQuery?

I have two websites, one for the UK and one for the US, both of which use the same text in some places, spelled in the British way - e.g. "I specialise in optimising stuff"
Is there a Javascript/JQuery package/solution to automatically replace all the British spelling that it finds in the DOM, to American spelling? E.g. change the above to "I specialize in optimizing stuff"
So I suppose I could loop through the DOM elements and replace them, eg
$('p').each(function() {
var text = $(this).text();
text = text.replace('ise', 'ize');
$(this).text(text);
});
But this won't work in all cases, e.g. "wise" should not be changed to "wize". Are there any known regex or similar solutions to solve this?
Here is a solution that uses a translation table and some jQuery and native JavaScript to traverse the DOM and to change text, excluding tag attributes. Click on the Switch to USA Spelling button:
const translations = {
colour: 'color',
colours: 'colors',
Colour: 'Color',
Colours: 'Colors',
optimising: 'optimizing',
specialise: 'specialize'
};
const regex = new RegExp('\\b(' + Object.keys(translations).join('|') + ')\\b', 'g');
console.log('regex', regex);
$(document).ready(function() {
$('.switchSpelling button').click(function() {
$('#mainContent *').contents().each(function() {
if(this.nodeType == 3) {
this.nodeValue = this.nodeValue.replace(regex, m => {
return translations[m];
});
}
});
})
});
.switchSpelling {
float: right;
margin-right: 70px;
}
.grayBackgroundColour {
background-color: #f0f0f0;
padding: 3px 10px;
}
.yellowBackgroundColour {
background-color: #fffff0;
padding: 3px 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="mainContent">
<div class="switchSpelling">
<button>Switch to USA Spelling</button>
</div>
<h1>The history of Colour</h1>
<div class="grayBackgroundColour">
<h2>Colours in Renaissance</h2>
<p>We specialise in optimising and restoring colours</p>
</div>
<div class="yellowBackgroundColour">
<h2>Colours in Cubism</h2>
<p>We specialise in optimising and restoring colours</p>
</div>
</div>

Replace end of multi HTML text with a few dots

I have the following mark-up:
if ($('.replacetext').text().length > 20) {
var linkText = $('.replacetext').text();
$('.replacetext').html(linkText.substring(0, 20) + "...")
$('.replacetext').on("click", function(e) {
console.log("linkText :: ", linkText);
$('.replacetext').html(linkText);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<h5>
<a class="replacetext" href="">I am a very long title and I need to be shortened And Also I am a very long title and I need to be shortened</a>
</h5>
<h5>
<a class="replacetext" href="">I am a very long title and I need to be shortened And Also I am a very long title and I need to be shortened</a>
</h5>
How can I make it so that if the h5 text (h5 may be more then one) is above a certain number of characters, I get rid of the other characters and replace them with a "..."?
the problem with this code is it also replaces the text same at all h5 tags along with dots.
First up I would reconsider the use of the a tag. You don't have a link. Use something else. I'll leave that up to you.
Next, you want to store the original text. I will use data attributes for this.
Finally, you want to only update the text of the clicked element. We will use the this keyword to help out here.
//Go through each long title
$('.replacetext').each(function() {
//If long title
if ($(this).text().length > 20) {
//Store original string in data attribute
$(this).data("og", $(this).text());
//Replace text
$(this).html($(this).text().substring(0, 20) + "...")
}
});
$('.replacetext').on("click", function(e) {
//Stop the link going anywhere
e.preventDefault();
console.log("Original Text: " + $(this).data("og"));
//Replace with the original
$(this).text($(this).data("og"));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<h5>
<a class="replacetext" href="">I am a very long title and I need to be shortened And Also I am a very long title and I need to be shortened</a>
</h5>
<h5>
<a class="replacetext" href="">I am another very long title and I need to be shortened And Also I am a very long title and I need to be shortened</a>
</h5>
<h5>
<a class="replacetext" href="">I am short</a>
</h5>
See CSS text-overflow Property
div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Add all these. To make in single line.
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
width:100px; // some width
To do in multi line which actually you asked.
#content{
overflow: hidden;
width:100px;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
Please note that this multiline code is supported only in web-kit browsers for now.
This is just a proof of concept and has many unhandled potential pitfalls, but you could recursively iterate the children of the element and truncate the text nodes.
I'm not saying this is a good idea. You'll run into whitespace complications and edge cases. Just saying it could be done this way in theory.
const TEXT = 3;
const ELEMENT = 1;
function truncateElement (elem, maxlength) {
let remaining = maxlength;
[...elem.childNodes].forEach(node => {
if (node.nodeType === TEXT) {
node.nodeValue = node.nodeValue.substr(0, remaining);
remaining -= node.nodeValue.length;
}
else if (node.nodeType === ELEMENT) {
truncateElement(node, remaining);
}
});
if (!remaining) {
elem.appendChild(document.createTextNode('…'));
}
}
document.querySelector('button')
.addEventListener(
'click',
() => truncateElement(document.querySelector('h5'), 20)
);
<div class="demo">
<h5><a class="replacetext" href="">I am a very long title and I need to be shortened And Also I am a very long title and I need to be shortened</a></h5>
<button>Truncate to 20</button>
</div>

Setting HTML Style Using Javascript String Literal - Colon Breaks String Variable

I'm trying to set the style on an HTML element before appending it to the page by passing the style tag through a variable in a JavaScript string literal.
So my code looks like this:
const STYLE = "font-weight: bold; color: crimson; background-color: red;"
const item = `<p class="text" style=${STYLE}>Some Text</p>`
const position = "beforeend";
list.insertAdjacentHTML(position, item);
When I run it though, the HTML on the page looks like this - the quotation mark on the style tag ends after the first colon. Is there any way to get the full string into the style tag?
<p class="text" style="font-weight:" bold; color: crimson; background-color: red;>Some Text</p>
const item = `<p class="text" style=${STYLE}>Some Text</p>
You should wrap ${STYLE} with ":
const item = `<p class="text" style="${STYLE}">Some Text</p>
Browsers for attributes values without " are adding them themselves and closing them before the first space in the string. That's why "font-weight:" was wrapped here:
style="font-weight:" bold; color: crimson; background-color: red;>

javascript - Why do I get a if I script ?

I having hard time to insert a single space at the end of my </span> in a document.execCommand().
document.execCommand("insertHTML", false, "<span class='own-class2'>"+"Test"+"</span>");
The reason behind this is I want the cursor to be outside the <span> after having made the insertion.
Here is a simple jsFiddle to show you what I mean:
jsFiddle
In that example, if you click the image and then write something, the text will be green. That means the text is still inside the span.
So What I want is to insert a normal space after </span>.
What I have already tried:
a space like this '</span> ' -> I get no space in Chrome.
a space like this '</span> ' -> I get </span> in Chrome
So my question is how to add a single space in order to get a result equivalent to this '</span> ' or '</span> ' and not '</span> ' ?
WHAT I GET ON THE INSPECTOR : https://ibb.co/cqCW2x
if I do :
document.execCommand("insertHTML", false, "<span class='own-class2'>"+"Test"+"</span> ");
Maybe you could use the zero width no break space character (invisible character) : \uFEFF.
The advantage of this solution is it does not create an (maybe?) unwanted visible space after the span
function Test() {
document.execCommand("insertHTML", false, "<span class='own-class2'>"+"Test"+"</span>\uFEFF");
}
#textBox {
width: 540px;
height: 200px;
border: 1px #000000 solid;
padding: 0;
overflow: scroll;
}
.own-class2 {color:green;}
<div id="toolBar">
<button height="20px" onclick="Test()" >insert a span</button>
</div>
<div id="textBox" class="textbox" contenteditable="true"></div>

Replace end of HTML text with a few dots [duplicate]

This question already has answers here:
Setting a max character length in CSS
(15 answers)
Closed 2 years ago.
I have the following mark-up:
<h5>
I am a very long title and I need to be shortened
</h5>
How can I make it so that if the h5 text is above a certain number of characters, I get rid of the other characters and replace them with a "..."?
This should work. You have to display the inline element as a block.
Edit: Just realized you want to add dots if the H5 exceeds a number of characters, not if it exceeds a width. I think to do that you will need to use JS - check out the other answer for that.
h5 {
display: block;
white-space: nowrap;
width: 12em;
overflow: hidden;
text-overflow: ellipsis;
color: red; /* This needs to match the color of the anchor tag */
}
a:link {
color: red;
}
<h5>
I am a very long title and I need to be shortened
</h5>
You can do this:
var name = $('a').text();
if (name.length > 20) {
var shortname = name.substring(0, 20) + " ...";
$('a').replaceWith(shortname);
}
If you want to use javascript, you can extend String object by prototyping:
String.prototype.limit = function(length) {
return this.length > length ? (this.substring(0, length) + '...') : this;
}
var str = 'qwertyuiop';
console.log(str.limit(5)); // qwert...
<h5 id="expansion">
<a id="myLink" href="javascript:void(0);">I am a very long title and I need to be shortened And Also I am a very long title and I need to be shortened</a>
</h5>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
if($('#myLink').text().length > 20){
var linkText = $('#myLink').text();
$('#myLink').html(linkText.substring(0,20)+"...")
$('#myLink').on("click",function(){
console.log("linkText :: ",linkText);
$('#myLink').html(linkText);
});
}
</script>
This one is working
<h5>
<a class ="one" href="javascript:void(0);">I am a very long title and I need to be shortened</a>
</h5>
<style>
.one
{
white-space: nowrap;
overflow:hidden;
text-overflow: ellipsis;
display:inline-block;
width : 100px;
}
</style>
set the width according to your website design

Categories