Appending clone to a div by for loop not working - javascript

Below javascript code is for cloning the clonedInput1. But below code only creating and appends one clone. But year_no is 3.
cloneid = 0;
function clone_year(year_no)
{
cloneid += 1;
var container = document.getElementById('clone_div');
var clone = $('#clonedInput1').clone();
for (i = 0; i < year_no; i++) {
$('.clone_div').append(clone);
}
}
This is the html code for above code.
<div id="year_sem_details" style="display:none">
<div class="form-group">
<div class="clone_div" id="clone_div">
<div id="clonedInput1" class="clonedInput row">
<div class="row">
<!-- here some html -->
</div>
</div>
</div>
</div>
</div>
Please Help me on this.

cloneid = 0;
function clone_year(year_no)
{
cloneid += 1;
var container = document.getElementById('clone_div');
//var clone = $('#clonedInput1').clone();
for (i = 0; i < year_no; i++) {
$('.clone_div').append($('#clonedInput1').clone());
}
}
clone_year(3);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="year_sem_details" style="display:block">
<div class="form-group">
<div class="clone_div" id="clone_div">
<div id="clonedInput1" class="clonedInput row">1
<div class="row">
<!-- here some html -->
</div>
</div>
</div>
</div>
</div>
Please check this.

You're appending the same element (clone) to $('.clone_div'). For each iteration, clone a new element.
for (i = 0; i < year_no; i++) {
$('.clone_div').append($('#clonedInput1').clone());
}

Try using an ID selector like $('#clonedInput1').clone() so you will append a new element on each iteration:
function clone_year(year_no)
{
var container = document.getElementById('clone_div');
var clone = $('#clonedInput1').clone();
for (i = 0; i < year_no; i++) {
$('#clone_div').append($('#clonedInput1').clone());
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group">
<div class="clone_div" id="clone_div">
<div id="clonedInput1" class="clonedInput row">
Hello
</div>
</div>
</div>
<input type='button' onclick='clone_year(3);' value='go' />

Here you go with a solution https://jsfiddle.net/u5zw67v3/
cloneid = 1;
function clone_year(year_no) {
for (i = 0; i < year_no; i++) {
cloneid++;
$('.clone_div').append($('#clonedInput1').clone());
$('.clone_div').find('.clonedInput').last().attr('id', 'clonedInput' + cloneid);
}
}
clone_year(3);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="year_sem_details">
<div class="form-group">
<div class="clone_div" id="clone_div">
<div id="clonedInput1" class="clonedInput row">
<div class="row">
here some html
</div>
</div>
</div>
</div>
</div>
Your id should be unique.
Hope this will help you.

Related

Adding a css class to a html div that is only defined by the combination of css classes it uses with javascript

I have a website with a few sections that look as following:
...
<div class="row docutils">
...
</div>
...
I would like to use javascript to add a custom css class to them so they looks like this:
...
<div class="row docutils my-class">
...
</div>
...
I have tried adding a js file in the same directory and added a script reference, however this approach didn't have any effect:
$(document).ready(function () {
var testarray = document.getElementsByClassName("row docutils");
for(var i = 0; i < testarray.length; i++)
{
testarray[i].className += "my-class";
}
});
Is there a better way to solve this problem?
You have to prepend a space, since classes are delimited by a space.
var testarray = document.getElementsByClassName("row docutils");
for (var i = 0; i < testarray.length; i++) {
testarray[i].className += " my-class";
}
.my-class {
background-color: red;
}
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
Although you should be using classList.add instead:
var testarray = document.getElementsByClassName("row docutils");
for (var i = 0; i < testarray.length; i++) {
testarray[i].classList.add("my-class");
}
.my-class {
background-color: red;
}
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
If you want to do it with jQuery:
$('.row.docutils').addClass('my-class');
.my-class {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
<div class="row docutils">
...
</div>
this is a one expression pure vanilla answer
Array.from(document.querySelectorAll('.row.docutils')).forEach(
current => current.classList.add('my-class')
)
In most browser you don't even need to cast the NodeList returned from Element.prototype.querySelectorAll to an array, so you can remove the Array.from(...) part, resulting in
document.querySelectorAll('.row.docutils').forEach(
current => current.classList.add('my-class')
)
Since you're already using jQuery target the elements with those classes, and use addClass.
$('.row.docutils').addClass('red');
.red { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row docutils">One</div>
<div class="row">Two</div>
<div class="row docutils">Three</div>
Try this.
$(document).ready(function () {
var testarray = document.querySelectorAll(".row.docutils");
for(let i = 0; i < testarray.length; i++){
testarray[i].classList.add("my-class");
}
});

Amp-script does not show the result for addEventListener "load"

I want to copy all A to B. Using plain javascript, it works as it is. But it does not work when I use amp-script. It also doesn't show any error(s).
A
<div class="harga">111</div>
<div class="harga">222</div>
<div class="harga">333</div>
B
<div class="showHargaProd"></div>
<div class="showHargaProd"></div>
<div class="showHargaProd"></div>
Javascript
<script>
function getAndShow(){
let sources = document.querySelectorAll('.harga');
let dests = document.querySelectorAll('.showHargaProd');
for (let i = 0; i < sources.length; i++){
if (dests[i]){
dests[i].innerHTML = sources[i].innerHTML;
}
}
}
document.addEventListener('DOMContentLoaded', getAndShow);
</script>
Here's all my codes
<amp-script layout='container' script='inline_amp'>
<div class='container_slide'>
<div class='prod_price'><b class='showHargaProd'><!--111--></b></div>
<div class='overlay'>
<div class='text'><b>BELI</b></div>
</div>
</div>
<div class='container_slide'>
<div class='prod_price'><b class='showHargaProd'><!--222--></b></div>
<div class='overlay'>
<div class='text'><b>BELI</b></div>
</div>
</div>
<div class='container_slide'>
<div class='prod_price'><b class='showHargaProd'><!--333--></b></div>
<div class='overlay'>
<div class='text'><b>BELI</b></div>
</div>
</div>
<p id="hrg1" class="harga">111</p>
<p id="hrg2" class="harga">222</p>
<p id="hrg3" class="harga">333</p>
</amp-script>
<script id="inline_amp" type="text/plain" target="amp-script">
function getAndShow(){
let sources = document.querySelectorAll('.harga');
let dests = document.querySelectorAll('.showHargaProd');
for (let i = 0; i < sources.length; i++){
if (dests[i]){
dests[i].innerHTML = sources[i].innerHTML;
}
}
}
document.addEventListener('DOMContentLoaded', getAndShow);
</script>
Finally I use time (seconds) to trigger the DOM, as in:
HTML
<input id='nTrigger' name='nTrigger' type='hidden' value='0'/>
<input id='nCheck' name='nCheck' type='hidden' value=''/>
JS
var dy = new Date();
var n = dy.getSeconds();
var trig = document.getElementById('nTrigger').value;
document.getElementById('nCheck').value = n;
if (trig !== n) getAndShow();
Here's trig would never equal as n forever since seconds has no zero value and it will show the result I wish.
Stupid of me, I actually can use directly or call function getAndShow() when the layout is responsive with fixed height and width (size must be included).
What I want is how to load the class showHargaProd when user load the page, and It solved successfully.
Here's all the codes:
Note: layout='container' must be changed into layout='responsive' (see issue in related to layout system and gestures: https://github.com/ampproject/amphtml/issues/28361#issuecomment-628779575) and How to show popup on AMP page after setTimeout
Or, we can use flex-item Layout to make it properly in container
<amp-script layout='flex-item' script='inline_amp'>
<div class='container_slide'>
<div class='prod_price'><b class='showHargaProd'><!--111--></b></div>
<div class='overlay'>
<div class='text'><b>BELI</b></div>
</div>
</div>
<div class='container_slide'>
<div class='prod_price'><b class='showHargaProd'><!--222--></b></div>
<div class='overlay'>
<div class='text'><b>BELI</b></div>
</div>
</div>
<div class='container_slide'>
<div class='prod_price'><b class='showHargaProd'><!--333--></b></div>
<div class='overlay'>
<div class='text'><b>BELI</b></div>
</div>
</div>
<p id="hrg1" class="harga">111</p>
<p id="hrg2" class="harga">222</p>
<p id="hrg3" class="harga">333</p>
<input id='nTrigger' name='nTrigger' type='hidden' value='0'/>
<input id='nCheck' name='nCheck' type='hidden' value=''/>
</amp-script>
<script id="inline_amp" type="text/plain" target="amp-script">
function getAndShow(){
let sources = document.querySelectorAll('.harga');
let dests = document.querySelectorAll('.showHargaProd');
for (let i = 0; i < sources.length; i++){
if (dests[i]){
dests[i].innerHTML = sources[i].innerHTML;
}
}
}
//document.addEventListener('DOMContentLoaded', getAndShow);
var dy = new Date();
var n = dy.getSeconds();
var trig = document.getElementById('nTrigger').value;
document.getElementById('nCheck').value = n;
if (trig !== n) getAndShow();
</script>
More: (trig !== n) in fact, it would never equal and therefore, it triggers the function getAndShow() (that is almost the same as DOMContentLoaded).

How to remove div container from HTML but not its content

I have this structure:
<div clas="page_cat_list">
<div class="page_cat_row">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="clear_fix"></div>
</div>
<div class="page_cat_row">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="clear_fix"></div>
</div>
</div>
and I need it to look like this:
<div clas="page_cat_list">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
</div>
I can insert JavaScript in the HTML, but I can not change these elements directly, because it's generated by some kind of function.
You could arrive with this simple js approach:
var container = document.querySelector('.page_cat_list');
var contents = container.querySelectorAll('.page_cat_row');
var newContent = '';
[].forEach.call(contents, function(cont) {
newContent = newContent + cont.innerHTML;
})
container.innerHTML = newContent;
<div class="page_cat_list">
<div class="page_cat_row">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="clear_fix"></div>
</div>
<div class="page_cat_row">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="clear_fix"></div>
</div>
</div>
Loop over the elements and than loop over the children appending them to the parent element.
(function() {
var wrappers = document.querySelectorAll(".page_cat_row"); //grab the parent elements
//Loop over the collection
for (var i = wrappers.length - 1; i >= 0; i--) {
//get the element and its parent
var wrapperToBeRemoved = wrappers[i],
parentNode = wrapperToBeRemoved.parentNode
//loop over the children until they are all removed
while (wrapperToBeRemoved.firstChild) {
parentNode.insertBefore(wrapperToBeRemoved.firstChild,
wrapperToBeRemoved);
}
//remove the wrapper from the collection
parentNode.removeChild(wrapperToBeRemoved);
}
}());
.page_cat_row {
background-color: red;
}
<div clas="page_cat_list">
<div class="page_cat_row">
<div class="page_cat_item">1...</div>
<div class="page_cat_item">2...</div>
<div class="page_cat_item">3...</div>
<div class="clear_fix"></div>
</div>
<div class="page_cat_row">
<div class="page_cat_item">4...</div>
<div class="page_cat_item">5...</div>
<div class="page_cat_item">6...</div>
<div class="clear_fix"></div>
</div>
</div>
You can easily do this with a combination of detach() and html() in JQuery:
$(document).ready(function(){
var ele = $('.page_cat_row').children().detach();
$('.page_cat_row').remove();
$('.page_cat_list').html(ele);
});
See the JSFiddle: https://jsfiddle.net/w6gkf23d/
With this, you don't need to directly loop anything as JQuery does it all for you.
Note that you will still need to set the clear_fix class to display:none.
Simplest way is to use unwrap.
$('.page_cat_item').unwrap();
I think this is the easiest way to do this.
Move the first childNode to the parent until the wrapper element has children.
If you don't have text between the elements, you can use wrapper.children.length instead, because it's faster in that case.
function removeElement(element) {
element.parentElement.removeChild(element);
}
function removeWrapper(wrapper) {
while (wrapper.childNodes.length) {
wrapper.parentElement.appendChild(wrapper.childNodes[0]);
}
wrapper.parentElement.removeChild(wrapper);
}
var clrFix = document.querySelectorAll('.page_cat_row > .clear_fix');
for (var i = 0; i < clrFix.length; i++) {
removeElement(clrFix[i]);
}
var cat_rows = document.querySelectorAll('.page_cat_list > .page_cat_row');
for (var i = 0; i < cat_rows.length; i++) {
removeWrapper(cat_rows[i]);
}
.page_cat_row {
color: red;
}
<div class="page_cat_list">
<div class="page_cat_row">
<div class="page_cat_item">1...</div>
<div class="page_cat_item">2...</div>
<div class="page_cat_item">3...</div>
<div class="clear_fix">fix</div>
</div>
<div class="page_cat_row">
<div class="page_cat_item">4...</div>
<div class="page_cat_item">5...</div>
<div class="page_cat_item">6...</div>
<div class="clear_fix">fix</div>
</div>
</div>
JSFiddle
$( "#divid" ).load(function() {
$( this ).removeClass( "page_cat_row" );
});

How to reorder divs based on class names using Javascript

Here is my HTML
<div id="subscriptionContainer">
<div class="subscription">
<div class="subs-btn">
<div class="subscribed">Subscribed</div>
</div>
</div>
<div class="subscription">
<div class="subs-btn">
<div class="btnGetit">Get It</div>
</div>
</div>
<div class="subscription">
<div class="subs-btn">
<div class="subscribed">Subscribed</div>
</div>
</div>
<div class="subscription">
<div class="subs-btn">
<div class="btnGetit">Get It</div>
</div>
</div>
<div class="subscription">
<div class="subs-btn">
<div class="subscribed">Subscribed</div>
</div>
</div>
<div class="subscription">
<div class="subs-btn">
<div class="btnGetit">Get It</div>
</div>
</div>
</div>
Now I want to rearrange the "subscription" divs withing the "subscriptionContainer" such that the divs that have class = "subscribed" should be moved to bottom and the divs having class = "btnGetit" should all be moved up. Please give solutions in Javascript or JQuery.
var $wrap = $('#subscriptionContainer');
$wrap.find('.subscribed').parents('.subscription').appendTo( $wrap );
Demo: http://jsbin.com/ebudux/2/edit
Here is a pure JavaScript implementation that I finally worked out
var container = document.getElementById('subscriptionContainer');
var allDivs = container.getElementsByTagName('div');
var subsProds = new Array();
var count = 0;
for (i = 0; i < allDivs.length; i++)
{
var currentElement = allDivs[i];
if (currentElement.className == 'subscribed') {
subsProds[count] = currentElement.parentNode.parentNode;
container.removeChild(currentElement.parentNode.parentNode);
count++;
}
}
for (i = 0; i < subsProds.length; i++)
container.appendChild(subsProds[i]);
var $wrap = $('#subscriptionContainer');
$wrap.find('.subscription').children('.subscribed').appendTo( $wrap );

Jquery basic: How to randomize this array and still call all the parameters?

I have 2 divs, #col1 and #col2, that I need to generate some divs with fruit names in there.
So far I have:
var fruitArray = ['apples','banana','orange','grapes'];
for (fruit in fruitArray) {
$('<div class="'+fruitArray[fruit]+'"></div>').appendTo('#col1').doSomething();
$('<div id="'+fruitArray[fruit]+'"></div>').appendTo('#col2').doSomething();
}
Which turns out like:
<div id="#col1">
<div class="apples"></div>
<div class="banana"></div>
<div class="orange"></div>
<div class="grapes"></div>
</div>
<div id="#col2">
<div id="apples"></div>
<div id="banana"></div>
<div id="orange"></div>
<div id="grapes"></div>
</div>
How do I randomize the array so it looks something like:
<div id="#col1">
<div class="orange"></div>
<div class="apples"></div>
<div class="orange"></div>
<div class="grapes"></div>
</div>
<div id="#col2">
<div id="grapes"></div>
<div id="orange"></div>
<div id="apples"></div>
<div id="banana"></div>
</div>
Simple shuffle extension:
Array.prototype.shuffle = function() {
var shuffledArray = [];
while (this.length) {
shuffledArray.push(this.splice(Math.random() * this.length, 1)[0]);
}
while (shuffledArray.length) {
this.push(shuffledArray.pop());
}
return this;
}
Use it like
var fruitArray = ['apples','banana','orange','grapes'].shuffle();
for (var i = 0; i < fruitArray.length; i++) {
$('<div class="'+fruitArray[i]+'"></div>').appendTo('#col1').doSomething();
$('<div id="'+fruitArray[i]+'"></div>').appendTo('#col2').doSomething();
}

Categories

Resources