Parse html string and delete some elements - javascript

I have a html string and I need to remove all between first occurrence of <div class="c and first close tag > and last closing tag "</div>". The first, should be this because it class is dynamically generated.
For example: <div class="c2029" style="font-size:45px"><p class="auto">Testing 123...</p></div> should be transformed to <p class="auto">Testing 123...</p>
I tried this, but it's removing all string:
var testString = '<div class="c2029" style="font-size:45px"><p class="auto">Testing 123...</p></div>'
var result = testString.replace(/\<div\_c.*\>/, '');
The content into div that should be removed is dynamically generated, it is an example.
More examples of dynamic string generated:
var testString = '<div class="c03"><div style="text-align: center">Testing 123...</div></div>';
var testString = '<div class="c435">Hello</div>';
var testString = '<div class="c1980">TEST</div>';

No need to use regular expressions, you can achieve this with jQuery's $.fn.unwrap:
$('[class^="c"]').children().unwrap()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="c2029" style="font-size:45px">
<p class="auto">Testing 123...</p>
</div>
To make it more bullet proof and target only element with class staring with "c" and with numbers after you could add additional filtering step:
$('[class^="c"]').filter(function () {
return this.className.match(/\bc\d+\b/)
}).children().unwrap()
This way it will not affect classes like cello (starts with "c").

Regex is wrong tool for this. You can just $.parseHTML() and then find() using [name^=”value”] selector and use it:
var all = ['<div><div class="c2029" style="font-size:45px"><p class="auto">Testing 123...</p></div></div>', '<div><div class="c435">Hello</div></div>', '<div><div class="c1980">TEST</div></div>'];
$.each(all, function(k,s) { f(s); });
function f(s) {
var nodes = $($.parseHTML(s)); // parse string to jquery object
var $p = nodes.find('div[class^="c"]'); // select all classes that starts with c
var inner = $p.prop('innerHTML'); // inner html of $p
console.log("Inner: " + inner);
$p.html(''); // select children of $p and remove
var outer = $p.prop('outerHTML'); // outer html of $p
console.log("Outer: " + outer);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Based on Stack Overflow answers, I found this solution that resolve my problem:
var testString = '<div class="c2029" style="font-size:45px"><p class="auto">Testing 123...</p></div>'
var result = testString.replace(/<div class="c.*?>(.*?)<\/div>/, '$1');
document.write(result);
console.log(result);

Related

How to make a word count that contains html tags using javascript?

Hi I would like to do a Word Count in my RTE (Rich Text Editor) with javascript can also use with jquery. But it should not count the html tags and repeating white spaces.
Sample Text:
<p>11 22 33</p><p>44</p>5<br></div>
The javascript should display 5 only.
Is there any javascript code for this and that is also fast to calculate the Word Count?
Thanks!
Try something like this:
You get the html in the div then you remove all tags and replace them with spaces. You remove (trim) all left and right spaces and finally you split the string into an array. The length is your answer.
var cont = $("#content").html();
cont = cont.replace(/<[^>]*>/g," ");
cont = cont.replace(/\s+/g, ' ');
cont = cont.trim();
var n = cont.split(" ").length
alert(n);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content">
<p>11 22 33</p><p>44</p>5<br></div>
var words = [];
function getWords(elements) {
elements.contents().each(function() {
if ($(this).contents().length > 0) return getWords($(this));
if ($(this).text()) words = words.concat($(this).text().split(" "));
})
}
getWords($('<div>').html('<p>11 22 33</p><p>44</p>5<br></div>'));
console.log(words,words.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can do something tricky by using jQuery by creating an element with the content.
var str = '<p>11 22 33</p><p>44</p>5<br></div>';
var len = 0;
// create a temporary jQuery object with the content
$('<div/>', {
html: str
})
// get al child nodes including text node
.contents()
// iterate over the elements
.each(function() {
// now get number or words using match and add
len += (this.textContent.match(/[\w\d]+/g) || '').length;
});
console.log(len);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can use Countable.js for live word counting, although it doesn't ignore HTML tags.

How to replace text between tags only

I have multiple h2 tags and every tag contains text and has a custom attribute called data-options. This attribute has multiple options separated by commas and one of these options is the h2 tag text itself.
HTML:
<h3 id='test' data-options='happy,sad,fantastic'>sad</h3>
<h3 id='test2' data-options='1,2,3,4'>3</h3>
jQuery:
var indexArray = ['happy','1'];
$('h3').each(function(i){
var $this = $(this),
value = $this.text(),
code = $('body').html();
code = code.replace(value, indexArray[i]);
$('body').html(code);
});
This is what I expect:
<h3 id='test' data-options='happy,sad,fantastic'>happy</h3>
<h3 id='test2' data-options='1,2,3,4'>1</h3>
Instead I get this:
<h1 id="test" data-options="happy,happy,fantastic">sad</h1>
<h3 id="test2" data-options="1,2,3,4">3</h3>
As you can see the script changes the first text it encounters, not the one inside the tags.
This is a working demo for the script : http://jsfiddle.net/fs1sfztx/
It makes no sense to do a replace unless you're searching. Which means you have to be provided what to search for and what to replace it with. So far only the text to in the h3 is given.
Assuming that each index in indexArray matches the index of each h3 element, then you can compare the current indexArray element indexArray[i] with each of the words in the corresponding elements data-options attribute. When a matches, set the innerText prop to that word.
var indexArray = ['happy','1'];
$('h3').text( function( i, txt ) {
var that = $(this);
var ntxt = txt;
$.each( that.data('options').split(','), function( j, u ) {
indexArray[i] !== u || (ntxt = u);
});
return ntxt;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3 id='test' data-options='happy,sad,fantastic'>sad</h3>
<h3 id='test2' data-options='1,2,3,4'>3</h3>
If all you wanted is to play with the replace method, then you could use something like this:
var indexArray = ['happy','1'];
var allhtml = $('body').html();
$('h3').each( function( i ) {
var txt = $(this).text();
var re = new RegExp( '>' + txt + '<', 'g' );
allhtml = allhtml.replace( re, '>' + indexArray[i] + '<' );
});
$('body').html( allhtml );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3 id='test' data-options='happy,sad,fantastic'>sad</h3>
<h3 id='test2' data-options='1,2,3,4'>3</h3>

exclude the first string from being appended to a character

FIDDLE Example
I'm learning how to append all the data attributes from div.query elements to a url string: http://web.com?get=
With the script I can get this result:
"http://web.com?get=|Africa|Asia|Europe"
But is there any way not to have the first one coupled with "|" so that the url should be
"http://web.com?get=Africa|Asia|Europe"
I want to get that result because either http://web.com?get=|Africa|Asia|Europe
or http://web.com?get=Africa|Asia|Europe| would be invalid. Any suggestions?
JS:
$( document ).ready(function() {
$(".query").each(function() {
var div_terms = $(this).data('term'),
source = $('#main').data('source');
var x = source+'|'+div_terms;
$('#main').data('source',x);
$('.result').html(x);
});
});
HTML:
<div id="main" data-source="http://web.com?get="></div>
<div class="query" data-term="Africa"></div>
<div class="query" data-term="Asia"></div>
<div class="query" data-term="Europe"></div>
<div class="result"></div>
The easiest way is to pull all the countries to an array and join them using the pipe character.
var terms = $('.query').map( function() {
return $(this).data('term');
}).get().join('|');
var source = $('#main').data('source');
$('.result').html( source + terms );
Demo
http://jsfiddle.net/cHtT6/3/
You just need to replace the first '|' in the resulting url with an empty character ''.
Make it simple use javascript join function
$( document ).ready(function() {
var terms=[];
$(".query").each(function() {
var div_terms = $(this).data('term');
terms.push(div_terms);
});
var x = $('#main').data('source')+terms.join("|");
$('.result').html(x);
});
Fiddle here
Use an if statement to check if it's the first 'data-term'. If it is then don't use the | character. Then in the else statement you just do as you've already done
DEMO
Just Check whether end is reached like this:
$( document ).ready(function() {
var i=0;
$(".query").each(function() {
i++;
var div_terms = i==$(".query").length? $(this).data('term')+"":$(this).data('term')+"|",
source = $('#main').data('source');
var x = source+''+div_terms;
$('#main').data('source',x);
$('.result').html(x);
});
});
Here when last term is reached. Automatically only "" is appended in all other cases "|" is appended.

javascript extract html block from string

I have a string extracted from a div and stored in variable "str". I now need to extract the ... subset of it.
str = '<div id="xyz"><p>This is a paragraph</p><img src="http://bs.serving-sys.com/BurstingPipe/adServer.bs?cn=bsr&FlightID=2997227&Page=&PluID=0&Pos=9088" border=0 width=300 height=250></div>';
Thanks in advance for any help with this.
You could try something like the below:
var a = $(str).find('a').html();
make it innerHTML of a temporary div.
use getElementsByTagName("A") to retreive all "A" nodes.
get their HTML .
Here is a running example : http://jsfiddle.net/3fZch/
var str = '<div id="xyz"><p>This is a paragraph</p><img src="http://bs.serving-sys.com/BurstingPipe/adServer.bs?cn=bsr&FlightID=2997227&Page=&PluID=0&Pos=9088" border=0 width=300 height=250></div>';
var newElem = returnTheParentNode(str);
var anchors = newElem.getElementsByTagName('A');
/* anchors has all the a tags of the html string */
for(var i = 0 ; i < anchors.length ; i++)
{
var aHTML = getHTML(anchors[i]);
alert(aHTML);
}
function returnTheParentNode(htmlStr)
{
var myCont = document.createElement('DIV'); // create a div element
myCont.innerHTML = htmlStr; // create its children with the string
return myCont; // return the parent div
}
function getHTML(theNode)
{
var myCont = document.createElement('DIV');
myCont.insertBefore(theNode,null);
return myCont.innerHTML ;
}
The expression you need is:
str.match(/a href="([^"]*)"/)[1]
But this assumes there is only one a tag in your string and you used double quotes to delimit the href.
Made a jsfiddle: http://jsfiddle.net/eDAuv/
Why not extract the link BEFORE you store it in a string?
myLink = $(".myDiv a").html()
This could work:
var link = $(str).find("a").get(0).outerHTML;
alert(link);

How to get child element by ID in JavaScript?

I have following html:
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
How can I get textarea element? I can't use document.getElementById("textid") for it
I'm doing it like this now:
var note = document.getElementById("note");
var notetext = note.querySelector('#textid');
but it doesn't work in IE(8)
How else I can do it? jQuery is ok
Thanks
If jQuery is okay, you can use find(). It's basically equivalent to the way you are doing it right now.
$('#note').find('#textid');
You can also use jQuery selectors to basically achieve the same thing:
$('#note #textid');
Using these methods to get something that already has an ID is kind of strange, but I'm supplying these assuming it's not really how you plan on using it.
On a side note, you should know ID's should be unique in your webpage. If you plan on having multiple elements with the same "ID" consider using a specific class name.
Update 2020.03.10
It's a breeze to use native JS for this:
document.querySelector('#note #textid');
If you want to first find #note then #textid you have to check the first querySelector result. If it fails to match, chaining is no longer possible :(
var parent = document.querySelector('#note');
var child = parent ? parent.querySelector('#textid') : null;
Here is a pure JavaScript solution (without jQuery)
var _Utils = function ()
{
this.findChildById = function (element, childID, isSearchInnerDescendant) // isSearchInnerDescendant <= true for search in inner childern
{
var retElement = null;
var lstChildren = isSearchInnerDescendant ? Utils.getAllDescendant(element) : element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].id == childID)
{
retElement = lstChildren[i];
break;
}
}
return retElement;
}
this.getAllDescendant = function (element, lstChildrenNodes)
{
lstChildrenNodes = lstChildrenNodes ? lstChildrenNodes : [];
var lstChildren = element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].nodeType == 1) // 1 is 'ELEMENT_NODE'
{
lstChildrenNodes.push(lstChildren[i]);
lstChildrenNodes = Utils.getAllDescendant(lstChildren[i], lstChildrenNodes);
}
}
return lstChildrenNodes;
}
}
var Utils = new _Utils;
Example of use:
var myDiv = document.createElement("div");
myDiv.innerHTML = "<table id='tableToolbar'>" +
"<tr>" +
"<td>" +
"<div id='divIdToSearch'>" +
"</div>" +
"</td>" +
"</tr>" +
"</table>";
var divToSearch = Utils.findChildById(myDiv, "divIdToSearch", true);
(Dwell in atom)
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
<script type="text/javascript">
var note = document.getElementById('textid').value;
alert(note);
</script>
Using jQuery
$('#note textarea');
or just
$('#textid');
$(selectedDOM).find();
function looking for all dom objects inside the selected DOM.
i.e.
<div id="mainDiv">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<div id="innerDiv">
link
<p>Paragraph 3</p>
</div>
</div>
here if you write;
$("#mainDiv").find("p");
you will get tree p elements together. On the other side,
$("#mainDiv").children("p");
Function searching in the just children DOMs of the selected DOM object. So, by this code you will get just paragraph 1 and paragraph 2. It is so beneficial to prevent browser doing unnecessary progress.

Categories

Resources