Simtwo Simtwo - 6 months ago 9
Javascript Question

Allow line break with javascript + LivePreview

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));
}
}

Answer

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