How to append string in jQuery without quotes? - javascript

Let's say we have a paragraph:
<p>txt0</p>
... and we want to append some text:
$("p").append("_txt1");
$("p").append("_txt2");
$("p").append("_txt3");
The result will be, as expected:
txt0_txt1_txt2_txt3
However if we inspect the result in browser, what it really is:
<p>
"txt0"
"_txt1"
"_txt2"
"_txt3"
</p>
There are 4 different strings that are only rendered as one. The problem is I'm creating a flash object dynamically and appending strings this way will not work because of the quotes. I really need it to be one continuous string like this:
<p>
txt0_txt1_txt2_txt3
</p>
Is there a way to append in such a way? Or to remove all the quotes afterwards?
PS. before you say to make one big string before appending, that won't work because the string is too big and for ex. it works in Chrome but not in Firefox or IExplorer (but that's a different issue).

Use text, otherwise you're appending a new TextNode everytime:
var $p = $('p');
$p.text('txt0');
$p.text($p.text() + '_txt1');
Or with textContent it's less confusing:
var p = $('p')[0];
p.textContent += 'txt0';
p.textContent += '_txt1';
...

You can manipulate the html inside the p-tag this way:
$('p').html($('p').html() + '_text');

My solution is similar to #DonnyDee's
$("p").append("_txt1");
$("p").append("_txt2");
$("p").append("_txt3");
$("p").html($("p").html());
Somehow .html knows how to remove the quotation marks where there are two strings together i.e. "txt0"
"_txt1" etc
afaik .text() is destructive, i.e. will replace html with text which is perhaps not what we want, although I agree for this example it would suffice.
$('p').html(function(index, oldHTML) { return oldHTML + '_text';});
looks like a good solution though. e.g.
$("p").append("_txt1");
$("p").append("_txt2");
$("p").append("_txt3");
$("p").html(function(index, oldHTML) { return oldHTML);

Related

Markdown in JS without enclosing <p>?

How can I convert a piece of markdown text to HTML using any JS library like markdown-js or marked without enclosing it in paragraph tag?
For example I like to convert this *italic* text to this <i>italic</i> text without enclosing it in <p></p>.
Edit:
- My question is not how to remove p tags from output after conversion, my question is how to ask the library not to enclose output in p tags.
- markdown-js and marked enclose output inside <p></p> by default.
The marked library allows you to define your own renderer, which allows you to define the output for paragraphs.
You can pass in your own renderer by using:
marked.setOptions({
renderer: new MyRenderer(),
});
var output = marked('This **text** will be rendered with MyRenderer');
This will require you to define methods for blockquote, html, paragraph and all the other methods that the default marked.Renderer defines.
Here is an example:
function MyRenderer(options) {
this.options = options || {};
}
MyRenderer.prototype.paragraph = function(text) {
return 'This comes from my own renderer: ' + text + '\n';
};
However, this requires some efforts, so the quickest way to get rid of the paragraphs (<p> tags) is to change the code of the existing Renderer in the marked.js file:
Replace:
Renderer.prototype.paragraph = function(text) {
return '<p>' + text + '</p>\n';
};
With:
Renderer.prototype.paragraph = function(text) {
return text + '\n';
};
markdown-it has md.renderInline() method which allows to do that.
I got around this by using a regex on the result:
rawMarkup.replace(/^(?:<p>)?(.*?)(?:<\/p>)?$/, "$1")
This will however only work on simple cases, and will fail in cases where there are two adjacent paragraphs, and possibly others.
After some testing I realized that there is a good reason why there are paragraph tags around the text, and that my implementation will have to adapt.
I'm way late to the game on this question, but I had the exact same problem last night, and I opened up marked in order to build a solution to this issue.
I need to be able (for my i18n translation CMS) to embed tags inside any kind of tag, like headers, and have them render from Markdown without the enclosing <p> tag. So this fix makes it so that if there is only one line of text in my source (which for me is JSON), then it will not wrap in <p> tags. But if there is more, it will wrap them all in tags as normal.
Here is my pull request for the change
https://github.com/chjj/marked/pull/841
I highly doubt it will be included, but I am using it in my project and it works wonderfully.
Here's what worked for me (many years later). It assumes that you know what elements you don't want to wrap in paragraph tags.
const marked = require("marked");
// Every new line in markdown is considered a new paragraph, this prevents
// img tags from being wrapped in <p> tags which is helpful for resizing img's,
// centering captions, etc.
marked.Renderer.prototype.paragraph = (text) => {
if (text.startsWith("<img")) {
return text + "\n";
}
return "<p>" + text + "</p>";
};
html = marked(markdownFile.body)

Split a sentence with HTML into words (but leave inline HTML intact)

I am looking for a way to use javascript for splitting a sentence with HTML into words, and leaving the inline HTML tags with the text content intact. Punctuation can be regarded as a part of the word it is closest to. I'd like to use regex, and probably preg_split() for splitting the sentences. Here follows an example:
A word, <a href='#' title=''>words within tags should remain intact</a>, so here's
<b>even more</b> <u>words</u>
Preferably, I would like to end up with the following:
[0] => A
[1] => word,
[2] => <a href='#' title=''>words within tags should remain intact</a>,
[3] => so
[4] => here's
[5] => <b>even more</b>
[6] => <u>words</u>
I know about the discussion on parsing HTML with Regex (I enjoyed reading Bobince' answer :-P ), but I need to split the words of a sentence without harming html-tags with attributes. I don't see how I can do this with JS in a different way than Regex. Of course, if there are alternatives, I'd be more than happy to adapt them, to achieve a similar result. :-)
Edit:
I searched for similar questions on Stackoverflow about this, but these don't tick the boxes for me. To put it a little into perspective:
splitting-up-html-code-tags-and-content: targets to split up the inline HTML, which is what I want to leave intact.
php-regex-to-match-outside-of-html-tags: targets all text nodes in a HTML snippet, even within HTML tags. But as a matter of fact, I want to target only the spaces outside of HTML elements (so even excluding the spaces within the text nodes being wrapped with HTML tags).
This is possible, but there will be some drawbacks to using a pure regex solution. The easiest to call out is nested HTML. The solution I'm about to show uses some back referencing to try get around this, but if you get some complicated nested HTML it will probably start failing in weird ways.
/(?:<(\w+)[^>]*>(?:[\w+]+(?:(?!<).*?)<\/\1>?)[^\s\w]?|[^\s]+)/g
Regex Demo
The regex uses back referencing and negative look behinds to get the work. You could potentially remove the back reference depending on your requirements. The back referencing helps with supporting nested tags.
JSFiddler Example - Check your console output for the example.
Here's the output from JS Fiddler (I formatted the output a bit)
[
"A",
"word,",
"<a href='#' title=''>words within tags should remain intact</a>,",
"so",
"here's",
"<b>even more</b>",
"<u>words</u>"
]
Depending on you're use case you'll need to modify it to work for you. I considered a word anything that wasn't a space, but you may have different criteria.
One negative to this method is if the start HTML tag is at the end of a word, it won't be picked up properly. ie. test<span>something else</span>.
You can use the following snippet:
function splitIntoWords(div) {
function removeEmptyStrings(k) {
return k !== '';
}
var rWordBoundary = /[\s\n\t]+/; // Includes space, newline, tab
var output = [];
for (var i = 0; i < div.childNodes.length; ++i) { // Iterate through all nodes
var node = div.childNodes[i];
if (node.nodeType === Node.TEXT_NODE) { // The child is a text node
var words = node.nodeValue.split(rWordBoundary).filter(removeEmptyStrings);
if (words.length) {
output.push.apply(output, words);
}
} else if (node.nodeType === Node.COMMENT_NODE) {
// What to do here? You can do what you want
} else {
output.push(node.outerHTML);
}
}
return output;
}
window.onload = function() {
var div = document.querySelector("div");
document.querySelector("pre").innerText = 'Output: ' + JSON.stringify(splitIntoWords(div));
}
<!-- Note you have to surround your html with a div element -->
<div>A word, <a href='#' title=''>words within tags should remain intact</a>, so here's
<b>even more</b> <u>words</u>
</div>
<pre></pre>
It iterates through all child nodes, takes the text nodes and splits them into words (you can do this safely since text nodes can't contain children).
This takes care of most issues. With this, HTML such as text<span>Test</span> will come out ["text", "<span>Test</span>"] unlike the answer above.
This may fail with <span>There are</span>: 4 words which results in ["<span>There are</span>", ":" /* Extra colon */, "4", "words"] (which it's supposed to do, but not sure if it is desirable).
I would think this is very safe with nested elements.

How to insert HTML entities with createTextNode?

If I want to add an ascii symbol form js to a node somewhere?
Tried as a TextNode, but it didn't parse it as a code:
var dropdownTriggerText = document.createTextNode('blabla ∧');
You can't create nodes with HTML entities. Your alternatives would be to use unicode values
var dropdownTriggerText = document.createTextNode('blabla \u0026');
or set innerHTML of the element. You can of course directly input &...
createTextNode is supposed to take any text input and insert it into the DOM exactly like it is. This makes it impossible to insert for example HTML elements, and HTML entities. It’s actually a feature, so you don’t need to escape these first. Instead you just operate on the DOM to insert text nodes.
So, you can actually just use the & symbol directly:
var dropdownTriggerText = document.createTextNode('blabla &');
I couldn't find an automated way to do this. So I made a function.
// render HTML as text for inserting into text nodes
function renderHTML(txt) {
var tmpDiv = document.createElement("div"); tmpDiv.innerHTML = txt;
return tmpDiv.innerText || tmpDiv.textContent || txt;
}

How to get all spans in string variable, with particular class name

as i am getting tough time to list out all spans, which having class="ansspans", may be one or more span with "ansspans" classes will be there, i need to get all the spans with its content and iterate through it. can you tell me how to do it, Regex, Jquery, any thing ok,
The content will be in string variable (not in DOM), as IE 9 ignoring quotes from attribute, so i cant use getelementbyclass name,and i followed this answer, to get quotes InnerHTml workAround, now its displaying with quotes. so i need get all the class of ansspans, in an array, so that i'll iterate it n get the text content of each span
<span id="sss_ctl00_ctl06_lblanswertext">
assignment
<span class="ansspans">submission </span>
date : 10:07:51 AM
</span>
in this eg, expected output will be 1 span object, so that i can iterate over it
Update : I cant use DOm, as we are in quirks mode, so ie 9 will ignore attribute quotes, which i cant traverse using getelement by class name, . so , i need to match all spans in a string variable. hope everyone understood my problem ;(
(as been said on this site before, sometimes it's ok to parse a limited, known set of xml with regex)
//assumes no <span id="stupid>" class="ansspans">, and no embedded span.ansspans
var data = ' <span id="sss_ctl00_ctl06_lblanswertext"> assignment \n date : 10:07:51 AM \n <span class="ansspans">ONE has a new \n line in it</span><span class="ansspans">TWO</span><span class="ansspans">3 </span><span class="ansspans">4 </span><span class="ansspans">5 </span>';
var myregexp = /<span[^>]+?class="ansspans".*?>([\s\S]*?)<\/span>/g;
var match = myregexp.exec(data);
var result = "spans found:\n";
while (match != null) {
result += "match:"+RegExp.$1 + ',\n';
match = myregexp.exec(data);
}
alert(result);
(edited to capture inner html instead of whole tag)
The following jQuery selector $('span.ansspans') will get all the <span class="anspans"> for the page.
If you need something for a specific element, add a prefix of the appropriate selector, i.e. $('#sss_ctl00_ctl06_lblanswertext span.ansspans')
If this needs to be done in a more dynamic way - look into functions like find(), filter(), etc.
solution using jquery
var tempArray = $("span.ansspans");//this will select all the span elements having class 'ansspans' and return them in an array
var len = tempArray.length;//calculate the length of the array
for(var index = 0;index<len;index++){
var reqString = $(tempArray[index]).html();
}
These string values can be either put inside an array or can be utilised then and there only.
If you want textContent, use .text() instead of .html()

find text wrapped in brackets in jQuery

I have some text on a page and I want to located and remove any text found in brackets.
For example:
<td>here is [my text] that I want to look at</td>
So I want to grab that text (my text), save it in a variable and remove it from where it is.
If you're using jQuery you could use a regular expression like \[(.+)\] on $('body').text().
EDIT: Sorry, I might have jumped the gun a little bit giving you this answer. Going to think about it for a few more minutes and try to update this with a little more info.
You may find that this task is not all that simple. If you have control over the text before it is sent to the web browser you may want to put a <span class='bracket'>[my text]</span> around the text, then you could easily do something like this with jQuery:
$(".bracket").each(function() {
// store the data from $(this).text();
}).remove();
This can be done using regular expressions and jQuery, but there are problems that may creep up dealing with text inside of attributes like <input name='test[one][]' /> The "simple" regex would be to do something like this:
$("td").each(function() {
var $this = $(this);
var html = $this.html();
var bracketText = [];
// match all bracketed text in the html - replace with an empty string
// but push the text on to the array.
html = html.replace(/\[([^\]]+)\]/g, function() {
bracketText.push(arguments[1]);
return "";
});
// put the new html in away and save the data for later
$this.html(html).data("bracketText", bracketText);
});
There is not much danger in doing this if you're sure you wont have [] inside of tags other than in the text.
I ended up doing the following:
$('#formQuizAnswers td.question').each(function(){
var header = $(this).text().match(/-.*-/);
$(this).text($(this).text().replace(header,''));
});
I changed my text I search for to have dashes around it IE -My text-

Categories

Resources