Insert dynamically created list items in <ol> with jquery - javascript

I'm trying to come up with a script that locates a paragraph with a class=SO-Para-Numbered-List, takes out the span element turns the paragraph into an li and then creates an ol and adds all list items within it.
This is the HTML structure
<p class="SOPara">Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
<p class="SO-Para-Numbered-List"><span>i</span> some text </p>
<p class="SO-Para-Numbered-List"><span>ii</span> some text</p>
<p class="SO-Para-Numbered-List"><span>iii</span> some text </p>
<p class="SO-Para-Numbered-List"><span>iv</span> some text</p>
<p class="SO-Para-Numbered-List"><span>v</span> some text</p>
<p class="SO-Para-Numbered-List"><span>vi</span> some text</p>
<p class="SO-Para-Numbered-List"><span>vii</span> some text </p>
<p class="SOPara">Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
And the jquery script
$(document).ready(function(){
//create ol
$(".SO-Para-Numbered-List").first().before("<ol class='newList'>");
//for each para item
$(".SO-Para-Numbered-List").each(function(){
//remove span
$(this).find("span").remove();
//save the text
var thisContent = $(this).text();
//replace p with li
var newText = $(this).replaceWith("<li style='list-style-type:lower-roman;' class='SOlistItem'>"+thisContent+"</li>");
//add items to list
$("ol.newList").add(newText);
});
});
I guess what I'm going for should look something like this
<ol>
<li style="list-style-type:lower-roman;" class="SOlistItem"> some text </li>
<li style="list-style-type:lower-roman;" class="SOlistItem"> some text </li>
<li style="list-style-type:lower-roman;" class="SOlistItem"> some text </li>
<li style="list-style-type:lower-roman;" class="SOlistItem"> some text </li>
</ol>
I can't figure out how to add the li to the dynamically created ol. Any thoughts?
Is there a way of having the code do the same for each set of elements on the page i.e. create a new list with numbering starting from 1 but for each group of <p class="SO-Para-Numbered-List"><span>i</span> some text </p> it encounters?
I tried setting it so that is locates the previous SOPara which is a paragraph always preceding the ones I want to turn into list items but I'm stuck
$(document).ready(function(){
$(".SO-Para-Numbered-List").each(function(){
if($(this).prev("p").hasClass("SOPara")){
$(this).before("<ol class='newList'></ol>");
$(this).siblings().nextUntil(".SOPara").each(function(){
var $this = $(this);
$(this).find("span").remove();
var listContent = $(this).text();
var newListItem = $(this).replaceWith("<li>"+listContent+"</li>");
});//end siblings function
}//end if
})//end SO Para function
});

You can user insertBefore() to get a reference to the ul and then append the lis to that
$(document).ready(function() {
var $ul = $("<ol class='newList'>").insertBefore('.SO-Para-Numbered-List:first');
//for each para item
$(".SO-Para-Numbered-List").each(function() {
$(this).find("span").remove();
var thisContent = $(this).text();
$('<li />', {
'class': 'SOlistItem',
text: thisContent
}).css({
'list-style-type': 'lower-roman'
}).appendTo($ul);
}).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="SOPara">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p class="SO-Para-Numbered-List"><span>i</span> some text</p>
<p class="SO-Para-Numbered-List"><span>ii</span> some text</p>
<p class="SO-Para-Numbered-List"><span>iii</span> some text</p>
<p class="SO-Para-Numbered-List"><span>iv</span> some text</p>
<p class="SO-Para-Numbered-List"><span>v</span> some text</p>
<p class="SO-Para-Numbered-List"><span>vi</span> some text</p>
<p class="SO-Para-Numbered-List"><span>vii</span> some text</p>
<p class="SOPara">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>

$(".SO-Para-Numbered-List:first").before("<ol class='newList'>");
$("p.SO-Para-Numbered-List").each(function() {
var getText = $(this).clone().children().remove().end().text();
$(".newList").append('<li>'+getText+'</li>');
}).remove();
Working Fiddle : https://jsfiddle.net/ydfyh19g/1/

try the append function:
$(document).ready(function() {
$("<ol class='newList'>").insertBefore('.SO-Para-Numbered-List:first');
//for each para item
$(".SO-Para-Numbered-List").each(function(){
//remove span
$(this).find("span").remove();
//save the text
var thisContent = $(this).text();
//add items to list
$("ol.newList").append("<li style='list-style-type:lower-roman;' class='SOlistItem'>"+thisContent+"</li>");
$(this).remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="SOPara">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p class="SO-Para-Numbered-List"><span>i</span> some text</p>
<p class="SO-Para-Numbered-List"><span>ii</span> some text</p>
<p class="SO-Para-Numbered-List"><span>iii</span> some text</p>
<p class="SO-Para-Numbered-List"><span>iv</span> some text</p>
<p class="SO-Para-Numbered-List"><span>v</span> some text</p>
<p class="SO-Para-Numbered-List"><span>vi</span> some text</p>
<p class="SO-Para-Numbered-List"><span>vii</span> some text</p>
<p class="SOPara">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>

You're currently setting the list-style-type on the li elements, when it should be on the ol. Also the use of add() is not having the effect you're after, you should use append() instead.
To achieve what you require you can create a new ol and save it in a variable. This will then allow you to append() directly to it in the loop, while also removing the original SO-Para... elements. Try this:
var $ol = $('<ol class="newList">').insertBefore('.SO-Para-Numbered-List:first()');
$(".SO-Para-Numbered-List").each(function() {
$ol.append("<li>" + $(this).find('span').remove().end().text() + "</li>");
}).remove();
Working example

Related

Using .split to split up content in a string

Hi I've got a string where I want to spilt up the content "ipsum dolar" and wrap it into a span tag and have the background change to red. My code does this but it wraps the two words into separate span tags. How would i amend my code to wrap them into one span tag together? Any help on this would be appreciated.
var findWords = 'ipsum dolor';
var elem = document.querySelectorAll('p.content');
elem.forEach(function(el) {
el.innerHTML = el.textContent.split(' ').map(function(i) {
return findWords.indexOf(i) > -1 ? '<span class="matched">' + i + '</span>' : i;
}).join(' ');
});
.matched {background: red;}
<p class="content"> Lorem ipsum dolor sit amet</p>
<p class="content"> Lorem ipsum dolor sit amet</p>
Using .replace() will be better in this case:
var findWords = 'ipsum dolor';
var elem = document.querySelectorAll('p.content');
elem.forEach(function(el) {
el.innerHTML = el.textContent.replace(new RegExp(findWords, 'g'), '<span class="matched">' + findWords + '</span>');
});
.matched {background: red;}
<p class="content"> Lorem ipsum dolor sit amet</p>
<p class="content"> Lorem ipsum dolor sit amet ipsum dolor</p>

Replacing HTML footer content with JavaScript

I'm trying to replace my footer's text with "Hello World" and I do not want to edit the HTML by adding a class or an id
HTML:
<footer>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
</footer>
JavaScript:
document.getElementById(footer).innerHTML="Hello World";
The problem is that, when I do the code above, nothing is changing
footer is not the id of the element you are selecting, its the tag name.
You can use tag selector for selecting footer.
And to change the div content(i am assuming you want to change the text, keeping div as is), you can select div using the tag selector
and can change the text.
document.getElementsByTagName("footer")[0].getElementsByTagName("div")[0].innerHTML = "Hello World";
Above statement is broken down :
document.getElementsByTagName("footer") //select footer
document.getElementsByTagName("footer")[0] //1st matched element
document.getElementsByTagName("footer")[0].getElementsByTagName("div") // select div
document.getElementsByTagName("footer")[0].getElementsByTagName("div")[0] // first div
document.getElementsByTagName("footer")[0].getElementsByTagName("div")[0].innerHTML = "Hello World"; //change content
document.getElementsByTagName("footer")[0].getElementsByTagName("div")[0].innerHTML = "Hello World";
<footer>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
</footer>
It's because you are selecting id which doesn't exist, try this instead:
document.querySelector('footer').innerHTML = "Hello world";
#edit
document.querySelector('footer').innerHTML = "Hello world";
<footer>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
</footer>
There are a couple of ways by which you can achieve the desired:
1) If you need to change the HTML, you should use the below code for targeting the footer:
document.getElementsByTagName('footer')[0].innerHTML = '<div>Hello World</div>';
document.getElementsByTagName('footer')[0].innerHTML = '<div>Hello World</div>';
<footer>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
</footer>
2) If you wish to just modify the text, without changing the HTML, you can also make use of the following:
document.getElementsByTagName('footer')[0].innerText = 'Hello World';
document.getElementsByTagName('footer')[0].innerText = 'Hello World';
<footer>
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
</footer>
The difference between the two approaches is that the former keeps the text inside the div while the latter keeps inside footer tag itself.
If you look through inspection in the two, it will have an output like the below:
1)
<footer>
<div>
Hello World
</div>
</footer>
2)
<footer>
Hello World
</footer>

Contenteditable - How to remove html tag with selection text

how to remove html tag in contenteditable with selection text
function testdemo() {
//what is next
....
}
Before :
<button onclick="testdemo();">RUN</button>
<div id="test" contenteditable="true">
<b>Lorem ipsum</b> dolor sit amet, <span style="color:red;">ea ignota verear</span> quaerendum
</div>
After :
<div id="test" contenteditable="true">
Lorem ipsum dolor sit amet, ea ignota verear quaerendum
</div>
Thank you in advance
Try this:
JS:
function testdemo() {
var div = document.getElementById('test');
div.innerHTML = div.textContent;
}
Jquery:
function testdemo() {
$('#test').html($('#test').text());
}
jQuery version would be as below:
function testdemo() {
$("#test").html($("#test").text());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="testdemo();">RUN</button>
<div id="test" contenteditable="true">
</div>
function testdemo() {
var div = document.getElementById('test');
div.innerHTML = div.textContent;
}
<button onclick="testdemo();">RUN</button>
<div id="test" contenteditable="true">
<b>Lorem ipsum</b> dolor sit amet, <span style="color:red;">ea ignota verear</span> quaerendum
</div>
See if this helps.
function testdemo() {
$('#test').html($('#test').text()).text();​
}

Find parent of unwrapped element and use it in .wrap() using jquery

I have dynamically added div elements with structure as follows.
<div class="blogPost">
<a href="link/to/full_artical">
<h1>Some Heading</h1>
</a>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
I want to remove a wrappers from h1 elements and add them to parent div elements. The result should be like:
<a href="link/to/full_artical">
<div class="blogPost">
<h1>Some Heading</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
</a>
I wish there is a way in jquery maybe a combination of unwrap() and wrap() functions.
I do not have access to the source of this dynamically added content.
divs are being added dynamically.
Thanks in advance.
EDIT
tried
$('.blogPost').wrap('')
Not Working.
You can use .clone() to copying a element and store it in variable. Use .unwrap() to remove a parent of h1 and use .wrap() to wrapping copied element around .blogPost.
var clone = $("a").clone().children().remove().end();
$("h1").unwrap().parent().wrap(clone);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="blogPost">
<a href="link/to/full_artical">
<h1>Some Heading</h1>
</a>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
Another way:
var href = $('.blogPost').children('a').attr('href');
$('.blogPost').wrap('');
$('h1').unwrap();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="blogPost">
<a href="link/to/full_artical">
<h1>Some Heading</h1>
</a>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
var link = $('a'),
heading = link.find('h1'),
blogPost = $('.blogPost');
blogPost.prepend(heading);
blogPost.wrap(link);
link.remove();
CODEPEN

How to show child element when other child element is overflowing with JQuery

I have recently been working on a comment feature. By default, the height of the paragraph element containing the text is 80px. Overflow is set to hidden.
I have another button (labelled "See More") that expands the paragraph by changing height to 'auto'. This button should only be visible if the paragraph content is overflowing the default 80px height. Otherwise the button must not be displayed.
I have tried to do this with a javascript for loop and some JQuery code, though it doesn't work as it should. It shows or hides the button for all comment sections.
Here is the html:
<div class="commentOwnerPost">
<div class="commentPostHeader">
<h4 class="commentOwnerName">NavyFoxKid</h4>
<h4 class="commentPostDate">3 days ago</h4>
</div>
<p class="commentText"> lorem ipsum dolor sit amet consectur lorem ipsum dolor sit amet consectur
amet consectur lorem ipsum dolor sit amet consectur lorem ipsum
</p>
<div class="commentPostFooter">
<a class="btnReply">Reply</a>
<a class="btnSeeMore">See More</a>
</div>
</div>
Here is the JavaScript:
$(document).ready(function(){
var element = $('.commentOwnerPost');
for(i=0; i < element.length; i++){
var commentText = $(element[i]).children('.commentText');
if ($(commentText).offsetHeight < $(commentText).scrollHeight) {
$parent = $(commentText).parent('.commentOwnerPost');
$parent.find('.btnSeeMore').hide();
console.log('Comment text not overflowing ');
} else {
$parent = $(commentText).parent('.commentOwnerPost');
$parent.find('.btnSeeMore').show();
console.log('Comment text overflowing ');
}
$('.btnSeeMore').click(function(){
});
}
});
Thanks for taking the time to read. Any help would be appreciated.
It works perfectly for me, I simplify your code:
$(document).ready(function(){
var elements = $('.commentOwnerPost');
elements.each(function() {
var el = $(this).find('.commentText').get(0);
if(el.offsetHeight < el.scrollHeight) {
$(this).find('.btnSeeMore').show();
} else {
$(this).find('.btnSeeMore').hide();
}
});
});
.commentText { max-height: 25px; overflow:hidden;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="commentOwnerPost">
<div class="commentPostHeader">
<h4 class="commentOwnerName">NavyFoxKid</h4>
<h4 class="commentPostDate">3 days ago</h4>
</div>
<p class="commentText"> lorem ipsum dolor sit amet consectur lorem ipsum dolor sit amet consectur
amet consectur lorem ipsum dolor sit amet consectur lorem ipsum
</p>
<div class="commentPostFooter">
<a class="btnReply">Reply</a>
<a class="btnSeeMore">See More</a>
</div>
</div>
<div class="commentOwnerPost">
<div class="commentPostHeader">
<h4 class="commentOwnerName">NavyFoxKid</h4>
<h4 class="commentPostDate">3 days ago</h4>
</div>
<p class="commentText"> lorem ipsum dolor sit amet.
</p>
<div class="commentPostFooter">
<a class="btnReply">Reply</a>
<a class="btnSeeMore">See More</a>
</div>
</div>

Categories

Resources