How to edit html element with Javascript dom? - javascript

i try to edit the span element inside with javascript dom:
<div class="data">
<span>Jan. 16, 2019</span>
</div>
So that only last 4 characters are shown,
var list = document.getElementById("data");
list.removeChild(list.childNodes[3]);
But it doesnot work

One error: you're searching with getElementById for an element with id data but data is the class.
<div id="data"> should make the list assignment work. Or use document.querySelector('.data')
The next line with removeChild makes no sense to me, at least with given HTML.

In order to only keep the last four characters in the span:
var list = document.getElementsByClassName("data")[0];
let str = list.childNodes[1].textContent;
list.childNodes[1].textContent = str.substring(str.length-4, str.length);
<div class="data">
<span>Jan. 16, 2019</span>
</div>

Two things are going wrong. You are looking for an ID, but the HTML does not have an ID. Also showing the last 4 characters is not going alright.
I would propose to add an id to the span:
<div class="data">
<span id="date">Jan. 16, 2019</span>
</div>
var span = document.getElementById("date");
var date = span.textContent;
span.textContent = date.substr(date.length - 4);

Related

Get the href value using HTML5 data attributes

I would like to get the value of the href i.e. the web link using the data attribute.
I have the following snippet of code
<div class="my-item-details">
<h3 class="my-item-title" data-item_item="x12">
<a href="http://link.com">
My Classic Box
</a>
</h3>
<span class="my-item-price" data-item_item="x12">
38.00
</span>
</div>
The following 2 snippets give the right output.
var price_val = $('.my-item-price[data-item_uuid=x12]').text();
price_val = $.trim(price_val)
console.log(price_val);
38.00
var item_name = $('.my-item-title[data-item_uuid=x12]').text();
item_name = $.trim(item_name)
console.log(item_name);
My Classic Box
However when I run this code
var item_link = $('.my-item-title[data-item_uuid=x12]').attr("href");
item_link = $.trim(item_link)
console.log(item_link);
I get an empty string instead of http://link.com
What am I missing?
.my-item-title[data-item_uuid=x12] selects the h3 element, which doesn't have an href attribute.
Only the a element has that.
Add a descendant combinator and a type selector:
.my-item-title[data-item_uuid=x12] a
You are trying to get the attribute href from a <h3> element without href property:
You could make a change on your selector this way to get the correct result:
var item_link = $('.my-item-title[data-item_uuid=x12] > a').attr("href");
This should give you the correct value.

Combined two HTML data value with Regex

I am trying to merege two HTML data into one HTML tag. I am trying to do it with regex.
The HTML is look like this
var temp = document.getElementById('data').innerHTML;
console.log(temp);
<div id="data">
<strong>20 </strong>
<strong>0 </strong>
<strong>0 /-</strong>
</div>
My expexted output is <strong>2000/-</strong>
// you should get the textContent instead of the innerHTML
var temp = document.getElementById('data').textContent;
// removes all spaces and
// surrounds the output with the <strong> element
var newhtml = `<strong>${ temp.replace(/\s/g,'') }</strong>`;
// replaces the innerHTML of the data with newhtml
document.getElementById('data').innerHTML = newhtml
<div id="data">
<strong>20 </strong>
<strong>0 </strong>
<strong>0 /-</strong>
</div>
You do not need regex for this you could simply concat the strings with
str.concat(string2, string3, string4, etc)
and giving all the strong tags an individual ID
However, if the content is dynamic and not hard coded in, you could loop through the child nodes of document.getElementById('data') and get the textContent of each of the child nodes and concat them that way.

Insert span in a dom element without overwrite child nodes?

I have an HTML article with some annotations that I retrieve with SPARQL queries. These annotations refer to some text in the document, and I have to highlight this text (wrapping it in a span).
I had already asked how to wrap text in a span, but now I have a more specific problem that I do not know how to solve.
The code I wrote was:
var currentText = $("#"+v[4]["element"]+"").text();
var newText = currentText.substring(0, v[5]["start"]) + "<span class=' annotation' >" + currentText.substring(v[5]["start"], v[6]["end"]) + "</span>" + currentText.substring(v[6]["end"], currentText.length);
$("#"+v[4]["element"]+"").html(newText);
Where:
v[4]["element"] is the id of the parent element of the annotation
v[5]["start"] is the position of the first character of the annotation
v[6]["end"] is the position of the last character of the annoation
Note that start and end don't consider html tags.
In fact my mistake consists in extracting data from the node with the text() method (to be able to go back to the correct position of the annotation) and put back with the html() method; but in this manner if parent node has children nodes, they will be lost and overwritten by simple text.
Example:
having an annotation on '2003'
<p class="metadata-entry" id="k673f4141ea127b">
<span class="generated" id="bcf5791f3bcca26">Publication date (<span class="data" id="caa7b9266191929">collection</span>): </span>
2003
</p>
It becomes:
<p class="metadata-entry" id="k673f4141ea127b">
Publication date (collection):
<span class="annotation">2003</span>
</p>
I think I should work with nodes instead of simply extract and rewrite the content, but I don't know how to identify the exact point where to insert the annotation without considering html tags and without eliminating child elements.
I read something about the jQuery .contents() method, but I didn't figure out how to use it in my code.
Can anyone help me with this issue? Thank you
EDIT: Added php code to extract body of the page.
function get_doc_body(){
if (isset ($_GET ["doc_url"])) {
$doc_url = $_GET ["doc_url"];
$doc_name = $_GET ["doc_name"];
$doc = new DOMDocument;
$mock_doc = new DOMDocument;
$doc->loadHTML(file_get_contents($doc_url.'/'.$doc_name));
$doc_body = $doc->getElementsByTagName('body')->item(0);
foreach ($doc_body->childNodes as $child){
$mock_doc->appendChild($mock_doc->importNode($child, true));
}
$doc_html = $mock_doc->saveHTML();
$doc_html = str_replace ('src="images','src="'.$doc_url.'/images',$doc_html);
echo($doc_html);
}
}
Instead of doing all these, you can either use $(el).append() or $(el).prepend() for inserting the <span> tag!
$("#k673f4141ea127b").append('<span class="annotation">2003</span>');
Or, If I understand correctly, you wanna wrap the final 2003 with a span.annotation right? If that's the case, you can do:
$("#k673f4141ea127b").contents().eq(1).wrap('<span class="annotation" />');
Fiddle:
$(document).ready(function() {
$("#k673f4141ea127b").contents().eq(1).wrap('<span class="annotation" />');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="metadata-entry" id="k673f4141ea127b">
<span class="generated" id="bcf5791f3bcca26">Publication date (<span class="data" id="caa7b9266191929">collection</span>): </span>
2003
</p>
At the end my solution is in this Fiddle.
Generalizing:
var element = document.getElementById(id);
var totalText = element.textContent;
var toFindText = totalText.substring(start,end);
var toReplaceText = "<span class='annotation'>"+toFindText+"</span>";
element.innerHTML = element.innerHTML.replace(toFindText, toReplaceText);
Hope it could help someone else.
Note: This don't check if two or more annotations refers to the same node, I'm working on it right now.

How can I dynamically wrap elements in a div within another div?

I have the following output of WordPress content:
link1
text1
<br>
<br>
link2
text2
<br>
<br>
link3
text
<br>
<br>
link4
text4
<br>
<br>
I DO NOT have access to edit the content so I'm looking to edit this via jQuery. I need to wrap each link with the text and br before next link in a div and then split it in two columns. So the final result would be something like this:
<div class="col-left">
<div class="item">
link1
text1
<br>
<br>
</div>
<div class="item">
link2
text2
<br>
<br>
</div>
</div>
<div class="col-right">
<div class="item">
link3
text3
<br>
<br>
</div>
<div class="item">
link4
text4
<br>
<br>
</div>
</div>
Any idea how can I achieve this using jQuery?
I have tried using .wrap() like this:
$('a').wrap( "<div class='item'></div>" );
That's a pretty fun challenge.
A quick explanation...
jQuery appears to struggle when getting text elements which aren't wrapped in any tag, so we must fist wrap them. I've used a <span>. I've used the code from this post to do that.
Now that they're all wrapped up nicely, we can select the elements we're interested in, and find the halfway point. If we have an odd number, let's call Math.ceil, so that the extra one ends up in the Left column.
var a = $('a');
var i = Math.ceil(a.length/2);
Now let's just get the first column and second column elements by calling $.slice.
var firstColEls = a.slice(0,i);
var secondColEls = a.slice(i);
We can now loop through the elements and add the <div> with the item class. I'm using itemC1 and itemC2 so we can quickly select all the grouped elements later on. The class can have the same styling.
$.each(firstColEls, function(idx,el){
$(el).nextUntil('a').addBack().wrapAll('<div class="itemC1"></div>');
});
$.each(secondColEls, function(idx,el){
$(el).nextUntil('a').addBack().wrapAll('<div class="itemC2"></div>');
});
Now let's select the items, and wrap all of them (together) in the left/right column divs!
$('.itemC1').wrapAll('<div class="l"></div>');
$('.itemC2').wrapAll('<div class="r"></div>';
Wasn't that fun? :). Working Fiddle.
Have you tried setting a variable like so:
if (check how many links) {
var wrapLinkLeft = $('<div class="col-left"><div class="item">link1<br><br></div></div>');
var wrapLinkRight = $('<div class="col-right"><div class="item">link2<br><br></div></div>');
$(wrapLinkLeft).appendTo('body'); //for example append it to the body
}
to make the link dynamic leave it empty and just append it to the href, which means you will probably need to set a class or ID for this href or build a counter to keep track of where the scripts at.
This is the closest I could get. It gives the desired outcome, but I'm not sure that it's terribly flexible.
var textNodes = $('a').first().parent().contents().filter(function() {
return this.nodeType === 3 && $(this).text() !== "\n";
});
$(textNodes).each(function() {
$(this).wrap('<span></span>');
});
var groups = $('a');
$(groups).each(function(index, item) {
$(item).before('<div class="item"></div>');
var theDiv = $(item).prev();
var theItem = $(item).detach();
var theRest = theDiv.nextUntil('a').detach();
theDiv.append(theItem);
theDiv.append(theRest);
theDiv.find('span').contents().unwrap();
});
var theDivs = $('.item');
var half = theDivs.length / 2;
$(theDivs).first().before('<div class="col-left"></div><div class="col-right"></div>');
var i;
for (i = 0; i < half; i++)
{
var nextDiv = $(theDivs[i]).detach();
$('.col-left').append(nextDiv);
}
for (; i < theDivs.length; i++)
{
var nextDiv = $(theDivs[i]).detach();
$('.col-right').append(nextDiv);
}
And here's the JSFiddle. Cheers.

jQuery find and replace string

I have somewhere on website a specific text, let's say "lollypops", and I want to replace all the occurrences of this string with "marshmellows". The problem is that I don't know where exactly the text is. I know I could do something like:
$(body).html($(body).html().replace('lollypops', 'marshmellows'));
This would probably work, but I need to rewrite as little HTML as I can, so I'm thinking something like:
search for the string
find the closest parent element
rewrite only the closest parent element
replace this even in attributes, but not all, for example replace it in class, but not in src
In example, I would have structure like this
<body>
<div>
<div>
<p>
<h1>
<a>lollypops</a>
</h1>
</p>
<span>lollypops</span>
</div>
</div>
<p>
<span class="lollypops">Hello, World!</span>
<img src="/lollypops.jpg" alt="Cool image" />
</p>
<body>
In this example, every occurrence of "lollypops" would be replaced, only <img src="... would remain the same and the only elements that would actually be manipulated would be <a> and both <span>s.
Does anybody know how to do this?
You could do something like this:
$("span, p").each(function() {
var text = $(this).text();
text = text.replace("lollypops", "marshmellows");
$(this).text(text);
});
It will be better to mark all tags with text that needs to be examined with a suitable class name.
Also, this may have performance issues. jQuery or javascript in general aren't really suitable for this kind of operations. You are better off doing it server side.
You could do something this way:
$(document.body).find('*').each(function() {
if($(this).hasClass('lollypops')){ //class replacing..many ways to do this :)
$(this).removeClass('lollypops');
$(this).addClass('marshmellows');
}
var tmp = $(this).children().remove(); //removing and saving children to a tmp obj
var text = $(this).text(); //getting just current node text
text = text.replace(/lollypops/g, "marshmellows"); //replacing every lollypops occurence with marshmellows
$(this).text(text); //setting text
$(this).append(tmp); //re-append 'foundlings'
});
example: http://jsfiddle.net/steweb/MhQZD/
You could do something like this:
HTML
<div class="element">
<span>Hi, I am Murtaza</span>
</div>
jQuery
$(".element span").text(function(index, text) {
return text.replace('am', 'am not');
});
Below is the code I used to replace some text, with colored text. It's simple, took the text and replace it within an HTML tag. It works for each words in that class tags.
$('.hightlight').each(function(){
//highlight_words('going', this);
var high = 'going';
high = high.replace(/\W/g, '');
var str = high.split(" ");
var text = $(this).text();
text = text.replace(str, "<span style='color: blue'>"+str+"</span>");
$(this).html(text);
});
var string ='my string'
var new_string = string.replace('string','new string');
alert(string);
alert(new_string);
Why you just don't add a class to the string container and then replace the inner text ? Just like in this example.
HTML:
<div>
<div>
<p>
<h1>
<a class="swapText">lollipops</a>
</h1>
</p>
<span class="swapText">lollipops</span>
</div>
</div>
<p>
<span class="lollipops">Hello, World!</span>
<img src="/lollipops.jpg" alt="Cool image" />
</p>
jQuery:
$(document).ready(function() {
$('.swapText').text("marshmallows");
});

Categories

Resources