Insert <span> in <p> element - javascript

I got like;
<p>Variable Text</p>
And I want to it to be;
<p>Variable <span>Text</span></p>
Is this possible by a javascript function? / or jQuery.
Oh yeah, and the p-element got an ID and the text inside the p-element is variable but always consists of 2 words. I want a span around the last word of the text by a javascript function.

Try this
var txt = "Hello bye";
var dataArr = txt.split(' ');
var paragraph = document.getElementById("pid");
paragraph.innerHTML = dataArr[0]+ " <span>"+dataArr[1]+"</span>";
Here is a demo

It's possible (the following assumes the p has an ID, like you said), in it's simplest form you can just do:
var paragraph = document.getElementById("pId");
paragraph.innerHTML = "Hello <span>World</span>";
Or if you want to use jQuery:
$("#pId").html("Hello <span>World</span>");
Or (as you said in comments, you want to keep the existing content, but wrap the last word in a span, you can do:
var newHTML = $("#pId").html().replace(" ", " <span>");
$("#pId").html(newHTML).append("</span>");
DEMO

I would like to share a jQuery solution, which is regardless of any words defined in your p element
$("p").html(function(){
var mystring= $(this).text().split(" ");
var lastword = mystring.pop();
return mystring.join(" ")+ (mystring.length > 0 ? " <span>"+ lastword + "</span>" : lastword);
});
Demo
In the demo above, I am splitting the string first, than am using pop to get the last index in the array, and than am adding span element and returning the string using join

$("document").ready(function(){
$("p").append("<span>world</span>");
});

With JQuery append
$("#paragraphId").append('<span>Text in span</span>');

jQuery is easier, and personally I think it's better to use than only javascript:
jQuery:
$("#paragraphID").append("<span>World</span>");
HTML:
<p id="paragraphID">Hello</p>

Related

Javascript - How can I replace text in HTML with text in script

I am new to javascript. I was thinking getelementbyid but i don't know how to make it work
Like the title, here is what I mean
For example I have in HTML:
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
So what I want is to make script to replace those fw_93 fw_94 to what I want.
For example
Instead of displaying "fw_93" I want it to display "9.3". Same with fw_94 to 9.4
Replace fw_ with nothing, divide the number by 10:
Array.prototype.forEach.call(document.getElementsByTagName('p'), function(el) {
el.innerHTML = parseInt(el.innerHTML.replace(/[A-Za-z_]*/, '')) / 10;
});
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
Okay so select the tags.
Loop over the collection
read the html
match the string
replace the html
var ps = document.querySelectorAll("p");
for (var i=0; i<ps.length; i++) {
var p = ps[i];
var txt = p.innerHTML; //.textContent
var updated = txt.replace(/.+(\d)(\d)/, "$1.$2");
p.innerHTML = updated;
}
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
Using JQuery
Not sure why I did it with JQuery, guess I wasn't paying enough attention. No point in me re-writing as there are already good answers in JS. Though I will leave this in case it's of use to anyone that is using JQuery.
You can loop though each <p> element and covert the contents, something like this:
$("p").each(function() {
var text = $(this).html();
var text = text.substring(text.indexOf("_") + 1);
var text = text[0] + "." + text.substring(1);
$(this).html(text);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
You may need to add validation depending on how reliable your input is.
Note that the code makes the following assumptions:
There will always be a _ followed by at least 2 digits
The . will always go after the first digit
Your HTML:
<p id="p1">init_value</p>
Your JS:
document.getElementById("p1").innerHTML = "new_value";

Find surrounding characters of an element inside a paragraph

I have this little problem. I need to find the first 3 characters before and after an anchor tag that is inside a paragraph.
Example:
<p>This is <a href='#' id='lock'>a</a> test for an anchor</p>
What I need to have as a result is:
is te
Where is (includes space at the end) is the first 3 characters left from the anchor tag and te (again including space at start) are the 3 first characters right from the anchor tag.
JQuery can help and so far I tried with regex and Jquery but no luck.
What else should I try? Is there something I might be missing?
It had been a while since I worked with frontend problems.
Something like this
var lock = document.getElementById('lock');
var prev = lock.previousSibling;
var next = lock.nextSibling;
var text = prev.textContent.slice(-3) + next.textContent.slice(0, 3);
FIDDLE
Use the following regex to capture the there characters before and after anchor a tag,
(.{3})<a href.*?<\/a>(.{3})
DEMO
If you want to replace the whole with only the captured groups then your regex would be,
.*(.{3})<a href.*?<\/a>(.{3}).*
And the substitution would be,
$1$2
DEMO
And your code would be,
> var str = "<p>This is <a href='#' id='lock'>a</a> test for an anchor</p>";
undefined
> var r = str.replace(/.*(.{3})<a href.*?<\/a>(.{3}).*/g, "$1$2");
undefined
> console.log(r);
is te
undefined
Try to use .contents() to grab the text nodes,
var pTag = $('p').contents();
console.log(pTag[0].nodeValue.slice(-3) +
pTag[2].nodeValue.substring(0,3)); // "is te"
DEMO
Another solution with jQuery and DOM traversing:
var a = $("a", "<p>This is <a href='#'>a</a> test for an anchor</p>")[0],
left = a.previousSibling.nodeValue.slice(-3),
right = a.nextSibling.nodeValue.slice(0, 3);
console.log(left, right); // "is " " te"

Getting the last entered word from a contentEditable div

I have a div tag with contenteditable set to true.
I am trying to find out the last entered word in the div.
For example, if I type in This is a test and I hit a space, I want to be able to get the word test
I want to be able to use this logic so that I can test each word being typed (after the space is pressed).
It would be great if someone could help me with this.
An easy solution would be the following
var str = "This is a test "; // Content of the div
var lastWord = str.substr(str.trim().lastIndexOf(" ")+1);
trim might need a shim for older browsers. (.replace(/\s$/,""))
To strip punctuation like " Test!!! " you could additionally do a replace like following:
lastWord.replace(/[\W]/g,"");
You might want to do a more specific definition of the characters to omit than \W, depending on your needs.
If you want to trigger your eventhandler also on punctuation characters and not only on space, the last replace is not needed.
You first have to know when the content is edited. Using jQuery, that can be done with
​$("div").on("keyup", function(){ /* code */ });
Then, you'll have to get the whole text and split it into words
var words = $(this).text().trim().split(' ');
And getting the last word is as complicated as getting the last element of the words array.
Here's the whole code
HTML
​<div contenteditable="true">Add text here</div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
JavaScript (using jQuery)
​
$("div").on("keyup", function(){
var words = $(this).text().trim().split(' '),
lastWord = words[words.length - 1];
console.log(lastWord);
});​​​​​​​
Demo
This is the ultimate way:
// listen to changes (do it any way you want...)
document.querySelectorAll('div')[0].addEventListener('input', function(e) {
console.log( getLastWord(this.textContent) );
}, false);
function getLastWord(str){
// strip punctuations
str = str.replace(/[\.,-\/#!$%\^&\*;:{}=\_`~()]/g,' ');
// get the last word
return str.trim().split(' ').reverse()[0];
}
DEMO PAGE
You can try this to get last word from a editable div.
HTML
<div id='edit' contenteditable='true' onkeypress="getLastWord(event,this)">
</div>
JS
function getLastWord(event,element){
var keyPressed = event.which;
if(keyPressed == 32){ //Hits Space
var val = element.innerText.trim();
val = val.replace(/(\r\n|\n|\r)/gm," ");
var idx = val.lastIndexOf(' ');
var lastWord = val.substring(idx+1);
console.log("Last Word " + lastWord);
}
}
Try this link http://jsfiddle.net/vV2mN/18/

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.

Count the lines of a PRE element using jQuery

How can I count how many lines of text a <pre> tag contains?
I want to append a absolute div with line numbers next to it.
you could use the javascript split function to count the line breaks.
$('pre').html().split(/\n/).length
better
$('pre').html().match(/\n/)
Using jQuery
$('#preID').text().split('\n').length
using plain javascript
document.getElementById('preID').innerHTML.split('\n').length
example at http://jsfiddle.net/gaby/tdekQ/
This will work as long as you don't have any <br> tags in your <pre> element:
var numlines = $('#mypreelement').text().match(/\n\r?/g).length + 1;
Example: http://jsfiddle.net/jtbowden/3QThm/
You can handle the <br> tags by counting them separately:
var pretext = $('#mypreelement').html();
var numlines = pretext.match(/\n\r?/g).length + 1;
numlines += $('#test br').length;
Example: http://jsfiddle.net/jtbowden/3QThm/2/
Other tags in the <pre> will cause you headaches.

Categories