I've needed to display an alert in case there's a text input includes a double-quote which isn't followed by a backslash. So I used 'negative lookbehind' regular expression and achieved that goal.
text.innerHTML.match(/(?<!\\)\"/);
" -> Alert
\" -> OK
However, I found an issue that when users put an indent into text box, the WYSIWYG (Quill) generates a class named "ql-indent-N (indent level starting from 1)" which triggers an alert by " detection.
Thus, I added another exception to the original regular expression like below.
text.innerHTML.match(/(?<!\\)(?<!class=)\"/);
But it didn't work so I tried some tests in console, and saw that
it works fine when I just put
class=" -> OK
while, it does not work when it's inside real tag like
<p class="ql-indent-1"> text </p> -> Alert
How can I make a lookbehind reg exp working fine with those <p class=" ...">? Or any other generous suggestion to achieve the same goal — Displaying an alert to double-quotes not followed by a backslash nor by <p class=" ...">? Below is a basic structure of the textbox.
<div class="ql-editor" data-gramm="false" contenteditable="true">
<p>text</p>
</div>
Dealing Quill's delta format is very complicated.
As mentioned in the comment, you could refer to the element innerText rather than its innerHTML in order to ignore any tag inserted by the WYSIWYG editor.
Example (here I am using RegExp.prototype.test() rather than RegExp.prototype.match())
const qEditor = document.querySelector('.ql-editor');
const re = /(?<!\\)"/gm;
qEditor.addEventListener('input', () => {
if (re.test(qEditor.innerText)){
window.alert('All double-quotes (") must be escaped (\\")');
}
})
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<div id="editor" class="ql-editor" data-gramm="false" contenteditable="true">
<p>text</p>
</div>
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<script>
var quill = new Quill('#editor', {
theme: 'snow'
});
</script>
I'm trying to create a small script that would wrap some parts of text from e.g. <p> tag like this one: <p>... 'displayed text'[popup content] ...</p> in a span wrapper.
The end result would look like this:
<span class='wrapper'>
displayed text
<span class='popup'>popup content</span>
</span>
At the moment I'm able to find and replace the text between apostrophes like this:
some_string.replace(/'(.*?)'/g,'<span>$1</span>');
But I would really like to wrap the popup content part first and then wrap it together with displayed text inside the wrapper element.
Would that be possible?
Sure - how about this?
some_string.replace(/'(.*?)'\[(.*?)\]/, "$1<span class='popup'>$2</span>");
Add a \s* between the two parts of the regex if they could be separated by whitespace:
/'(.*?)'\s*\[(.*?)\]/
I am getting below response from the API, and I want to convert it into proper html and would like to render it on dom, but it is rendering raw html and special characters.
example api response:
resp = {
body: "<p>Cali Thirty Seven turned what appeared to be certain defeat into an exhilarating and much-deserved victory late Saturday afternoon at Gulfstream Park. She reasserted herself after relinquishing the lead to 8-5 favorite Stormy Victoria to successfully defend her title in the $100,000 Powder Break Stakes.</p>\r\n<p>"
}
In the react component I am rendering it in the following way:
<p
className="newsDescription"
dangerouslySetInnerHTML={{ __html:this.props.story.desp }}
/>
I tried to escape html but it is not working.
You have to replace whatever html characters you have in your string to the corresponding tags. Since in your example you only have "<p> (which correspond to <p>) you can do this:
validate if this.props.story.desp has a value a is a string and then replace:
<span
className="newsDescription"
dangerouslySetInnerHTML={{ __html: this.props.story.desp.replace(/</g, '<').replace(/>/g, '>')}}
/>
This will generate a <span> element with a <p> element (the paragraph element coming from your API) inside the <span> with your text. Also, notice that this will replace all occurrences for creating the paragraph tags.
Unfortunately there is no generic vanilla javascript function for replacing all possible tags.
Note that I changed the <p> tag to a <span> because block elements should not have other block elements inside. Have a look at this question in SO.
I understand how (and why) to add a whitespace in JSX, but I am wondering what's best practice or if any makes any real difference?
Wrap both elements in a span
<div className="top-element-formatting">
<span>Hello </span>
<span className="second-word-formatting">World!</span>
</div>
Add them on one line
<div className="top-element-formatting">
Hello <span className="second-word-formatting">World!</span>
</div>
Add space with JS
<div className="top-element-formatting">
Hello {" "}
<span className="second-word-formatting">World!</span>
</div>
Because   causes you to have non-breaking spaces, you should only use it where necessary. In most cases, this will have unintended side effects.
Older versions of React, I believe all those before v14, would automatically insert <span> </span> when you had a newline inside of a tag.
While they no longer do this, that's a safe way to handle this in your own code. Unless you have styling that specifically targets span (bad practice in general), then this is the safest route.
Per your example, you can put them on a single line together as it's pretty short. In longer-line scenarios, this is how you should probably do it:
<div className="top-element-formatting">
Hello <span className="second-word-formatting">World!</span>
<span> </span>
So much more text in this box that it really needs to be on another line.
</div>
This method is also safe against auto-trimming text editors.
The other method is using {' '} which doesn't insert random HTML tags. This could be more useful when styling, highlighting elements, and removes clutter from the DOM. If you don't need backwards compatibility with React v14 or earlier, this should be your preferred method.
<div className="top-element-formatting">
Hello <span className="second-word-formatting">World!</span>
{' '}
So much more text in this box that it really needs to be on another line.
</div>
You can use the css property white-space and set it to pre-wrap to the enclosing div element.
div {
white-space: pre-wrap;
}
I tend to use
It's not pretty but it's the least confusing way to add whitespace I've found and it gives me absolute control over how much whitespace I add.
If I want to add 5 spaces:
Hello <span className="second-word-formatting">World!</span>
It's easy to identify exactly what I'm trying to do here when I come back to the code weeks later.
You can add simple white space with quotes sign: {" "}
Also you can use template literals, which allow to insert, embedd expressions (code inside curly braces):
`${2 * a + b}.?!=-` // Notice this sign " ` ",its not normal quotes.
You can use curly braces like expression with both double quotes and single quotes for space i.e.,
{" "} or {' '}
You can also use ES6 template literals i.e.,
` <li></li>` or ` ${value}`
You can also use   like below (inside span)
<span>sample text </span>
You can also use   in dangerouslySetInnerHTML when printing html content
<div dangerouslySetInnerHTML={{__html: 'sample html text: '}} />
I have been trying to think of a good convention to use when placing text next to components on different lines, and found a couple good options:
<p>
Hello {
<span>World</span>
}!
</p>
or
<p>
Hello {}
<span>World</span>
{} again!
</p>
Each of these produces clean html without additional or other extraneous markup. It creates fewer text nodes than using {' '}, and allows using of html entities where {' hello & goodbye '} does not.
You don't need to insert or wrap your extra-space with <span/>. Just use HTML entity code for space -
Insert regular space as HTML-entity
<form>
<div>Full name:</span>
<span>{this.props.fullName}</span>
</form>
use {} or {``} or to create space between span element and content.
<b> {notif.name} </b> <span id="value"> { notif.count }{``} </span>
Despite using this is a neat approach: using the <Fragment> tag to insert HTML inside a variable, which allows the creation of a custom spacer to be used in JSX.
Import { Fragment } ...
import { Fragment } from "react"
Create the variable..
const space = <Fragment> </Fragment>
Note: it can also be done with <span> instead of <Fragment>
Use like so..
return (
<div> some text here {space} and here... </div>
)
If the goal is to seperate two elements, you can use CSS like below:
A<span style={{paddingLeft: '20px'}}>B</span>
Why does a new line immediately following a <pre> tag not appear in the DOM?
<html>
<body>
<div id="mydiv">
hello
div
world
</div>
<pre id="mypre">
hello
pre
world
</pre>
<script>
alert("div content: "+document.getElementById("mydiv").innerHTML)
alert("pre content: "+document.getElementById("mypre").innerHTML)
</script>
</body>
</html>
Shows that unlike the line break after the div-tag the line break after the pre-tag doesn't seem to be in the dom. Also the innerHTML of the whole body doesn't show a line break after the pre-tag.
Is there any way to find out in JS if the original HTML document contains a line break after the <pre> or not?
Because that's what the spec says to do:
Note: In the HTML syntax, a leading newline character immediately following the pre element start tag is stripped.
So if you want that newline there, somewhat counter-intuitively you have to add an extra one: Example
<pre id="mypre">
hello
pre
world
</pre>
Side note: I strongly recommend always including a doctype, even in short examples like the one in your question. It can make a difference (although I don't think it does in this case).
From the specification of <pre>:
Note In the HTML syntax, a leading newline character immediately following the pre element start tag is stripped.
I think this is done so you don't have to write:
<pre>Some text
some more
and more
</pre>
to avoid an extra line break at the beginning. You can write:
<pre>
Some text
some more
and more
</pre>
This is useful if you're using <pre> to line up columns, since the first format doesn't allow you to line up the first line properly.
If you want an extra newline at the beginning of your preformatted text, put a blank line after the tag:
<pre id="mypre">
hello
pre
world
</pre>