Does something similar to gsub exist in javascript? - javascript

Is there any way to to do something similar to ruby gsub in javascript? I have a local html file that I want to process and replace certain template variables with content but I cannot figure out how to substitute out the template variables with the new content. The html contains fragments like below:
<div id="content">
<h1>{{title}}</h1>
{{content}}
</div>
Now if I wrap every template variables in a named div then I can use something like jquery's replaceAll method to replace the template variable with its content but I cant figure out how to do it without wrapping every variable in a div.
I just want to do something like $('document').gsub("{{title}}", "I am a title").
Anyone have any ideas?
Thanks for your help!

If others were looking for an equivalent to gsub in general, this only replaces the first match:
"aa".replace("a", "b") // "ba"
//g replaces all matches:
"aa".replace(/a/g, "b") // "bb"
"aa".replace(new RegExp("a", "g"), "b"); // "bb"

You can access the raw HTML via a DOM element's innerHTML property, or using JQuery's html property wrapping it, and then perform the substitution:
var html = $(document).html();
$(document).html(html.replace('{{title}}', 'I am a title');
EDIT:
As pointed out by Antti Haapala, replacing the entire document HTML can have side-effects you don't want to deal with, like scripts being reloaded. Thus, you should drill down to the most specific DOM element possible before performing the substitution, i.e.:
var element = $('#content');
var html = element.html();
element.html(html.replace('{{title}}', 'I am a title');

Well, you can use String.replace with a regex, but really, what you could use are jQuery Templates.
http://api.jquery.com/category/plugins/templates/

I recently used Handlebars to take a data attribute (template) from a table and inject another value (record id) from one of its rows:
// data-row-url="http://example.com/people/{{id}}"
var table = $(this).closest('.data_grid table');
if(table.attr('data-row-url')) {
var record_id = $(this).data('record-id')
var show_url_template = table.data('row-url');
var url_template = Handlebars.compile(show_url_template)
var url = url_template({ id: record_id });
$.getScript(url);
}
For context this code runs from inside an onclick event for the table's tr elements and fetches the clicked record via ajax.

I believe that might be a mustache template. You might want to check mustache.js. I think you might be able to compile that to JS.

Related

apple .replace() Html element generate by handlebar js

I am wondering if how am i able to change the element data by .replace() if i use handlebar js to generate html elements.
For instance i have this role of p tag which display a row of data by handlebar js:
<p id="pre-region">{{region}}</p>
and the result of it is
1,44
and i 'd like to change it to
1+44
If you haven't had any experience of handlebar js then consider the tag be
<p id="pre-region">1,44</p>
how should i change from 1,44 to 1 +44?
UPDATE 1
Here should be an extersion for my question. I am passing the HTML element inside pre-region into an href in order to update my website by Ajax.
After i have converted all the comma in to "+" the API retrieve special character "&B2" which equal to the symbol "+" and the API goes error.
MYDOMAIN/path/getRegion?token&profileId=111&dataType=all&region=1%2B4
This is how may API looks like at the moment
MYDOMAIN/path/getRegion?token&profileId=111&dataType=all&region=1+4
should be the solution
I haven't had any experience of handlebars.js but from my point of view, you can just put the code just before the </body>:
<script>
var node = document.getElementById('pre-region');
node.innerHTML = node.innerHTML.replace(',', '+');
</script>
I'll check out the handlebars js in case it does not work.
Update:
As you mentioned in the comment, if you need to use it in the HTTP request/URL, you may handle the string using decodeURIComponent(yourstring):
decodeURIComponent('1%2B44'); // you get '1+44'
Read more about decodeURIComponent() method from this. In URL, it should be encoded as region=1%2B44 in your case; while it should be decoded if you want to use it in your JavaScript code or display in the web page.
Update 1
You should encode your string when it's used as a part of parameter of HTTP request. Therefore, it looks good if the URL is:
MYDOMAIN/path/getRegion?token&profileId=111&dataType=all&region=1%2B4
What you need to do is decode the string on your server side. I assume that you are in control of the server side. If you are using Node.js, you can just use decodeURIComponent() method to decode the parameter. If you're using Python or PHP as your server language, it should be something like decodeURIComponent() in that language.
Update 2
The solution above only replace the first occasion of comma to +. To solve that, simply use:
<script>
var node = document.getElementById('pre-region');
node.innerHTML = node.innerHTML.replace(/,/g, '+');
// Regular Expression is used here, 'g' for global search.
</script>
PHP has a replaceAll() method, so we can add that method to String.prototype like below if you want:
<script>
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
}
// Another method to replace all occasions using `split` and `join`.
</script>
Alright, so this is my first answer ever on stack overflow so I'm alien to this whole thing but here we go:
You could try this code in another js file that runs after handlebars:
var pre = $('#pre-region'); // defines a variabe for the element (same as
// document.getElementById('pre-region'))
var retrievedRegion = pre.innerHTML;
var splitten = retrievedRegion.split(',');
var concatenated = parseInt(split[0]) + parseInt(split[1])
retrievedRegion.innerHTML = "'" + concatenated) + "'";
or using replace():
retrievedRegion.replace(',','+')

Remove HTML tags and entites from string coming from server

In an app I receive some HTML text: since the app can't display (interpret) HTML, I need to remove any HTML tag and entity from the string I receive from the server.
I tried the following, but this one removes HTML tags but not entities (eg. &bnsp;):
stringFromServer.replace(/(<([^>]+)>)/ig,"");
Any help is appreciated.
Disclaimer: I need a pure JavaScript solution (no JQuery, Underscore, etc.).
[UPDATE] I'm reading all your answers now and I forgot to mention that I'm using JavaScript BUT the environment is not a web page, so I have no DOM.
You can try something like this:
var placeholder = document.createElement('div');
placeholder.innerHTML = stringFromServer;
var theText = placeholder.innerText;
.innerText only grabs text content from the element.
However, since it appears you don't have access to any DOM manipulation at all, you're probably going to have to use some kind of HTML parser, like these:
https://www.npmjs.org/package/htmlparser
http://ejohn.org/blog/pure-javascript-html-parser/
A solution without using regexes or phantom divs can be found on Mozilla's MDN.
I put the code in a JSfiddle here:
var sMyString = "<a id=\"a\"><b id=\"b\">hey!<\/b><\/a>";
var oParser = new DOMParser();
var oDOM = oParser.parseFromString(sMyString, "text/xml");
// print the name of the root element or error message
alert(oDOM.documentElement.nodeName == "parsererror" ?
"error while parsing" : oDOM.documentElement.textContent);
Alternatively, parse the HTML snippet in a new document and do your dom manipulations from that (if you'd rather keep it separate from the current document):
var tmpDoc=document.implementation.createHTMLDocument("");
tmpDoc.body.innerHTML="<a href='#'>some text</a><p style=''> more text</p>";
tmpDoc.body.textContent;
tmpDoc.body.textContent evaluates to:
some text more text
stringFromServer.replace(/(<([^>]+)>|&[^;]+;)/ig, "")

Unable to remove html tags from response JSON

Hi I am new to AngularJS. I am having a problem parsing JSON data to proper format. Actually the JSON response itself returned HTML format data (it contains HTML tags like &lt,;BR,> etc). If I check the response in browser it returns fine, but in device(TAB,MOBILE) the HTML tags are also getting appended. I am using AngularJS to bind the JSON response to DOM. Is there any way to simply ignore HTML tags in JQuery or in AngularJs? At the same time I don't want to remove the HTML tags as they are necessary to define "new line", "space", "table tag" etc.
A sample response I am getting is like:
A heavier weight, stretchy, wrinkle resistant fabric.<BR><BR>Fabric Content:<BR>100% Polyester<BR><BR>Wash Care:<BR>
If I apply the binding using {{pdp.desc}}, the HTML tags are also getting added. Is there any way to accomplish this?
I have added ng-bind-html-unsafe="pdp.desc", but still "BR" tags r coming.
useless html tags can be remove using regix expression, try this
str.replace(/<\/?[^>]+>/gi, '')
Try to use three pairs of brackets {{{pdp.desc}}} In Handlebars it works, possible in your case to.
Use JS HTML parser
var pattern = #"<(img|a)[^>]*>(?<content>[^<]*)<";
var regex = new Regex(pattern);
var m = regex.Match(sSummary);
if ( m.Success ) {
sResult = m.Groups["content"].Value;
courtesy stackoverflow.

JS - Stripping tags while preserving line breaks works with DOM object, but not html in a variable

I'm trying to create a function in javascript (or jQuery) that will take a variable filled with html and output a plain text version. The function needs to strip the html tags and insert line breaks at the end of heading and paragraph tags.
I've been going round in circles for ages with this. There are lots of examples of how to take a DOM object, e.g. document.body.innerHTML and remove the tags. However, I'm using a variable filled with html and the results are not the same.
This is the supposed duplicate solution: http://jsfiddle.net/8JSZX/. However, create an html variable and use that and you get: http://jsfiddle.net/JjXXY/ - which does not preserve the line breaks.
The html variable would be something like:
var html = '<h1>This is a heading</h1><p>This is a paragraph</p><p>This is another paragraph</p>'
If there is a better solution to this I'm open to suggestions!
Gave it a shot:
var html_string = '<h1>Test</h1><p>A paragraph with a link</p>';
var regex = /<(\/?)[a-zA-Z0-9][^>]*>/g;
var stripped = html_string.replace(regex, '');
$("#result").html(stripped);
See: http://jsfiddle.net/Y6q2j/5/

Best way to pick up text in a HTML element that is in the parent node only

I have, for example, markup like this
<div id="content">
<p>Here is some wonderful text, and here is a link. All links should have a `href` attribute.</p>
</div>
Now I want to be able to perform some regex replace on the text inside the p element, but not in any HTML, i.e. be able to match the href within backticks, but not inside the anchor element.
I thought about regex, but as the general consensus is, I shouldn't be using them to parse HTML.
My current method of doing this is like so: I've got a bunch of words in an array, and I am looping through them and making an object of data like so:
termsData[term] = {
regex: new RegExp('(\\b' + term + '\\b)', 'gmi'),
replaceWith: '<span>{TERM}</span>'
};
I then loop through it again, making the replacements like so:
var html = obj.html();
$.each(terms, function(i, term) {
// Replace each word in the HTML with the span
html = html.replace(termsData[term].regex, termsData[term].replaceWith.replace(/{TERM}/, '$1'));
});
obj.html(html);
Now I did a lot of this last night at an ungodly hour, and copying and pasting it into here seems to make think I should refactor some of this.
So from you should be able to tell, I want to be able to replace plain text, but not anything inside a HTML tag.
What would be the best way to do it?
Note: The source code is coming from here if you'd like a better look.
You're right to not want to be processing HTML with regex. It's also bad news to be assigning huge chunks of .html(); apart from the performance drawbacks of serialising and reparsing a large amount of HTML, you'll also lose unserialisable data like event listeners, form data and JS properties/references.
See the findText function in this answer and call something like (assuming obj is a jQuery wrapper over your topmost node to search in):
findText(obj[0], /\b(term1|term2|term3)\b/g, function(node, match) {
var span= document.createElement('span');
node.splitText(match.index+match[0].length);
span.appendChild(node.splitText(match.index));
node.parentNode.insertBefore(span, node.nextSibling);
});

Categories