Cloning an element multiple times - javascript

I have a li element parented to a div with id holder. I need to clone the li multiple times, have all the clones parented to the holder div and change their data-ids. My hierarchy looks like this:
<div id="holder">
<li data-id=0 class="element">
//other nodes
</li>
</div>
How can I clone the li element and than change it's data-id so I get:
<div id="holder">
<li data-id=0 class="element">
//other nodes
</li>
<li data-id=1 class="element">
//other nodes
</li>
<li data-id=2 class="element">
//other nodes
</li>
<li data-id=3 class="element">
//other nodes
</li>
<li data-id=4 class="element">
//other nodes
</li>
<li data-id=5 class="element">
//other nodes
</li>
</div>
-- David

Just use clone and attr:
var holder, li, clone, counter;
holder = $("#holder");
li = holder.find("li:first");
counter;
for (counter = 1; counter <= 5; ++counter) {
clone = li.clone();
clone.attr("data-id", counter);
clone.appendTo(holder);
}

Here's a quick and dirty solution:
http://jsfiddle.net/Epzt9/7/
Also - and I'm surprised no-one else has mentioned this - your containing element for the list items should be a <ul>, not a <div> - <li> tags don't stand on their own, they should belong to a list.

Something along these lines should work:
var clone = $("#holder > li").last().clone();
clone.data("id", parseInt(clone.data("id"), 10) + 1);
$("#holder").append(clone);
It gets a reference to the last li child of #holder and clones that. It then adds 1 to the current value of the data-id attribute, and appends the clone back into #holder.
However, this won't actually change the value of the attribute on the element (if you inspected the DOM, clones would appear to have the same data-id value as the element from which they came). The new value is associated with the element, which is fine if you are using the jQuery data method to obtain this value later. If not, you would need to use attr instead of data to set the value.

Related

How to find certain text on child nodes using JavaScript when selecting by class name

I have multiple divs with the same structure as follows, I need to check for a text within the child nodes on each main div tag
<div class="s4-wpcell-plain">
<div class="ms-chrome">
<div class="ms-chrome-title" id="WPWPQ6_ChromeTitle">
<span title="My Content" id="WPTitleWPQ6" class="js-wp-titleCell">
<h2 style="text-align:justify;" class="ms-wp-titleText">Results (0)</h2>
</span>
</div>
<div wpid="50348231-8acb-4794-af32-d481915fc127" haspers="false" id="WPWPQ6" width="100%" class="ms-WPBody ms-WPBorder noindex ms-wpContentDivSpace " allowdelete="false" style="">
<div style="display: none;">
</div>
<div componentid="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr" id="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr">
<div class="containerForStyle">
<ul class="cbs-List">
<div class="ms-srch-result-noResults">There are no items to show. </div>
</ul>
</div>
</div>
</div>
</div>
</div>
In this case I'm selecting the main div with document.getElementsByClassName("s4-wpcell-plain") from there I need to check for the text "There are no items to show" and hide the corresponding main div.
I have tried to use
document.getElementsByClassName("s4-wpcell-plain").getElementsByTagName("*")
and after this, I will scan on each element on innerText but it is not getting the elements, any help would be appreciated.
I wasn't sure if you wanted .s4-wpcell-plain to disappear or the element that has the text so I wrote code for both objectives and commented out the part that hides .s4-wpcell-plain.
Trying to find a text in DOM is inefficient, you need to use whatever this widget uses and I can assure you it isn't the text it generates. The pattern looks like if there's no items to show the message would be in a div with the className of:
.ms-srch-result-noResults
I don't know how your widget works so I'm assuming that whenever there's no items to show then it creates:
<div class="ms-srch-result-noResults">There are no items to show. </div>
The Demo:
Collects all .ms-srch-result-noResults into a NodeList with document.querySelectorAll()
Makes that NodeList into an array with Array.from()
Runs the array thru forEach() array method.
On each .ms-srch-result-noResults is sets style.display to none
There's also an alternate forEach() method setup to use closest() to find .s4-wpcell-plain and then hide that instead.
Demo
Details commented in Demo
/* Collect all .ms-srch-result-noResults into a NodeList
|| then convert that NodeList into an array
*/
var noResults = Array.from(document.querySelectorAll('.ms-srch-result-noResults'));
/* Run the array thru forEach() method
|| hide each .ms-srch-result-noResults
*/
noResults.forEach(function(v, i) {
v.style.display = 'none';
});
/*//Or do the same thing but hide the .s4-wpcell-plain instead
noResults.forEach(function(v, i) {
var main = v.closest('.s4-wpcell-plain');
main.style.display = 'none';
});
*/
<div class="s4-wpcell-plain">
<div class="ms-chrome">
<div class="ms-chrome-title" id="WPWPQ6_ChromeTitle">
<span title="My Content" id="WPTitleWPQ6" class="js-wp-titleCell">
<h2 style="text-align:justify;" class="ms-wp-titleText">Results (0)</h2>
</span>
</div>
<div wpid="50348231-8acb-4794-af32-d481915fc127" haspers="false" id="WPWPQ6" width="100%" class="ms-WPBody ms-WPBorder noindex ms-wpContentDivSpace " allowdelete="false" style="">
<div style="display: none;">
</div>
<div componentid="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr" id="ctl00_ctl40_g_50348231_8acb_4794_af32_d481915fc127_csr">
<div class="containerForStyle">
<ul class="cbs-List">
<li class="ms-srch-result-noResults">There are no items to show. </li>
</ul>
</div>
<ul class="cbs-List">
<li class="ms-srch-result-results">There are items to show. </li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
</ul>
</div>
<ul class="cbs-List">
<li class="ms-srch-result-results">There are items to show. </li>
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
</ul>
</div>
<ul class="cbs-List">
<li class="ms-srch-result-noResults">There are no items to show. </li>
</ul>
</div>
</div>
innerText returns text content of all of its nested childrens
try:
var elements = document.getElementsByClassName("s4-wpcell-plain");
for (var i = 0; i < elements.length; i++) {
if (elements[i].innerText.indexOf('There are no items to show') !== -1) {
elements[i].style.display = 'none';
}
}
So here are the things you may follow,
1 - Get the list of elements with document.getElementsByTagName
2 - You can use iterate over, to filter out with the innerText && ClassName for each element
CODE:
// Get the elements list by ClassName
var allEles = documents.getElementsByTagName("*");
var templateString = 'Something';
var wantedClassName = 'ClassName';
// Iterate over all the elements
for(var key in allEles) {
if( (a[key].className === wantedClassName) && (a[key].innerText) === templateString ) {
/* Do Whatever you want with this element => a[key] */
}
}
`

Javascript - get child of child

How can I set the innner html of a span element in dom that is under li>a>?
<li class="first">
<a>
<span aria-hidden="true">1</span>
</a>
</li>
I have tried something like this, but nothing was written:
element[i].childNodes[1].children.innerHTML = number;
children is an HTMLCollection. innerHTML only applies to HTML elements. You need to find the HTML element in the children before using innerHTML.
It doesn't make a lot of sense to mix the use of childNodes and children. Use the former for more compatibility across browsers, use the latter for a simpler approach that lets you consider only element nodes.
var li = document.querySelector("li");
var number = 13;
li.children[0].children[0].innerHTML = number;
<ul>
<li class="first">
<a>
<span aria-hidden="true">1</span>
</a>
</li>
</ul>
Alternatively, you could just use querySelector:
var li = document.querySelector("li");
var number = 13;
li.querySelector("a").innerHTML = number;
<ul>
<li class="first">
<a>
<span aria-hidden="true">1</span>
</a>
</li>
</ul>
I recommend using jQuery (http://jquery.com)
and then use can simply do
$('li > a > span').html('THE INNER HTML HERE');
or
$('li > a').find('span').html('THE INNER HTML HERE');
you can use .first() to the result of find() function to get the first element

Append a child element to another div while having a reference to the orginal parent element

I have this html code
<div id="left-container" class="w3-container w3-left">
<div class="wordDiv w3-container w3-pale-green w3-leftbar w3-border-green w3-hover-border-red">
<h1>Give</h1>
<h3>Selected Definition:</h3>
<ul style="display:none;">
<li> offer in good faith </li>
<li> inflict as a punishment </li>
<li> afford access to </li>
</ul>
</div>
<div class="wordDiv w3-container w3-pale-green w3-leftbar w3-border-green w3-hover-border-red">
<h1>Up</h1>
<h3>Selected Definition:</h3>
<ul style="display:none;">
<li> to a higher intensity </li>
<li> to a later time </li>
<li> used up </li>
</ul>
</div>
</div>
<div id="right-container" class="w3-container w3-right"></div>
I want the user, once he click on one of the wordDiv's, to be able to see the potential definitions of that word in the right container (which are found in the "ul" element of each "wordDiv"), select one of the definitions, then I want to display the selected definition in the original wordDiv in the left-container.
You can found Jsfiddle Demo Here
A solution using jQuery. Updated Fiddle
$(function() {
$('.wordDiv').click(function() {
var txt = $(this).find('ul').html();
$('#right-container').html('<ul>' + txt + '</ul>')
})
})
Please check this fiddle
I have added li elements to another div based on the div which you are selected.
You can use the jQuery this variable in the click function, here is a working jQuery example of your request Updated Fiddle
It puts the li elements in the right div AND adds the onclick listener, which has the knowlege of its origin ;)
$('h1').click(function(){
var origin=$(this);
$(this).siblings('ul').children().click(function(){
$(this).parent().hide();
$(origin).parent().append(this);
$(this).replaceWith($('<div>' + this.innerHTML + '</div>'))
})
$(this).siblings('ul').show();
$("#right-container").append($(this).siblings('ul'));
})
$('ldi').click(function(){
$(this).parent().hide();
$(this).parent().parent().append(this);
$(this).replaceWith($('<div>' + this.innerHTML + '</div>'))
})

Iterate through a list of elements and hide them

In javascript (jquery), I'm retrieving a list of elements that start with "#error-". This works correctly. The problem I have is that I can't assign a value to elements of the array while looping through it.
I'm using this function:
function HideErrorMessages(){
var errors = $('*[id^="error-"]');
for (var i = 0; i < errors.length; i++) {
errors[i].css('display', none);
}
}
As you can see, I tried this "css" possibility. Doesn't work.
I also tried:
errors[i].hide();
errors[i].style.display = 'none';
But when using " alert(errors[i]) ", I get a response which indicates that it contains a list of "span" elements (which is correct).
So how can I do to hide elements in this loop?
Thanks!
Try to invoke .hide() over the jquery object,
$('[id^="error-"]').hide();
You don't need to iterate over that elements one by one. If you fetch elements from a jquery object by bracket notation, then it will return native javascript DOM node. So .css() will cause error as it is not a part of a DOM node.
errors[i] makes reference to a property inside the jQuery object which is a selected DOM object. There's no css function for those objects, it's a jQuery thing. But you can use jQuery eq to select the object and have access to jQuery methods:
errors.eq(i).css('display', 'none');
You can also use each to iterate each element of the jQuery object:
$('*[id^="error-"]').each(function(){
$(this).css('display', 'none');
});
I would go like this.
$('#buttonClick').on('click', function() {
var showing = $(this).closest('.thumbBrowser').find('ul li:visible');
var next = showing.last().next();
if( next.length === 0 ) {
next = $(this).closest('.thumbBrowser').find('ul li').first();
}
next.toggleClass('hidden').next().toggleClass('hidden');
showing.toggleClass('hidden');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="thumbBrowser">
<ul>
<li class="thumbLeft caseStudy tint tintWhite">
<img src="images/argus_thumb.jpg" alt="one">
</li>
<li class="thumbRight caseStudy tint">
<img src="images/adr_thumb.jpg" alt="two">
</li>
<li class="hidden thumbLeft caseStudy tint tintWhite">
<img src="images/dd_thumb.jpg" alt="three">
</li>
<li class="hidden thumbRight caseStudy tint">
<img src="images/cdp_thumb.jpg" alt="four">
</li>
<li class="hidden thumbRight caseStudy tint tintWhite">
<img src="images/pm_thumb.jpg" alt="five">
</li>
<li class="hidden thumbLeft caseStudy tint tintWhite">
<img src="images/argus_thumb.jpg" alt="six">
</li>
</ul>
<div class="cycleButton" id="buttonClick"><img src="images/cycleIcon.png"></div>
</div>
.hidden {
display:none;
}

Weird behavior with .parents() and .closest() when trying to return parent <ul> element id in jQuery

So I've got 2 <ul> containers each with id's. Inside of them are a list of <li> elements.
The first <ul> is <ul id="coaches-list">. The second is <ul id="players-list">.
There are tags within each <li> that have an id called close (which is a link that I'm using as my selector), which will delete each <li> node once clicked. I'm trying to target each <ul> container to see where it is coming from.
My HTML is:
<!-- coaches box -->
<div class="box">
<div class="heading">
<h3 id="coaches-heading">Coaches</h3>
<a id="coaches" class="filter-align-right">clear all</a>
</div>
<ul id="coaches-list" class="list">
<li><span>Hue Jackson<a class="close"></a></span></li>
<li class="red"><span>Steve Mariuchi<a class="close"></a> </span></li>
</ul>
</div>
<!-- players box -->
<div class="box">
<div class="heading">
<h3 id="players-heading">Players</h3>
<a id="players" class="filter-align-right">clear all</a>
</div>
<ul id="players-list" class="list">
<li><span>Steve Young<a class="close"></a></span></li>
<li><span>Gary Plummer<a class="close"></a></span></li>
<li><span>Jerry Rice<a class="close"></a></span></li>
</ul>
</div>
My remove tag function in jQuery is:
function removeSingleTag() {
$(".close").click(function() {
var $currentId = $(".close").closest("ul").attr("id");
alert($currentId);
// find the closest li element and remove it
$(this).closest("li").fadeOut("normal", function() {
$(this).remove();
return;
});
});
}
Whenever I click on each specific tag, it's removing the proper one I clicked on, although when I'm alerting $currentId, if I have:
var $currentId = $(".close").closest("ul").attr("id");
It alerts 'coaches-list' when I'm clicking on a close selector in both <ul id="coaches-list" class="list"></ul> and <ul id="players-list" class="list"></ul>
If I change that to:
var $currentId = $(".close").parents("ul").attr("id");
It has the same behavior as above, but alerts 'players-list', instead.
So when using closest(), it's returning the very first <ul> id, but when using parents(), it's returning the very last <ul> id.
Anyone know what is going on with this whacky behavior?
It's expected behavior.
You should use:
var $currentId = $(this).closest("ul").attr("id");
$(this) points at the clicked .close.
$(".close") points at the first one found.
It's because you run that selector from click handler you should use this instead:
var $currentId = $(this).closest("ul").attr("id");
Try using this function to get the parent:
var $currentId = $(this).parents().first();
I've never used the .closest() function but according to jQuery what you have specified should work. Either way, try that out and tell me how it goes.
You also need to make it so that it selects the current element by using $(this)

Categories