jQuery update html element text without affect the HTML children elements - javascript

I have a litle problem and I don't know how to fix it.
I have an HTML hierarchy like the one here
<ul id="mylist">
<li id="el_01">
<div class="title">
Title Goes Here
<span class="openClose"></span>
</div>
</li>
</ul>
What I like to do is to modify the "Title Goes Here".
What I have try is :
$('#el_01 title').text('New Title Goes Here');
But that also remove the :
<span class="openClose"></span>
Is there a way to update only the "Title Goes Here" without affect the span element ?

You can edit the text node directly by accessing the DOM element, and getting its firstChild.
$('#el_01 .title')[0].firstChild.data = 'New Title Goes Here';
If there are several .title elements, you can do it in an .each() loop.
$('#el_01 .title').each(function(i,el) {
el.firstChild.data = 'New Title Goes Here';
});

Two possible solution:
Either: Wrap the text in a span of its own:
<div class="title">
<span class="text">Title Goes Here</span>
<span class="openClose"></span>
</div>
... and update that:
$('#el_01 .text').text('New Title Goes Here');
Or: Keep a copy of the openClose span and re-insert it after updating the text:
var openClose = $('#el_01 .title .openClose');
$('#el_01 .title').text('New Title Goes Here').append(openClose);

Related

Javascript targeting the parent div from a string of text

<div class="myDiv">
<span class="mySpan">SAMPLE TEXT A</span>
<span class="mySpan">SAMPLE TEXT B</span>
</div>
I'm struggling to get the right javascript to hide "myDiv" if the text in "mySpan" is "SAMPLE TEXT A".
Somehow like this (you will not see anything, because <div class="myDiv"> is hidden already):
var spans = document.getElementsByClassName('mySpan')
for(var i = 0; i < spans.length; i++) {
if(spans[i].innerHTML === 'SAMPLE TEXT A') spans[i].parentElement.style.display = 'none';
}
<div class="myDiv">
<span class="mySpan">SAMPLE TEXT A</span>
<span class="mySpan">SAMPLE TEXT B</span>
</div>
UPDATE
"What is the significance of the 'for' statement?"
document.getElementsByClassName('mySpan') will select ALL elements with class mySpan, think about it as an array. Then i iterate through all selected span's and finding the case, where innerHTML is equal to our specific string.
"In the if statement, how would I specify just the parent div and not every element with class "myDiv"? There are other elements on the page with that class."
If so, you need to use parentElement (I have updated my answer with needed row).

Replace only text content inside DIV using JavaScript

I want to change only text content inside an h1 tag. Here's my code:
<h1 id="pageTitle" class="ms-core-pageTitle">
<span id="DeltaPlaceHolderPageTitleInTitleArea">
<span>
<span>
<a title="some title" href="/link/page.aspx">Change only this text and keep the rest</a>
</span>
</span>
</span>
</h1>
I've tried this code :
document.getElementById("DeltaPlaceHolderPageTitleInTitleArea").innerHTML = "text changed";
But it doesn't work, here's the result:
<h1 id="pageTitle" class="ms-core-pageTitle">
<span id="DeltaPlaceHolderPageTitleInTitleArea">text changed</span>
</h1>
Any help would be appreciated
You have to use querySelector() method, in order to change text content of hyperlink.
document.querySelector("#pageTitle a").innerHTML = "text changed";
<h1 id="pageTitle" class="ms-core-pageTitle">
<span id="DeltaPlaceHolderPageTitleInTitleArea">
<span>
<span>
<a title="some title" href="/link/page.aspx">Change only this text and keep the rest</a>
</span>
</span>
</span>
</h1>
What you are doing is changing "DeltaPlaceHolderPageTitleInTitleArea" 's innerHTML therefore you replace :
<span>
<span>
<a title="some title" href="/link/page.aspx">Change only this text and keep the rest</a>
</span>
</span>
with:
text changed
What you wanted to change is the title's text am I right ? To do so :
really basic JS:
document.getElementById("DeltaPlaceHolderPageTitleInTitleArea").children[0].children[0].children[0].innerHTML = "text changed";
a bit more advanced :
document.querySelector("DeltaPlaceHolderPageTitleInTitleArea > span > span > a").innerHTML = "text changed";
Or using jQuery :
$("DeltaPlaceHolderPageTitleInTitleArea > span > span > a").text("text changed");
You can try out this.
function changeContent(){
var element = document.getElementById('DeltaPlaceHolderPageTitleInTitleArea');
element.children[0].innerHTML = "whatever";
}
<h1 id="pageTitle" class="ms-core-pageTitle">
<span id="DeltaPlaceHolderPageTitleInTitleArea">
<a title="some title" href="/link/page.aspx">Change only this text and keep the rest</a>
</span>
<button name="change content" onClick="changeContent()">change content</button>
</h1>
You are pointing to the id of the h1 tag and not the anchor ()tag containing the text to be changed. this im not not sure will allow you to insert the text exactly where you want it to be. using the query selector or any other means of selecting the tag wrapping the text you what to change will surely do. if you dont mind, jquery selector will do the job much easier
you can try something like $("#DeltaPlaceHolderPageTitleInTitleArea a").text("")

Javascript to get link text

My HTML looks like this:
<div class="col-md-2" id="myName1">
<p>
Get This Text
</p>
</div>
The question is how do I get the text "Get this Text"
Something like this, but getting that text which is wrapped in the p and a tags:
function () {
return document.getElementById('TextID');
}
You can search for the first p inside your myName1 element, then the first a within that.
var e = document.getElementById('myName1').
getElementsByTagName('p')[0].
getElementsByTagName('a')[0];
var theText = e.innerHTML;
console.log(theText);
// or, in sufficiently-modern browsers
e = document.querySelector('#myName1 p a');
theText = e.innerHTML;
console.log( theText );
<div class="col-md-2" id="myName1">
<p>
Get This Text
</p>
</div>
Try adding the following in your function:
return document.querySelector('#myName1 p a').innerHTML
Simply using document.getElementById('anchorID').text; assuming anchor has id of anchorID. The text property sets or returns the text content of a link.
EDIT 1 : If you are not able to add the ID, then you need to take long path by going to document.getElementByID and then reach to the element using the document.getElementsByTagName
var myAnchor = document.getElementById("myName1").getElementsByTagName('p')[0].getElementsByTagName('a')[0];
console.log(myAnchor.text);
<div class="col-md-2" id="myName1">
<p>
<a id="anchorID" href="/something/121212">Get This Text</a>
</p>
</div>
you can use the get element by tag name method, but it returns an array of results so you will have to consider that, in your example, this works...
var a=document.getElementById('myName1');
console.log(a.getElementsByTagName('p')[0].getElementsByTagName('a')[0].innerHTML);
<div class="col-md-2" id="myName1">
<p>
Get This Text
</p>
</div>
Check this code, you can use innerHtml attribute
<script>
function gettext()
{
return document.getElementById('link').innerHTML;
}
</script>
<div class="col-md-2" id="myName1">
<p>
Get This Text
</p>
</div>
<script>
alert(gettext());
</script>
Or if you are using JQuery
$("#myName1 p a").text();

Jquery prepend based on own content

I need something in jQuery but can't figure it out.
I got this html:
<h2>My Name 1</h2>
<h2>My Name 2</h2>
// many more
In jQuery I want to get the content of this `h2' and need that for:
<h2>My Name 1</h2>
This is working:
jQuery(".content h2").prepend("<a href=''>").append("</a>");
But the href has to be based on its content... How to do that?
Thanks!
You can't append a chunk of HTML element like the half of a tag. Browser fixes such an invalid HTML and won't render it.
Use wrapInner method:
$('.content h2').wrapInner('');
If link href attribute somehow depends on actual h2 content then you should use function as wrapInner arguments, see Rory McCrossan's answer. For example to set href to be the same as h2 content it can be:
$('h2').wrapInner(function() {
return '';
});
I'm not sure that what you have is working as you expect because you can only append whole elements. Your current code would end up with something like this:
<h2>
<a href=''></a>
My name 1
<a></a>
</h2>
Given that you want to effectively wrap the text of the h2 in an a element you can use wrapInner() with a handler function containing the logic to set the href. Try this:
jQuery(".content h2").wrapInner(function() {
var href = 'foo.php'; // your logic here
return '';
});
Example fiddle
$(function () {
$(".content h2").each(function (n) {
var x =$('h2').eq(n).text();
var y = x.replace(/\s/g, '');
$(".content h2").eq(n).empty().append(""+x+"");
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="content">
<h2>My Names 1</h2>
<h2>My Names 2</h2>
<h2>My Names 3</h2>
<h2>My Names 4</h2>
<h2>My Names 5</h2>
</div>
Blockquote
So, grab the content of H2 and then append A with href and text as the grabbed content.
var h2Text = $(".content h2").text();
$(".content h2").empty().append( $("<a/>", { href: h2Text, text: h2Text }));
Try this..
$(document).ready(function(){
var href = 'test.html';
jQuery(".content h2").prepend("<a href='"+href+"'>").append("</a>");
});

How do I use a function argument for this jquery code, or is there a better solution?

I have about 50 p tags and next to these are again 50 divs. on click of each p tag, its div should be shown and the rest hidden. How do i acheive this. I can use something like below:
$(function() {
$('.p1').click(function(){
$('.div1').show();
$('.div2','.div3','.div4','.div5','.div6',.........,'.div50').hide()
})
$('.p2').click(function(){
$('.div2').show();
$('.div1','.div3','.div4','.div5','.div6',.........,'.div50').hide()
})
//////////////
//////
})
but as you see that this is not an effiecient solution. I am also not sure how the jquery each can be leveraged here or how can this implementation be done using arrays. Can somebody point me in the right direction. I think we should use a function and pass that no. as a parameter, but I dont know how to use custom functions in jquery.
UPDATE:
This is what I have done
$(function() {
$('.p1').click(function() {
$('.div').hide();
$('.d1').show();
})
})
I have added the class div to all of my 50 divs and I am showing d1 on click of p1. Now how do I replace 1 for each instance till 50.
I would have a common class to all div and p so that the binding the handler and the hide can be simple. And for the div, I would associate a data-tag to each p to link each p tag to div
<p class="p1 pclass" data-showdiv="div1">
...
</p>
<p class="p2 pclass" data-showdiv="div2">
..
<div class="mydiv div1" ..>
..
</div>
<div class="mydiv div2" ..>
..
</div>
And the script would be,
$(function() {
$('.pclass').click(function(){
$('.mydiv').hide();
$('.' + $(this).data('showdiv')).show();
});
});
As Jason told,
Use this
$('p').click(function() {
$('div').hide();
$(this).next('div').show();
});
If the div is next to each paragraph.
But, if there's an element between p and div, it wont work.
For you problem, you can do,
$('p').click(function() {
$('div').hide();
var divClass = $(this).attr("class").replace('p','div');
$('.' + divClass).show();
});
provided you have only p1, p2 .... in paragrah classes ;)
Update
See this fiddle
Notice , we have <br> tags between <p> and <div> as you wanted.
Assuming your HTML structure is
<p>Some text</p>
<div>More text to hide and show</div>
<p>Some text</p>
<div>More text to hide and show</div>
<p>Some text</p>
<div>More text to hide and show</div>
....
Use the following in your $(function(){}); method:
$('p').click(function() {
$('div').hide();
$(this).next('div').show();
});
var dvs = ['.div1','.div2','.div3','.div4','.div5','.div6',.........,'.div50'];
$('p').click(function() {
var index = parseInt(this.className.replace('p','')) - 1;
$(dvs[index]).show();
$(dvs.join(', ')).not(dvs[index]).hide();
});
The jQuery click event will automatically be registered on all elements that match the selector, so you shouldn't have to use the each() method. I would suggest having two CSS classes to distinguish between elements that have this toggling behaviour and elements that are primary (i.e. should be shown when their parent is clicked).
The markup:
<body>
<p class="togglable">
<div class="primary">
This is the primary div that will be shown when our parent is clicked.
</div>
<div>Regular div child</div>
<p>Nested paragraph</p>
<ul>
<li>A list perhaps</li>
</ul>
</p>
<p class="togglable">
<div class="primary">
This is the primary div that will be shown when our parent is clicked.
</div>
<div>Regular div child</div>
<p>Nested paragraph</p>
<ul>
<li>A list perhaps</li>
</ul>
</p>
<p>This is a normal paragraph</p>
</body>
The code:
$(function () {
$('.togglable').click(function () {
// hide all our children
$(this).children().hide();
// now only show our primary chlid
// NOTE: we pass 'this' as the second argument
// so that the selector will only apply to the
// children of the element that was clicked
// (i.e. we are providing a custom context for the selector).
$('.primary', this).show();
// You could even use the position of the child as well:
// $(this).children().first().show();
// This will show the first child element.
});
});
In this example all elements with the class togglable will show their primary child element when clicked and hide all other child elements.

Categories