I'm trying to check whether the given htmlData
has nested(parent,child not siblings) span
elements with attribute name data-fact
or not.
if it does then replace it with span
to div
with class='inline-span'
pass all the attributes with it.
else just return the htmlData
var htmlData = `<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
<span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span>
</span>
</p>
`
replaceTags(htmlData)
function replaceTags (htmlData) {
var $elm = $(htmlData).find("span[data-fact]");
var $nestedElm = $elm.children().length > 1;
if($nestedElm){
htmlData = htmlData.replace(/<span/g, '<div ');
htmlData = htmlData.replace(/<\/span>/g, '<\/div>');
}else{
return htmlData;
}
},
The output htmlData
i want is something like this
<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<div class='inline-span' xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
<div class='inline-span' xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</div>
</div>
</p>
Here i'm not able to find is the span
element is nested or not and then the conversion of how can i pass the class='inline-span'
with all the previous attributes to the div
.
PS: answer i want is in JQuery
CodePudding user response:
Code hint is in the comments where changes have been made.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script> var htmlData = `<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" data-fact="619959c0062c677faebd7b55">
<span xvid="ca5635a4e4de332d7dc3036a68e57009" data-fact="619959c0062c677faebd7b57">November 1, 2021</span>
</span>
</p>
`
console.log(replaceTags(htmlData));
function replaceTags (htmlData) {
//var $factElem = $elm.find('[data-fact]');
// alternative way to make above checks since htmlData is a string at this point of time so just simply search the string to determin id data attribute exists.
if(htmlData.toLowerCase().includes("data-fact")){
htmlData = htmlData.replace(/<span/g, '<div ');
htmlData = htmlData.replace(/<\/span>/g, '<\/div>');
}
//no need to else it since you would be throwing out htmlData in any case.
return htmlData;
}
</script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
just in case data-fact is present but no span tag then it would make the replacement as examplified below.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script> var htmlData = `<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<p xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" data-fact="619959c0062c677faebd7b55">
<p xvid="ca5635a4e4de332d7dc3036a68e57009" data-fact="619959c0062c677faebd7b57">November 1, 2021</p>
</p>
</p>
`
console.log(replaceTags(htmlData));
function replaceTags (htmlData) {
//var $factElem = $elm.find('[data-fact]');
// alternative way to make above checks since htmlData is a string at this point of time so just simply search the string to determin id data attribute exists.
if(htmlData.toLowerCase().includes("data-fact")){
htmlData = htmlData.replace(/<span/g, '<div ');
htmlData = htmlData.replace(/<\/span>/g, '<\/div>');
}
//no need to else it since you would be throwing out htmlData in any case.
return htmlData;
}
</script>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
I did some changes related to Find in HTML element and in replace jquery code here is a working demo hope it will be helpful for you.
you can direcatly replace all html with like
htmlData = htmlData.replace($factElem[0].outerHTML, 'div html');
using $factElem[0].outerHTML
you can find element containing [data-fact] html.
yes you can check only using data-fact and replace it with div there is no span needed
I updated Code Please check now.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("button").click(function () {
var htmlData = '<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f"><span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"><span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span></span></p>'
replaceTags(htmlData)
});
});
function replaceTags(htmlData) {
var $factElem = $(htmlData).find('[data-fact]');
if ($factElem) {
htmlData = htmlData.replace($factElem[0].outerHTML, '<div class="inline-span" xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"><div class="inline-span" xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</div></div>');
$("#append").empty().append(htmlData);
alert(htmlData);
} else {
$("#append").empty().append(htmlData);
}
}
</script>
</head>
<body>
<div id="append"></div>
<button>Click me to Replace!!</button>
</body>
</html>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
It is typically a bad idea to do string replacement to change HTML. You should instead use the tools of jquery to manipulate the DOM. Which is safer and less error prone.
// While there are still more span's in the p
while ($('p span[data-fact]').length > 0) {
// get the next span to replace with a div
const $span = $($('p span[data-fact]')[0]);
// create the new div
const $newDiv = $('<div>');
// copy the span's html into the div
$newDiv.html($span.html());
// For each attribute in the span ...
$.each($span[0].attributes, (_ , attr) => {
// ... set the new div to have the span's attribute.
$newDiv.attr(attr.name, attr.value);
});
// new div needs 'inline-span' property.
$newDiv.addClass('inline-span');
// finally replace the span with the new div
$span.replaceWith($newDiv);
}
console.log($('p').html());
span[data-fact] {
border: 1px solid red;
padding: 3px;
}
div[data-fact] {
border: 1px solid blue;
padding: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
<span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
<span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span>
</span>
</p>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
NOTE: it is invalid HTML to have div
tag inside p
so one should probably replace the p
tag too.