Changing HTML with spans and symbols in Javascript [duplicate] - javascript

This question already has answers here:
Double quote in JavaScript string
(4 answers)
Escape quotes in JavaScript
(13 answers)
Closed 1 year ago.
I have some HTML and when a function is called, I want to change to text in a div that uses span. The idea is to be a sort of customized alert. I'm trying to use .innerHTML, but what I want to change has both quotations and span. Is there a way that I can get this to update?
Current HTML:
<div id="messageBox" class="messageBox">
<div id="picture"></div>
<div id="messageArea">"I need to update this <span class="keyWord">code</span> and keep the
quotations and keywords!"
</div>
</div>
This shows a box with a picture and
"I need to update this code and keep the quotations and the
keywords!"
The current javascript that I have is:
alertChange = document.getElementById("messageArea");
alertChange.innerHTML = ""This <span class="keyWord">code</span> needs to change!"";
It won't allow me to add the extra quotations or the span element.
The resulting text should be
"This code needs to change!"

Method 1 - Backslash escape
Escape the double quotes within your HTML string with the backslash \ character:
alertChange = document.getElementById("messageArea");
alertChange.innerHTML = "\"This <span class=\"keyWord\">code</span> needs to change!\"";
<div id="messageBox" class="messageBox">
<div id="picture"></div>
<div id="messageArea">"I need to update this <span class="keyWord">code</span> and keep the
quotations and keywords!"
</div>
</div>
Further reading: String - JavaScript | MDN#Escape Notation
Method 2 - Using template strings
Declare your string as a template literal by encapsulating it in backtick characters:
alertChange = document.getElementById("messageArea");
alertChange.innerHTML = `"This <span class="keyWord">code</span> needs to change!"`;
<div id="messageBox" class="messageBox">
<div id="picture"></div>
<div id="messageArea">"I need to update this <span class="keyWord">code</span> and keep the
quotations and keywords!"
</div>
</div>
Further reading: Template literals (Template strings) - JavaScript | MDN
Method 3 - Single quote (') encapsulation
In this specific case, since you haven't used single quotes anywhere in your string, you can simply declare the HTML string by encapsulating it in single quote characters. Be forewarned that this will break if for whatever reason your text changes to include a single quote, which would then force you to escape them as detailed in Method 1.
alertChange = document.getElementById("messageArea");
alertChange.innerHTML = '"This <span class="keyWord">code</span> needs to change!"';
<div id="messageBox" class="messageBox">
<div id="picture"></div>
<div id="messageArea">"I need to update this <span class="keyWord">code</span> and keep the
quotations and keywords!"
</div>
</div>

You need to use the Backslash \ to "escape" the special character (in your case the double quote symbol) like this
alertChange.innerHTML = "\"This <span class=\"keyWord\">code</span> needs to change!\"";

Related

Regular Expression

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>

Mustache.js splits HTML attibuts between whitespaces

Mustache.js splits an HTML attribut between many HTML attributs between whitespaces. How can I keep the attribut as it is ?
The Object to render (width contains whitespaces)
cardpool = {
width:"col-md-offset-3 col-md-6 col-sm-4"
}
The template to use
<div class={{width}}>
</div>
The wrong result (Mustache.js splits the attributs between the whitespaces) :
<div class="col-md-offset-3" col-md-6="" col-sm-4="">
</div>
The expected result (I want to keep the whitespaces in the attribut)
<div class="col-md-offset-3 col-md-6 col-sm-4">
</div>
Do you have a solution to get the expected result ?
Thank you for your help.
This isn't Mustache's fault. Your template is rendered to this:
<div class=col-md-offset-3 col-md-6 col-sm-4>
</div>
Notice the lack of any quotation marks around your class names. A browser can internally convert this to what you're seeing (I'm guessing that you are inspecting the generated data inside your browser's dev tools).
Your template should include the quotation marks around the variable if you want to group the class names into a single class attribute value:
<div class="{{width}}">
</div>
Mustache is (mostly) agnostic about the context in which it's used, so it doesn't know that attributes in HTML should be surrounded by quotation marks if the values contain whitespace. Hence, you need to add those yourself.
Try with the triple mustache: {{{width}}}. This prevents HTML escaping, which it does if used as {{width}}.
Not familiar Mustache.js, but ejs for example works like this :
<div class="<%= preRendData.class %>"></div>
So try your code with quotes :
<div class="{{width}}">

JS RegEx to match all characters (including newline) between two strings but without the two strings?

Example Text:
<div id="not-wanted">
no no
no
</div>
<div id="wanted">I want
only this
text
</div> no no no
no no
<div id="not-wanted">
no no no
</div>
<div id="wanted">no no
no no</div>
<div id="wanted">
no no
</div>
Should deliver:
I want
only this
text
Or better:
I want only this text
Unfortunately, my solution catches the 2 delimitation strings also:
$('#put').append(/<div id="wanted">[^<>]*<\/div>/.exec(strg)[0]);
==>
<div id="wanted">I want
only this
text
</div>
Online example
http://regex101.com/r/rF7jR9
Question
What regular expression for Java Script can deliver the characters between delimiting strings, if there are also \n and \r resend. It would be nice, if \n and \r are removed from the delivered string. The RegExpr should work fast.
Now I know how to:
$('#put').append(/<div id="wanted">([\s\S]*?)<\/div>/.exec(strg)[1]);
Thank you Jerry for the (group) hint. [\s\S] stands for every character. *? stop after first found <\/div>.
You can use a capture group and ignore the full match?
$('#put').append(/<div id="wanted">([^<>]*)<\/div>/.exec(strg)[1]);
^------^ ^
( ... ) is a capture group and since it's the first one in the regex, it gets to the first capture group, hence the 1 near the end.

Appending large block of html with append()

Im trying to append a large block of text using jquery's append().
$('#add_contact_btn').click(function(event) {
event.preventDefault();
var large = '<div class="accordian_container"><h4>Co-Borrower Information</h4><hr/><div class="accordian_item" id="accord_item_2"><label> First Name</label><br/><input type="text"/><br/><label>Middle Name</label><br/>
<input type="text"/><br/>
<label>Last Name</label><br/>
<input type="text" /><br/>
<label>Home Number</label><br/>
<input type="text"/><br>
<label>Work Number</label><br/>
<input type="text"/><br>
<label>Cell Number</label><br/>
<input type="text"/><br>
</div>
</div>';
$('#accordion_container').append(large);
});
It doesn't seem to be working and after looking at the documentation for append(), I can't figure out why - any ideas? Is it the large amount of HTML that I am trying to append?
Modern Answer
As ES6 (and beyond) becomes more common, and as more and more people transpile from ES6, we are more and more able to use template literals, which can be used as multiline strings:
var myString = `<p>Line One</p>
<p>Line Two</p>
<p>Line Three</p>`;
Original 2012 Answer (ES5)
Javascript does not have multiline strings in the way you are writing them, you can't just open a string on one line, go down a few lines and then close it. (there are some ways of doing multi-line strings in JS, but they are kind of backwards).
How most people do it is something like this:
var myString = '<p>Line One</p>' +
'<p>Line Two</p>' +
'<p>Line Three</p>';
You could create a template in HTML that is hidden, then append its content HTML. For example:
<div class="hide" id="template">
<b>Some HTML</b>
</div>
jQuery:
$("#container").append($("#template").html());
Putting HTML in a JavaScript string is harder to read and search for, is error prone and your IDE will struggle to format it properly.
Update 2019
Check out the template tag, which was created for this purpose: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
The template tag is even allowed to contain what would be invalid HTML elsewhere, e.g. a td tag outside a table.
Remove the line breaks.
http://jsfiddle.net/DmERt/
var large = '<div class="accordian_container"><h4>Co-Borrower Information</h4><hr/><div class="accordian_item" id="accord_item_2"><label> First Name</label><br/><input type="text"/><br/><label>Middle Name</label><br/><input type="text"/><br/><label>Last Name</label><br/><input type="text" /><br/><label>Home Number</label><br/><input type="text"/><br><label>Work Number</label><br/><input type="text"/><br><label>Cell Number</label><br/><input type="text"/><br></div></div>';
$('#accordion_container').append(large);​
It's my understanding that if you want to put your long string on multiple lines that it's more efficient to use an array of strings and join them.
var bigString = [
'some long text here',
'more long text here',
'...'
];
$('#accordion_container').append(bigString.join(''));
You can use a backslash at the end of each line.
http://davidwalsh.name/multiline-javascript-strings
var multiStr = "This is the first line \
This is the second line \
This is more...";
Another alternative is Template literals with back-ticks:
var large = `some long text here
some long text here
some long text here`;
It's a fairly new syntax and not supported in IE though.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Use Template literals Template literals are literals delimited with backticks (`), allowing embedded expressions called substitution
var test = `<div class="question-content"> <p> ${mydata.commented.comment}</p></div> <div class="about-info">
<div class="count-section">
<button id="clike-button" value={{comment.id}}><i class="fas fa-arrow-up"></i></button>
<h3 id="clike_count">{{ question.clike_count }}</h3>
<button id="cdislike-button" value={{comment.id}}><i class="fas fa-arrow-down"></i></button>
</div>
<div class="user-profile">
<img src="{% static 'img/profile-pic.png' %}" alt="">
<div class="user-info">
<p> ${mydata.user}</p>
<p class="user-badge">
<p class="user-badge"> <span style="padding-left: 2px;">13.1k</span><i
class="fas fa-circle gold"></i> <span> 2</span> <i class="fas fa-circle silver"></i>
<span>
7</span> <i class="fas fa-circle bronze"></i> <span>56</span>
</p>
</div>
</div></div> `;
$("#commentlist").append(test)
https://i.stack.imgur.com/5BZHB.png
Javascript have the option to extend multiple lines/HTML section into a single line, for each line of HTML row add backslash() to identify that its continue line.
Note :-The only thing to consider while append lines are the single quote and double quote. If you start with the single quote, then use double quote in the internal string or vice-versa, otherwise, line is break and do not get the proper result.
$(element).append('<div class="content"><div class="left"></div><div class="right"></div></div>');
Javascript syntax
var str = ' <div class="content"> \
<div class="left"> \
</div> \
<div class="right"> \
</div> \
</div> ';
document.getElementsByName(str).html(str);
//or
document.getElementsById(str).html(str);
Jquery syntax
$(element).append(' \
<div class="content"> \
<div class="left"> \
</div> \
<div class="right"> \
</div> \
</div> \
');
Or
you can use a html template for this as mention in 3rd link via jquery
$("#div").load("/html_template.html");
http://www.no-margin-for-errors.com/blog/2010/06/17/javascript-tip-of-the-day-extending-a-string-across-multiple-lines/
Appending multiple html elements using Jquery
spread html in multiple lines javascript
By default, the HTML code containing wraps cannot be used with append/prependdirectly use 'or". However currently there are following methods to do that:
Use "+" to join HTML code pieces.
Use "\" to escape.
Use "`" (back-tick, grave accent), do not need any extra operations.
This method is supported from ES2015/ES6 (Template literals).
Add a hidden tag containing the same HTML code you need, e.g. <p id="foo" style="display:none;">, then use.append($('#foo').html());.
Now post some use scenarios to the first three methods metioned above (just run them in the console of Chrome browser.):
We can see their differences clearly.
You can also clone the div with jQuery and then append the clone--way less messy.
var accordionClone = $('.accordion_container').clone();
$('#accordion_container').append(accordionClone);
just add like this $(#element).append(large_html),large_html in special character(``) and thank me later.
If line-breaks are an issue just use innerHTML, works in every browser since IE5:
$('#accordion_container')[0].innerHTML += large;​
Or, for collections:
$('.accordion_container').forEach(function () {
this.innerHTML += large;​
});

How to concatenate strings in JavaScript with tabs and carriage returns in Geany?

I'm making an app with dynamic content loader, it's load the content via ajax then change the DOM. I have a structure/schema, my question is how can I to concatenate the strings, I want to keep my code "indentated" for make it easly readable...
Example:
How can I achieve that? I need some special scape character or sort of?
You can escape the newline character at the end of each line with a \, though it's generally considered bad practice (because it's very easy to miss an escape in maintaining the code.)
var page = '\
<div class="row well">\
<div class="row info-block">\
<div class="col-xs-4 logo-container">\
' + logo + '\
</div>\
</div>\
</div>';
What you really want is ES6 template strings, though:
var page = `
<div class="row well">
<div class="row info-block">
<div class="col-xs-4 logo-container">
${logo}
</div>
</div>
</div>`;
Template strings allow multiline strings by default and support interpolation (the ${logo} above.)
Note: there is a difference between the two resulting strings. In the newline-escaped string, the newlines are actually not a part of the resulting string; whereas, they are in the template string example.

Categories

Resources