2

I am currently writing my own BBCode parser. Now what I would like to do is allow the user to enter BBCode, and then it will write it into HTML and display it has HTML. Yet if they enter HTML it will just show it as plain old HTML. Here is what I have so far:

var replacebbcode = $('#textareainput').val().replace(/(\[((\/?)(b|u|i|s|sub|sup))\])/gi, '<$2>');
$('#posttextareadisplay').html(replacebbcode);

In the above I am just replacing all BBCode with HTML tags. Problem is if a user directly enter HTML it will use that as well. So basically, how can I display BBCode as HTML, but actual HTML as text?

2 Answers 2

1

Set the target's text() with the full text; so your HTML tags will be encoded. Then do the BBCode replacement on the encoded HTML:

$('#posttextareadisplay').text( $('#textareainput').val() );

var replacebbcode = $('#posttextareadisplay').
  html().
  replace(/(\[((\/?)(b|u|i|s|sub|sup))\])/gi, '<$2>');

$('#posttextareadisplay').html( replacebbcode );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<textarea name="" id="textareainput" cols="30" rows="10">
  [b]bold[/b] &lt;bold>bold&lt;/bold>
</textarea>

<p id="posttextareadisplay"></p>

Sign up to request clarification or add additional context in comments.

4 Comments

Hello, thank you for replying! :) Problem is, the text will not update. I am making this a live preview (as you know probably). Here is my JSFiddle: jsfiddle.net/18ehuy5t
Should be grabbing the val(), not text, of the textarea. Fixed above. Also fixed your fiddle: jsfiddle.net/18ehuy5t/1
Thank you! :) Also while you are still here, I have one more question you may be able to answer. If a user enters this in there Textarea lets say: Hello, my name is Michael. What is your name?, then they try to highlight the second name, and style it. It will then just style the first name. It is because of the replace, are there any other ways to replace the text in the textarea correctly? Do you understand my question? :)
Basically, yes. See questions such as stackoverflow.com/questions/3964710/… to get it right.
0

If you want to replace with regular html tags and restrict to only specific BB tags. This is how it's done with a little help from jQuery and Regular Expression:

const replaceBBCodeAsElements = (jElement, tagMapping = {}) =>
  jElement.html(jElement.html().replace(/\[(?<tag>\w+)\](.+?)\[\/\k<tag>\]/g,
      (...{ 0: original, 1: tagName, 2: tagContent }) =>
          tagMapping.hasOwnProperty(tagName) ? $(tagMapping[tagName]).html(tagContent)[0].outerHTML : original
  ));

And here is an example of using this function:

const replaceBBCodeAsElements = (jElement, tagMapping = {}) =>
  jElement.html(jElement.html().replace(/\[(?<tag>\w+)\](.+?)\[\/\k<tag>\]/g,
      (...{ 0: original, 1: tagName, 2: tagContent }) =>
          tagMapping.hasOwnProperty(tagName) ? $(tagMapping[tagName]).html(tagContent)[0].outerHTML : original
  ));

const config = {
  'a': '<div class="tag some-special-a-tag" />',
  'object': '<span class="tag some-special-object-tag" />',
  'pre': '<p class="tag some-special-pre-tag" />',
  'test': '<div data-hello="world" class="tag some-special-test-tag" />',
};

$("#input").bind("input", function() {
  const jRes = $("#result");
  jRes.text(this.value);
  replaceBBCodeAsElements(jRes, config);
}).trigger('input');
#input {
  width: 400px;
  height: 100px;
}

#result {
  white-space: pre-wrap;
}

.tag {
 display: inline-block;
 background: rgba(0,0,0,.1);
 padding: 0 4px;
 border-radius: 5px;
 font-family: monospace;
 font-weight: bold;
 margin: 0;
 box-shadow: 0 0 10px 0 rgba(0,0,0,.6);
}

.some-special-a-tag {
 background: rgba(255,0,0,.1);
}

.some-special-object-tag {
 background: rgba(0,255,0,.1);
}

.some-special-pre-tag {
 background: rgba(0,0,255,.1);
}

.some-special-test-tag {
 background: rgba(0,255,255,.1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<textarea id="input">This &lt;p&gt;is&lt;/p&gt; 
a [a]test[/a] text [pre]with[/pre] [b]some[/b] va[test]lu[/test]e.

And this is how it looks [object]when a [pre]tag inside[/pre] other[/object] tag</textarea>

<div id="result"></div>

The above example, will parse only [a], [object], [pre] and [test] BB tags and convert them according to the creation element they are pointing to.

Note, that the minimum required version of JS is ES2018, because of the RegExp Named Group support.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.