I'm making a website in two column, on the left, you can write, and it display on the right with a special design.
The thing is, I'd like to allow line break on the right side, but it doesn't display. How could I do that ?
here is a preview of my design. To see the full picture, here is a > Fiddle HERE
function wordsinblocks(self) {
var demo = document.getElementById("demo"),
initialText = demo.textContent,
wordTags = initialText.split(" ").map(function(word) {
return '<span class="word">' + word + '</span>';
});
demo.innerHTML = wordTags.join('');
self.disabled = true;
fitWords();
window.addEventListener('resize', fitWords);
}
$(function() {
$('textarea.source').livePreview({
previewElement: $('p#demo'),
allowedTags: ['p', 'strong', 'br', 'em', 'strike'],
interval: 20
});
});
window.onload = wordsinblocks(self);
function fitWords() {
var demo = document.getElementById("demo"),
width = demo.offsetWidth,
sizes = [7.69230769230769, 23.07692307692307, 46.15384615384614, 100],
calculated = sizes.map(function(size) {
return width * size / 100
}),
node,
i,
nodeWidth,
match,
index;
for (i = 0; i < demo.childNodes.length; i++) {
node = demo.childNodes[i];
node.classList.remove('size-1', 'size-2', 'size-3', 'size-4');
nodeWidth = node.clientWidth;
match = calculated.filter(function(grid) {
return grid >= nodeWidth;
})[0];
index = calculated.indexOf(match);
node.classList.add('size-' + (index + 1));
}
}
You can do inserting linebreaks whenever the Enter
key is pressed. One way is to use .which
or .keyCode
:
$(document).keydown(function(e){
var event = e.which || e.keyCode;
if (event == 13){
//do something like this
return '<span class="word"><br/>' + word + '</span>';
}
});
"13" is the character code for Enter
. I've tested it in your code and it works fine. You just need to place it (alter it too) where it doesn't affect any of your functioning codes.
Second way is to copy exactly what is in the "Write" panel before doing some actions like separating the words by encapsulating them in different highlights, etc.
[UPDATE #1]
Just a piece of your code for testing.
function wordsinblocks(self) {
var demo = document.getElementById("demo"),
initialText = demo.textContent,
wordTags = initialText.split(" ").map(function(word) {
return '<span class="word">' + word + '</span>';
});
$(document).keydown(function(e){
var event = e.which || e.keyCode;
if (event == 13){
demo.innerHTML = wordTags.join(' <br/> ');
} else{
demo.innerHTML = wordTags.join('');
}
});
self.disabled = true;
fitWords();
window.addEventListener('resize', fitWords);
}
[UPDATE #2]
function wordsinblocks(self) {
var demo = document.getElementById("demo"),
initialText = demo.innerText.replace(/\n\r?/g,"<br/>"),
wordTags = initialText.split(" ").map(function(word) {
return '<span class="word">' + word + '</span>';
});
demo.innerHTML = wordTags.join('');
self.disabled = true;
fitWords();
window.addEventListener('resize', fitWords);
}
You need to split the source (what you write) by new line
and then split each line by space
.
Update wordsinblocks as:
function wordsinblocks(self) {
var demo = document.getElementById("demo"),
initialText = demo.innerText,
wordTags = initialText.split(/\n/g).map(function(line) {
var spanWord = line.split(/\s/g).filter(Boolean).map(function(word){
return '<span class="word">' + word + '</span>';
});
return "<span class='line-break'>" + spanWord.join("") + "</span>";
});
demo.innerHTML = wordTags.join('');
self.disabled = true;
fitWords();
window.addEventListener('resize', fitWords);
}
Update fitWords as
function fitWords() {
var demo = document.getElementById("demo"),
width = demo.offsetWidth,
sizes = [7.69230769230769, 23.07692307692307, 46.15384615384614, 100],
calculated = sizes.map(function(size) {
return width * size / 100
}),
lineNode,
node,
i, k,
nodeWidth,
match,
index;
for (k = 0; k < demo.childNodes.length; k++) {
lineNode = demo.childNodes[k];
for(i = 0; i < lineNode.childNodes.length; i++) {
node = lineNode.childNodes[i];
node.classList.remove('size-1', 'size-2', 'size-3', 'size-4');
nodeWidth = node.clientWidth;
match = calculated.filter(function(grid) {
return grid >= nodeWidth;
})[0];
index = calculated.indexOf(match);
node.classList.add('size-' + (index + 1));
}
}
}
Add following style
in your css
#demo .line-break:after {
clear: both;
display: table;
content: ""
}
FIDDLE DEMO HERE
Hope, It helps you & let me know if i miss anything.
UPDATE for Multiple Line-Break
Update textarea.reloadPreview as
textarea.reloadPreview = function() {
var previewString = this.val().replace(/\n/g,"<br>");
if (previewString.length > 0) {
previewString = this.htmlUnencode(previewString);
previewString = previewString.replace(opts.paraRegExp, "<p>$1</p><p>$2</p>");
previewString = previewString.replace(opts.lineBreakRegExp, "$1<br />$2");
previewString = previewString.replace(allowedTagsRegExp, "<$1>");
}
try {
// Workaround for a bug in jquery 1.3.2 which is fixed in 1.4
preview[0].innerHTML = previewString;
}
catch (e) {
alert("Sorry, but inserting a block element within is not allowed here.");
}
preview.updatingPreview = false;
this.bind('keyup', this.handleKeyUp);
wordsinblocks(self);
}
Update worksinblocks as
function wordsinblocks(self) {
var demo = document.getElementById("demo"),
initialText = demo.innerText,
wordTags = initialText.split(/\n/g).map(function(line) {
var spanWord = line.split(/\s/g).filter(Boolean).map(function(word){
return '<span class="word">' + word + '</span>';
});
var result = spanWord.join("");
result = result == "" ? "<span class='empty'></span>" : result;
return "<span class='line-break'>" + result + "</span>";
});
demo.innerHTML = wordTags.join('');
self.disabled = true;
fitWords();
window.addEventListener('resize', fitWords);
}
Add following styles
in your css
#demo .line-break .empty {
height: 25px;
display: block
}
#demo .word {
float: left;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 5px;
padding-left: 10px;
padding-right: 10px;
font-size: 2.9vw;
height: 25px;
font-family: "helvetica";
border: 1px solid black;
}
UPDATED FIDDLE HERE
Change wordsinblocks
to
function wordsinblocks(self) {
var demo = document.getElementById("demo"),
initialText = demo.textContent.replace(new RegExp("\n", "g"), '<br>'),
wordTags = initialText.split(" ").map(function(wordWithLineBreaks) {
return wordWithLineBreaks.split('<br>').map(function(word, index, arr) {
return (word === '' ? '' : '<span class="word">' + word + '</span>') +
(index < arr.length - 1 ? '<div class="lb"> </div>' : '') ;
}).join('');
});
demo.innerHTML = wordTags.join('');
self.disabled = true;
fitWords();
window.addEventListener('resize', fitWords);
}
In the for
loop inside the fitWords
function, add, after the first line in the loop:
if (node.tagName.toLowerCase() === 'div') continue;
Change
$(function() {
$('textarea.source').livePreview({
previewElement: $('p#demo'),
allowedTags: ['p', 'strong', 'br', 'em', 'strike'],
interval: 20
});
});
to
$(function() {
$('textarea.source').livePreview({
previewElement: $('p#demo'),
allowedTags: [],
paraRegExp: new RegExp('something nobody will ever enter'),
lineBreakRegExp: new RegExp('something nobody will ever enter'),
interval: 20
});
});
Add to the end of your css:
.lb {
display: block;
clear: both;
}
See jsfiddle for complete solution.
Although, this solution works, it is far from optimal.
For example, the usage of the livePreview
jQuery plugin does not make much sense because it seems that you don't need HTML support as your code is using the textContent
property after livePreview
has done it's job which effectively removes all HTML.
This is also the reason why inserting the line breaks (added by hitting the enter key) did not work in your original code. What happened was the following:
livePreview
replaces these line breaks with <br>
due to the usage of the lineBreakRegExp
option.textContent
property returns only the text, meaning the <br>
's are lost again.So actually, @Shlomi Hassid has provided a better, alothough incomplete, approach. Incomplete because the sizing of the boxes is missing.
you can do it with css instead white-space: pre;
p {
white-space: pre;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With