Home > Back-end >  Allow linebreaks only after a certain character, but don't force them to occur (jQuery)
Allow linebreaks only after a certain character, but don't force them to occur (jQuery)

Time:12-15

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 >'   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" >
  <p >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" >
  <p >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>

CodePudding user response:

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 &nbsp; (non-braking space) entity, and restore spaces (or <wbr /> tags) where needed:

var $el = $('#wrapper2 .string1');
var html = $el.text()
  .replace(/ /g, '&nbsp;')
  .replace(/(&nbsp;·)/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" >
  <p >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" >
  <p >The title of the event · day, month and year · at the end the location</p>
</div>

CodePudding user response:

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 · at the end, then added the last part, also with a span tag around it, but wothout 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" >
  <p >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" >
  <p >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