array_chunk in Javascript, after Appending a big chunk using ForLoop - javascript

(In edit part at the bottom, I have included my code that I got closest)
Explanation:
I have an ajax post, which fetches data from controller. On success, I have a for loop for each post:
success: function(data) {
var posts = data['data'];
var postsCount = data['per_page'];
var frag = document.createDocumentFragment();
for(i=0; i < postsCount; i++){
frag.appendChild(postElem(posts));
}
document.getElementById('content').appendChild(frag);
}
I also have another function function postElement() which creates eachPost div, appends the child divs into eachPost and returns it
function postElem(posts){
var eachPost = document.createElement('div');
eachPost.className = "col-md-4 eachPost";
//and a big chunk of code that finally appends into `eachPost`.
return eachPost;
}
This works perfectly until here
The structure I got working in html, and also want to achieve in javascript looks like this:
<div id="content">
#foreach (array_chunk($posts->all(), 3) as $row)
<div class="row eachRow">
#foreach($row as $post)
<div class="col-md-3 eachPost">
<!-- rest of the code -->
After some research, I figured out I can achieve array_chunk like this:
var n,j,tempArray,chunk = 3;
for (n=0,j=posts.length; n<j; n+=chunk) {
tempArray = posts.slice(n,n+chunk);
// my other `for`.
}
However, whatever I tried, I couldn't figure out how I can achieve what I achieved in html. I couldn't import eachRow bit in javascript. What is the way of doing it? Is it because of the document.createDocumentFragment() bit?
Edit: What I tried, that fails what I want to achieve:
success: function(data) {
var posts = data['data'];
var postsCount = data['per_page'];
var frag = document.createDocumentFragment();
var eachRow = document.createDocumentFragment();
var n,j,tempArray,chunk = 3;
for (n=0,j=posts.length; n<j; n+=chunk) {
tempArray = posts.slice(n,n+chunk);
for(i=0; i < tempArray.length; i++){
frag.appendChild(postElem(tempArray));
}
var eachRow = document.createElement('div');
eachRow.className = "row eachRow";
eachRow.appendChild(frag);
}
document.getElementById('content').appendChild(eachRow);
}
In this part, it appends the stuff in frag. It creates a div. (See bottom for the view:source)
This creates a post inside each row, and it's like a straight line of posts, instead of 3 posts in 1 row.
What I want to achieve
<div class="row eachRow">
<div class="eachPost>_</div>
<div class="eachPost>_</div>
<div class="eachPost>_</div>
</div>
<div class="row eachRow">
<div class="eachPost>_</div>
<div class="eachPost>_</div>
<div class="eachPost>_</div>
</div>
The code at the top is producing:
<div class="row eachRow">_</div>
<div class="row eachRow">_</div>
<!-- for each bit -->
<div class="eachPost>_</div>
<div class="eachPost>_</div>
<div class="eachPost>_</div>
Code in edit part is producing:
<div class="row eachRow">
<div class="eachPost>_</div>
</div>
<div class="row eachRow">
<div class="eachPost>_</div>
</div>
<div class="row eachRow">
<div class="eachPost>_</div>
</div>

Related

Get values from ID HTML and save in array

I'm doing a view where once I click I'm displaying
For Loop
I am having a view that captures a QR code and displays it on the screen, what I want to do next is take these values by iterating the elements with a for loop and save it in an array, in this case my ID is id="scanned-result" and I want to iterate each containing values and saving to an array.
I am doing this but for some reason it is not performing the operation correctly. I would like to know what I should correct?
function SubmitCodes() {
var QRCodeval= document.querySelectorAll('scanned-result');
var arr = [];
for (var i in QRCodeval) {
alert(QRCodeval[i]);
arr.push( QRCodeval[i]);
}
alert(arr.val);
}
VIEW
<div class="container">
<div class="row">
<div class="col-md-12" style="text-align: center;margin-bottom: 20px;">
<div id="reader" style="display: inline-block;"></div>
<div class="empty"></div>
<div id="scanned-result">
<div>[1] - https://www.investopedia.com/terms/q/quick-response-qr-code.asp</div>
<div>[2] - https://www.dropbox.com/s/705b6p4a2ydvayx/EN-Poster.pdf?dl=0</div></div>
</div>
</div>
</div>
There are several issues with your code. To select element by ID using querySelector you need to use # selector, also to select the divs inside you can use element > element selector.
var QRCodeval = document.querySelectorAll("#scanned-result>div");
querySelectorAll returns a nodeList. So you need to iterate through it to get value of individual elements. But you should not use for..in. You can use forEach instead.
function submitCodes() {
var QRCodeval = document.querySelectorAll("#scanned-result>div");
var arr = [];
QRCodeval.forEach((el) => arr.push(el.innerHTML));
console.log(arr)
}
submitCodes();
<div class="container">
<div class="row">
<div class="col-md-12" style="text-align: center;margin-bottom: 20px;">
<div id="reader" style="display: inline-block;"></div>
<div class="empty"></div>
<div id="scanned-result">
<div>[1] - https://www.investopedia.com/terms/q/quick-response-qr-code.asp</div>
<div>[2] - https://www.dropbox.com/s/705b6p4a2ydvayx/EN-Poster.pdf?dl=0</div>
</div>
</div>
</div>
</div>
To get the text inside of the elements you can use innerHTML.
Since there is no <scanned-result></scanned-result> element on your page, as charlietfl pointed out, you won't get any results.
Since your HTML markup is the following:
<div id="scanned-result">
<!-- … -->
</div>
You are looking for an ID.
And the valid ID query in a CSS selector is a #, because of that you should query like:
var QRCodeval = document.querySelectorAll('#scanned-result')
I've changed the iteration to fill the array with the lines inside the ID scanned-result. Would that help ?
function SubmitCodes() {
var QRCodeval = document.getElementById('scanned-result').children;
var arr = [];
for (var i = 0; i < QRCodeval.length; i++) {
arr.push(QRCodeval[i].innerText)
}
console.log(arr)
}
<div class="container">
<div class="row">
<div class="col-md-12" style="text-align: center;margin-bottom: 20px;">
<div id="reader" style="display: inline-block;"></div>
<div class="empty"></div>
<div id="scanned-result">
<div>[1] - https://www.investopedia.com/terms/q/quick-response-qr-code.asp</div>
<div>[2] - https://www.dropbox.com/s/705b6p4a2ydvayx/EN-Poster.pdf?dl=0</div>
</div>
</div>
</div>
</div>

Wrapping elements while looping through HTMLCollection causes problem

I want to wrap each item of the container in a div. When I loop through HTMLCollection, some elements are accessed multiple times while others are left out
HTML
<div class="container">
<div class="item_1"></div>
<div class="item_2"></div>
<div class="item_3"></div>
<div class="item_4"></div>
<div class="item_5"></div>
<div class="item_6"></div>
<div class="item_7"></div>
<div class="item_8"></div>
<div class="item_9"></div>
</div>
JS
const container = document.querySelector('.container');
const items = container.children;
for(let i = 0; i < items.length; i++) {
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.appendChild(items[i]);
container.appendChild(wrapper);
}
Looping directly through HTMLCollection gives this bizarre result
<div class="container">
<div class="item_2"></div>
<div class="item_4"></div>
<div class="item_6"></div>
<div class="item_8"></div>
<div class="wrapper">
<div class="item_1"></div>
</div>
<div class="wrapper">
<div class="item_5"></div>
</div>
<div class="wrapper">
<div class="item_9"></div>
</div>
<div class="wrapper">
<div class="wrapper">
<div class="item_7"></div>
</div>
</div>
<div class="wrapper">
<div class="wrapper">
<div class="wrapper">
<div class="wrapper">
<div class="item_3"></div>
</div>
</div>
</div>
</div>
</div>
problem gets solved when I convert HTMLCollection to an Array
const items = Array.from(container.children);
I can't understand what causes such behavior
You were iterating the container.children list which you were also changing during the iterations. This messed up the iteration. You can solve this, as you mentioned yourself, by converting the container.children to an array because then you are not iterating over the live container.children list but over an array copy of that. This copy is still referring to the correct child elements so they are moved correctly with the appendChild() function.
As an alternative you can use the querySelecterAll() to retrieve all the elements you want to wrap.
const container = document.querySelector('.container');
const items = container.querySelectorAll('.container > *');
for(let i = 0; i < items.length; i++) {
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.appendChild(items[i]);
container.appendChild(wrapper);
}
.wrapper {
background-color: red;
}
<div class="container">
<div class="item_1">1</div>
<div class="item_2">2</div>
<div class="item_3">3</div>
<div class="item_4">4</div>
<div class="item_5">5</div>
<div class="item_6">6</div>
<div class="item_7">7</div>
<div class="item_8">8</div>
<div class="item_9">9</div>
</div>

Vanilla Javascript insertBefore() in for loop

I have the following html structure.
<div id="page1" class="page">
<div class="firstchild"></div>
<div class="secondchild"></div>
<div class="thirdchild"></div>
<div class="forthchild"></div>
</div>
<div id="page2" class="page">
<div class="firstchild"></div>
<div class="secondchild"></div>
<div class="thirdchild"></div>
<div class="forthchild"></div>
</div>
<div id="page3" class="page">
<div class="firstchild"></div>
<div class="secondchild"></div>
<div class="thirdchild"></div>
<div class="forthchild"></div>
</div>
And my javascript structure is.
var pageCLASS = frame.querySelectorAll(".page");
//var pageCLASS = frame.getElementsByClassName('page')[0];
var leng = pageCLASS.length;
for (var i = 0; i < leng; ++i) {
var pageID = frame.getElementById('page' + (i + 1));
var firstchild = frame.getElementsByClassName('firstchild')[0];
var secondchild = frame.getElementsByClassName('secondchild')[0];
var thirdchild = frame.getElementsByClassName('thirdchild')[0];
pageID.insertBefore(thirdchild, firstchild.nextSibling);
//pageCLASS.insertBefore(thirdchild, firstchild.nextSibling);
}
Now I have problems with the thirdchild being moved to below the firstchild and above the secondchild in all of page1, page2, and page3 together. The code above only moves it in page1, but for the other 2 which does nothing. The frame shown in the source is an iframe stored on the same domain with access to it's elements. Can I please get some advice on what I am doing wrong as I want to move all thirdchilds in each div to below the first child in each of their parent div?
The problem you are having is that you are constantly targeting the same elements with e.g.
var firstchild = frame.getElementsByClassName('firstchild')[0];
because this instruction always returns the first occurrence of such an element in the iframe and never the second or third.
In order to be sure that you are targeting the correct elements you can rewrite some of your code to only search for the elements that are contained within a certain parent and not inside the whole iframe.
You can then use something like this instead
var firstChild = pageID.querySelector('.firstchild');
which will only search for an element (the first occurrence) with class firstchild that is contained within some other element (in this case the element saved in pageID).
Check below (I exchanged the form for document so we can test here):
var pageCLASS = document.querySelectorAll(".page");
var leng = pageCLASS.length;
for (var i = 1; i <= leng; i++) {
var pageID = document.getElementById('page' + i);
var firstChild = pageID.querySelector('.firstchild');
var thirdChild = pageID.querySelector('.thirdchild');
firstChild.parentNode.insertBefore(thirdChild, firstChild.nextSibling);
}
.page {
border: 1px solid #09f;
}
<div id="page1" class="page">
<div class="firstchild">first child</div>
<div class="secondchild">second child</div>
<div class="thirdchild">third child</div>
<div class="forthchild">fourth child</div>
</div>
<div id="page2" class="page">
<div class="firstchild">first child</div>
<div class="secondchild">second child</div>
<div class="thirdchild">third child</div>
<div class="forthchild">fourth child</div>
</div>
<div id="page3" class="page">
<div class="firstchild">first child</div>
<div class="secondchild">second child</div>
<div class="thirdchild">third child</div>
<div class="forthchild">fourth child</div>
</div>

Copy Class Values to Div

I have HTML File:
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="Function()">Whatever</button>
<div id="result"></div>
I'd like my function to take values from all four divs with class "um-field-value"
<div class="um-field-value">Value1</div>
And past them in Div "result"
Essentially, I want a script to simply copy values given in class um-field-value and paste it in a "result" div. I tried following:
function Function() {
var x = document.getElementsByClassName("um-field-value");
document.getElementsById('result').innerHTML = x;
}
But that doesn't work at all.
I am somewhat new to coding so I am not entirely sure if it is even possible. Googled for over an hour but couldn't find any solutions.
document.getElementsByClassName gets the HTML nodes themselves but then you have to extract the values from within the HTML nodes, combine them, and set that to your result div. Example snippet below:
function myFunction() {
var valueNodes = Array.prototype.slice.call(document.getElementsByClassName("um-field-value"));
var values = valueNodes.map(valueNode => valueNode.innerHTML);
var result = values.join(' ');
document.getElementById('result').innerHTML = result;
}
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="myFunction()">Whatever</button>
<div id="result"></div>
Use querySelectorAll to get all the dom with this class um-field-value and iterate over that to get the innerHTML
There is a typo in your code.It is getElementById instead of getElementsById. There is an extra s
function Function() {
var x = document.querySelectorAll(".um-field-value");
let result = '';
for (var y = 0; y < x.length; y++) {
result += x[y].innerHTML;
}
document.getElementById('result').innerHTML = result;
}
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="Function()">Whatever</button>
<div id="result"></div>
You are on the right track. document.getElementsByClassName will return a NodeList. You need to get the innerText for each of the elements in that list. Depending on the browser you can either use forEach or a regular for loop to iterate over the list.
function Function() {
var fieldsList = document.getElementsByClassName("um-field-value");
var fieldValues = [];
fieldsList.forEach(function(field) { fieldValues.push(field.innerText) });
document.getElementsById('result').innerHTML = fieldValues.join(", ");
}
This is a simple and readable solution that uses a loop to get the text inside each element and add it to a string. getElementsByClassName returns an array of all elements found, so a loop is needed to get the text inside each with textContent.
function Function() {
var result = '';
var fields = document.getElementsByClassName("um-field-value");
for (var i=0; i<fields.length; i++) {
result += fields[i].textContent + '\n';
}
document.getElementById('result').innerHTML = result;
}
<div class="um-field-area">
<div class="um-field-value">Value1</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value2</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value3</div>
</div>
<div class="um-field-area">
<div class="um-field-value">Value4</div>
</div>
<button onclick="Function()">Whatever</button>
<div id="result"></div>

Get children under a parent using jQuery

$(document).ready(function() {
$.ajax({
type: "POST",
url: 'some/url',
data: {
'name':'myname'
},
success: function (result) {
var result = ["student", "test"];
var length = result.length;
for (var i = 0; i < length; i++) {
var datastores = result;
$('#data_stores').append(
"<div class='col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore' id=" + datastores[i] + "> </div>");
}
}
})
var ids = $('#data_stores').children().map(function(){ return this.id }).get();
$('<pre>').appendTo('body').text(JSON.stringify(ids));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="data_stores">
</div>
<div id="data_stores">
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="students">
//Some other codes here
</div>
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="teachers">
//Some other codes here
</div>
</div>
This is a block of code in my HTML. The inner divs under data_stores are created using jquery. The IDs of the children div were result of an AJAX request and assigned on success.
The problem is, I need the ID values of the children divs to use for another AJAX call.
I ran the following:
console.log($("#data_stores"));
Output I got is the same above.
But for,
console.log($("#data_stores").find('.datastore'));
[prevObject: m.fn.init[1], context: document, selector: "#data_stores
.datstore"]
But, when accessing the child it says the element is undefined.
I need to do both AJAX calls on
$(document).ready(function() {
})
Using children like this works:
var ids = $('#data_stores').children().map(function(){ return this.id }).get();
var ids = $('#data_stores').children().map(function(){ return this.id }).get();
$('<pre>').appendTo('body').text(JSON.stringify(ids));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="data_stores">
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="students">
//Some other codes here
</div>
<div class="col-sm-8 col-md-8 col-lg-8 col-xs-8 pre-panel datastore" id="teachers">
//Some other codes here
</div>
</div>

Categories

Resources