How to get text of element in a variable using jquery? - javascript

var markup = '<div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC">Employee Self-Service pages have been corrected but may require you to refresh the page.</div><div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC"> </div><div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC">If the problem remains, follow these instructions.  </div>';
var str = "";
$(markup).find("div[class^='ExternalClass']").each(function(){
str += $(this).text();
})
How do I grab content of all the divs in the markup that starts with ExternalClass?

$(markup) selector contain all ExternalClass class and you can't use .find() because it doen't any matched child. You need to use .filter() to filter selected element.
var markup = "<div...";
var str = "";
$(markup).filter("div[class^='ExternalClass']").each(function(){
str += $(this).text();
})
var markup = '<div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC">Employee Self-Service pages have been corrected but may require you to refresh the page.</div><div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC"> </div><div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC">If the problem remains, follow these instructions.  </div>';
$(markup).filter("div[class^='ExternalClass']").each(function(){
console.log($(this).text());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

jQuerys .find() only loops through the children of the specific HTML you selected. Your variable markup has no children with the fitting class selector.
The easiest way I can imagine getting this solved, is to wrap all you have in markup inside another div, and then use your jQuery selector - that works:
var markup = '<div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC">Employee Self-Service pages have been corrected but may require you to refresh the page.</div><div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC"> </div><div class="ExternalClass34E9F553C2F74AA2B6D693A07BA166AC">If the problem remains, follow these instructions.  </div>';
markup = '<div>' + markup + '</div>';
var str = "";
$(markup).find("div[class^='ExternalClass']").each(function(){
str += $(this).text();
})

Related

Writing line breaks to a <span> element using JavaScript?

My goal is to take an array, and write each element onto a HTML page using a <span> element with .textContent using a for loop. Only problem is that instead of:
Error1
Error2
I get:
Error1<br/>Error2<br/>
HTML code:
<p><span id="EBox"></span></p>
JS code:
var EBox = document.getElementById("EBox");
var eArray = []; //Elements get added via push
for (var i = 0; i < eArray.length; i++) {
EBox.textContent = EBox.textContent + eArray[i] + '<br/>';
}
The entire system works, but it just ends up as one jumbled sentence. What can I change to make it add the line breaks? I've tried '<br>', '<br />' and '\n' with similar results.
Use .innerHTML .insertAdjacentHTML instead of .textContent as .textContent does not parse the HTML <br> but simply outputs it as text.
Also if you're appending to the HTML each time, it's better to use .insertAdjacentHTML as it does not reparse the previous HTML, thus making it much faster and less error prone than .innerHTML.
var strArr = ['foo', 'bar'];
strArr.forEach(function(str) {
document.querySelector('div').insertAdjacentHTML('beforeend', str + '<br>');
});
<div></div>
Instead of .textContent use .innerHTML.
I would also recommend building up a string first before using .innerHTML so the DOM isn't rebuilt each time...
var EBox = document.getElementById("EBox");
var eArray = []; //Elements get added via push
var html = "";
for (var i = 0; i < eArray.length; i++) {
html += eArray[i] + '<br/>';
}
EBox.innerHTML = html;
I found a better answer here:
https://developer.mozilla.org/pt-BR/docs/Web/CSS/word-break
You can use CSS to do this, see below:
span{word-break: break-word;}
or
span{word-break: break-all;}
BREAKE-WORD will put the next word in a new line and BREAKE-ALL will break the text justifying the content, when it gets bigger than the div or span container.
I hope I'd help :)

Jquery - find all elements where the start element matches closest parent with that selector

I have HTML structures in a form system where a html node will have data-src="formname" and this will contain lots of html nodes with data-fld="fieldname". This would be easy to parse but sometimes a field can be a host of a subform that itself contains data-src and data-fld.
When I search for [data-src='name'] using jquery find selectors I get both the immediate data-fld elements and the ones contained in a child data-src, I only want the former, not the latter.
I've created a fiddle to demonstrate:
<div data-src="mainform">
<div data-fld="field1">fld1</div>
<div data-fld="field2">
<div data-src="subform">
<div data-fld="subfield1">subfld1</div>
</div>
</div>
</div>
<div id="info"></div>
And the JS:
var result = "";
var find = "mainform";
var src = $("[data-src='" + find + "']");
src.find("[data-fld]").each(function() {
var ele = $(this);
if (ele.closest("[data-src='" + find + "']") === src) {
result += "Child field : " + $(this).data("fld") + " ";
}
});
$("#info").text(result);
The above code works, by virtue of that IF statement, I think it would be nice to be able to select "[data-fld]" where its closest "[data-src]" is the one I'm working on, and I wondered if (a) there's an inherent JQuery/CSS selector way of doing this or (b) is there otherwise a better solution to this code.
Not only because we want elegant code but also because asking for closest on every loop iteration is going to be a performance issue, possibly.
using immediate children selector
var result = "";
var find = "mainform";
var src = $("[data-src='" + find + "']");
src.find("[data-fld]").first().each(function() {
var ele = $(this);
result += "Child field : " + $(this).data("fld") + " ";
});
$("#info").text(result);

Append data from div to link url

I am trying to have a div element on every page of my site that will contain the product number and then have a link that will put that number at the end.
For example,
<div id="productnumber">01101</div>
https://example.com/#
Then put the contents of the element with id "productnumber" after the # of the link.
Any idea if this is possible? Since this would make life easier than editing all existing pages and their respective php files.
Check for Element.innerHTML. You could use some inline JS and append it to the href-Attribute (which should be were id="purchaseurl" is now)
You can add a simple script to all your pages.
document.addEventListener("DOMContentLoaded", function() {
var productNumber = document.getElementById('productnumber').textContent;
Array.prototype.forEach.call(document.querySelectorAll('a[href~="purchaseurl"]'), function(link) {
// if you want to change the link
var currentHref = link.getAttribute('href');
link.setAttribute('href', currentHref + '#' + productNumber);
// if you want to change anchor text
var currentText = link.innerHTML;
link.innerHTML = currentText + productNumber;
});
});
<div id="productnumber">01101</div>
https://example.com/#
See getElementById, getElementsByTagName, and nextSibling.
var data = document.getElementById('productnumber'),
url = data.nextSibling.nextSibling;
url.innerText += data.innerText;
<div id="productnumber">01101</div>
https://example.com/#

JavaScript RegExp match text ignoring HTML

Is it possible to match "the dog is really really fat" in "The <strong>dog</strong> is really <em>really</em> fat!" and add "<span class="highlight">WHAT WAS MATCHED</span>" around it?
I don't mean this specifically, but generally be able to search text ignoring HTML, keeping it in the end result, and just add the span above around it all?
EDIT:
Considering the HTML tag overlapping problem, would it be possible to match a phrase and just add the span around each of the matched words? The problem here is that I don't want the word "dog" matched when it's not in the searched context, in this case, "the dog is really really fat."
Update:
Here is a working fiddle that does what you want. However, you will need to update the htmlTagRegEx to handle matching on any HTML tag, as this just performs a simple match and will not handle all the cases.
http://jsfiddle.net/briguy37/JyL4J/
Also, below is the code. Basically, it takes out the html elements one by one, then does a replace in the text to add the highlight span around the matched selection, and then pushes back in the html elements one by one. It's ugly, but it's the easiest way I could think of to get it to work...
function highlightInElement(elementId, text){
var elementHtml = document.getElementById(elementId).innerHTML;
var tags = [];
var tagLocations= [];
var htmlTagRegEx = /<{1}\/{0,1}\w+>{1}/;
//Strip the tags from the elementHtml and keep track of them
var htmlTag;
while(htmlTag = elementHtml.match(htmlTagRegEx)){
tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
tags[tags.length] = htmlTag;
elementHtml = elementHtml.replace(htmlTag, '');
}
//Search for the text in the stripped html
var textLocation = elementHtml.search(text);
if(textLocation){
//Add the highlight
var highlightHTMLStart = '<span class="highlight">';
var highlightHTMLEnd = '</span>';
elementHtml = elementHtml.replace(text, highlightHTMLStart + text + highlightHTMLEnd);
//plug back in the HTML tags
var textEndLocation = textLocation + text.length;
for(i=tagLocations.length-1; i>=0; i--){
var location = tagLocations[i];
if(location > textEndLocation){
location += highlightHTMLStart.length + highlightHTMLEnd.length;
} else if(location > textLocation){
location += highlightHTMLStart.length;
}
elementHtml = elementHtml.substring(0,location) + tags[i] + elementHtml.substring(location);
}
}
//Update the innerHTML of the element
document.getElementById(elementId).innerHTML = elementHtml;
}
Naah... just use the good old RegExp ;)
var htmlString = "The <strong>dog</strong> is really <em>really</em> fat!";
var regexp = /<\/?\w+((\s+\w+(\s*=\s*(?:\".*?"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/gi;
var result = '<span class="highlight">' + htmlString.replace(regexp, '') + '</span>';
A simpler way with JQuery would be.
originalHtml = $("#div").html();
newHtml = originalHtml.replace(new RegExp(keyword + "(?![^<>]*>)", "g"), function(e){
return "<span class='highlight'>" + e + "</span>";
});
$("#div").html(newHtml);
This works just fine for me.
Here is a working regex example to exclude matches inside html tags as well as javascripts:
http://refiddle.com/lwy6
Use this regex in a replace() script.
/(a)(?!([^<])*?>)(?!<script[^>]*?>)(?![^<]*?<\/script>|$)/gi
this.keywords.forEach(keyword => {
el.innerHTML = el.innerHTML.replace(
RegExp(keyword + '(?![^<>]*>)', 'ig'),
matched => `<span class=highlight>${matched}</span>`
)
})
You can use string replace with this expression </?\w*> and you'll get your string
If you use jQuery, you can use the text property on the element containing the text you're searching for. Given this markup:
<p id="the-text">
The <strong>dog</strong> is really <em>really</em> fat!
</p>
This would yield "The dog is really really fat!":
$('#the-text').text();
You could do your regex search on that text instead of trying to do so in the markup.
Without jQuery, I'm unsure of an easy way to extract and concatenate the text nodes from all child elements.

jQuery issue with editing heading tags using html()

Basically I have a load of H1 H2 and H3 tags on a website and I want to be able to put a span around PART of these heading tags.
At the moment I have this:
jQuery(document).ready(function(){
// get all headings first
jQuery('h1, h2, h3').each(function(){
// get the text
var theHtml = jQuery(this).html();
// split by spaces
var theWords = theHtml.split(" ");
// count the words
var wordCount = theWords.length;
var newHtml;
if(wordCount < 2){
// only one word
newHtml = theHtml;
}
else if(wordCount == 2){
// word count is 2...
newHtml = theWords[0]+" <span style='color: #000'>"+theWords[1]+"</span>";
}
else {
// add the first two words:
newHtml = theWords[0]+" "+theWords[1]+" <span style='color:#000'>";
// need to loop through the array now
for(var i = 2; i<wordCount; i++){
newHtml = newHtml+theWords[i];
if(i+1 < wordCount){
newHtml = newHtml+" ";
}
}
//end
newHtml = newHtml+"</span>";
}
jQuery(this).html(newHtml);
});
});
Which works quite well. But now I have a problem which is sometimes there is an a element or a div (for an inline editor if logged in as an admin) in the titles which is breaking this...
How would I get around this? I need to potentially get all the html from the header tag, strip the HTML tags, add the span around the latter part, then put the html back in!
Any ideas?
Thank you.
Edit:
This is what the problematic html looks like:
<h1 class="entry-title"><div data-type="input" data-post_id="12" class="fee-field fee-filter-the_title">Bristish Society of Blood and Marrow Transplantation</div></h1>
And like this:
<h2 class="entry-title"><div data-type="input" data-post_id="62" class="fee-field fee-filter-the_title">About the Registry</div></h2>
But if not logged in as an administrator then the div's go away.
Hey! Nice one, I think this is possible with regular expressions. I made a quick example for you, covering the a and the div for the biggest part. All spaces that are not meant as real whitespaces (in the tags) are replaced with symbols like ___ or ---, which are changed back afterwards.
Take a look at this jsfiddle!
theHtml = theHtml.replace(/[\s]+\</gi,'<');
theHtml = theHtml.replace(/\s+[\'\"]/gi,'___');
theHtml = theHtml.replace(/[\'\"]\s+/gi,'---');
theHtml = theHtml.replace(/a\s/gi,'a_');
theHtml = theHtml.replace(/div\s/gi,'div_');
and backwards:
newHtml = newHtml.replace(/___/gi,' "');
newHtml = newHtml.replace(/---/gi,'" ');
newHtml = newHtml.replace(/div_/gi,'div ');
newHtml = newHtml.replace(/a_/gi,'a ');
COMMENT after your edit
This will not work for the example h1 and h2 you posted. This is just an idea of how to approach this. I hope this will help you! Good luck!
COMMENT2 after my own edit ;-)
It does work, I just forgot to add case insensitivity and recursivity! It's just not finished yet. There are more checks needed such as ' or " etc. Here you go, I hope this will get you on the right track.
Please use the jQuery .text() function to strip out all the text within any particular H1, H2 tags etc. Other HTML inside these tags will be ignored.
But, i'm not sure how you will restore all the Inner HTML tags back.
Have you tried jQuery's wrapInner() function? I think it does what you're looking for in just one line.
$('h1, h2, h3').wrapInner('<span></span>');
If you know what class will be in the "inner" HTML element, you can just grab that.
var outer = $('.entry-title');
var html = html.find('.fee-field');
if(html === null){
html = outer;
}
// html will either be your `h` element or your inner most element.

Categories