Positioning divs based on array elements - javascript

I am trying to make a project where an array is created with a set number of elements ranging from 1 to any number. A div is then created for each element, where the distance from right is determined by (some number * array[div number]) + "px". Something like this:
<div id = "demo"></div>
var d = document.getElementById("demo").innerHTML;
var array = [1,2,3];
//insert some code I don't know here
d.style.right: (array[1] * 20) + "px"
Here is where I get stuck because I am very much a beginner and I don't know how to make a new div for each array element.

Try
var demoElement = document.getElementById("demo");
var array = [1,2,3];
array.forEach((x, i)=> {
let el = document.createElement("div");
el.innerText = array[i] + ' element';
el.style.paddingLeft = (array[i] * 50) + 'px';
demoElement.appendChild(el);
});
<div id="demo">Demo Element</div>

Iterating over an array
If your array is of fixed length, you can fetch each element of the array using array[x]. However it is better to use a for-loop to fetch each item.
for (let i of arr) {
console.log(i); // logs 3, 5, 7
}
More on this topic here.
Creating elements
In order to create HTML element from within Javascript, you can make use of the Document.createElement() method. You would need to write something like
let element = document.createElement("div");
You can read more on this topic and see a few examples on the MDN site

This does what you asked for.
var array = [1,2,3];
array.map((elem,i) => {
document.getElementById('container').innerHTML += `<div class="generatedDiv" id="${elem}">${elem}</div>`
})
.container{
display: flex;
}
.generatedDiv{
background-color: blue;
display: inline;
margin-right: 20px;
}
<div id="container">
</div>

I beleive this is what you want to achieve:
const d = document.getElementById("demo");
const arr = [1,2,3,4,5,6];
arr.forEach(e => {
const child = document.createElement("div");
child.className = "demo__children";
child.textContent = "child" + e;
child.style.left = e * 20 + "px"
d.appendChild(child);
});
.demo__children {
position: relative;
}
<div id = "demo"></div>

Related

How to break array from filling div if the div is full

I'd like to ask a question regarding arrays and HTML divs.
If I have an array of:
const exampleArray = ['Germany','Australia','Canada','Mongolia','Argentina','China'];
And let's say I have a div like so, with a max length of around 100px (sorry for the long looking table, I couldn't format it on stack overflow)
| A div |
| -------- |
I want to try fill up the div as much as possible, but if it overflows, I want it to stop and end with ', ... 5' the number being the number of array items it couldn't print
For example:
| Germany, Australia, Canada, ... 2|
| -------- |
Not:
| Germany, Australia, Canada, Mong... 2|
| --------- |
Could anyone advise what is the best way to implement this?
Assuming you want the ellipsis and the bracketed number to be within the 100px, this snippet keeps adding an array item, plus its comma, calculates what the width of the ellipsis and bracketed remaining count is and if it fits, carries on.
If it has got too big then it reverts to the previous content and displays that.
Note: 100px is quite narrow given on my example at least the ellipsis plus bracketed number take at least 30px, so this snippet will show just one country name. Try it with 200px or smaller font size to test for more.
const exampleArray = ['Germany','Australia','Canada','Mongolia','Argentina','China'];
const div = document.querySelector('#list');
const endbit = document.querySelector('#endbit');
let i, endbitLength;
let divPrev = '';
let endbitPrev = '';
for (i = 0; i< exampleArray.length; i++) {
endbitPrev = endbit.innerHTML;
endbit.innerHTML = '...(' + (exampleArray.length - i) +')';
endbitLength = endbit.offsetWidth;
div.innerHTML = divPrev + exampleArray[i] + ', ';
if (div.offsetWidth > (100 - endbitLength)) {
break;
}
else {
divPrev = divPrev + exampleArray[i] + ', ';
endbitPrev = '...' + '(' + (exampleArray.length - i) + ')';
}
}
endbit.style.display = 'none';
div.innerHTML = divPrev + endbitPrev;
div {
display: inline-block;
}
<div id="list"></div>
<div id="endbit">...</div>
If you are ok with adding a span inside the div then this would do. I know there are better ways to do it, but you can try this function for now
function addToDiv(arr) {
const div = document.querySelector("#div");
const span = div.firstElementChild;
const divWidth = div.clientWidth;
let finalIndex = 0;
let remaining = 0;
for (const [index,c] of arr.entries())
{
span.append(c)
if(span.offsetWidth >= divWidth){
finalIndex = index-1;
remaining = arr.length - index;
break;
}
if(index != arr.length -1)
span.append(', ')
}
if(!remaining) return;
span.textContent = '';
for (const [index,c] of arr.entries())
{
if(index > finalIndex) break;
span.append(c+', ')
}
span.append('...'+remaining)
}
It periodically checks if the width of the span exceeds that of the div. I have written a fiddle here
https://jsfiddle.net/10fbkmg5/4/
You can play with the fiddle by changing the width of the div to check if it fits your requirements.
You can achieve your desired result by using below example, it is just reference for your requirement, just change the code or logic according.
const exampleArray = ['Germany','Australia','Canada','Mongolia','Argentina','China'];
var width=$(".tobefilled").width();
var news=exampleArray.slice(0,-width/15);
var remaining=exampleArray.length-news.length;
$(".tobefilled").html(news+",..."+remaining);
.tobefilled{
width:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tobefilled"></div>
You can create a clone to measure how many items fit, here is an example:
const exampleArray = ['Germany', 'Australia', 'Canada', 'Mongolia', 'Argentina', 'China'];
const target = document.querySelector('#target');
const temp = target.cloneNode();
temp.style.whiteSpace = 'nowrap';
temp.style.visibility = 'hidden';
target.parentElement.append(temp);
const content = exampleArray.filter((v, i, arr) => {
temp.textContent = arr.slice(0, i + 1).join(', ');
if (temp.scrollWidth <= target.clientWidth) {
// Make sure that this is the last element or if it is not, that the ellipsis still fits.
if (i === (arr.length - 1)) {
return true;
} else {
temp.textContent += ` ... ${arr.length - (i + 1)}`;
if (temp.scrollWidth <= target.clientWidth) {
return true;
}
}
}
});
const restCount = exampleArray.length - content.length;
target.textContent = content.join(', ')
if (restCount) {
target.textContent += ` ... ${restCount}`;
}
#target {
width: 200px;
}
<div id="parent">
<div id="target"></div>
</div>
What this does is:
Clone the #target element.
Add the clone to the parent of this element (to maximise the changes that it will have the same styling).
Filter the strings array. The filter function adds all the strings up to the current iteration's index to the clone and checks if the clone's width is bigger than the original element, it also makes sure that all the items up to this point as well as the ellipsis text will fit.
The result of the filter operation is then used to set the original element's text and to calculate the count of the remaining element (the ones that don't fit if any).

How to change specific values in a table created in javascript by pressing a button

Does anyone here know how I can change the value of "list4" when I have created a HTML table like so:
var obj = { list1, list2, list3, list4, list5 };
var newArray = [];
Object.keys(obj).forEach( (o) => newArray.push(obj[o]));
newArray.forEach(function(items) {
var row = document.createElement("tr");
items.forEach(function(item) {
var cell = document.createElement("td");
cell.textContent = item;
row.appendChild(cell);
});
table.appendChild(row);
});
I have extracted the 5 list elements out of a larger array by using this method:
var list1 = myArray.map(a => a.list1);
var list2 = myArray.map(a => a.list2);
var list3 = myArray.map(a => a.list3);
var list4 = myArray.map(a => a.list4);
var list5 = myArray.map(a => a.list5);
And I would like to change the value of all of the list elements in "list 4" to the existing values divided by 2.2046:
I have made a for-loop and changed the values to the new values:
var newValues = myArray.map(a => a.list4);
for (var i = 0; i < newValues.length; i++) {
newValues[i] = (newValues[i]/2.2046).toFixed(1);
}
Does anyone know how I can incorporate the last code so that I, by pressing a button with the id="metric", can make all the existing values change to the new values? I thinking maybe innterHTML could help, but I do not know how to get the specific values of list4.. Thank you for any help!
Bonus:
I have tried everything but have not succeeded in turning a string of "5' 6\"" into actual numbers as I also have to change these to metric values, possible anyone here knows?:) Thank you!
Create an array of cell elements in the same scope as your list. That way, you write something like cell[0].textContent = value whenever you want.
Separate updating the HTML in a new function. Clear the HTML by using remove(), then update by using .appendChild(cell[0]) to add the new values.
As for changing the string to numbers, here is an idea:
let number = "5' 6\"";
let div = document.getElementById("test");
let decimalValue = imperialToDecimal(number);
div.innerHTML = number + " becomes " + decimalValue;
function imperialToDecimal(measurement) {
let indxFeet = measurement.indexOf("'");
let indxInches = measurement.indexOf("\"");
let feet = measurement.substring(0, indxFeet);
let inches = measurement.substring(indxFeet + 1, indxInches);
return footAndInchToMeter(feet, inches);
}
function footAndInchToMeter(feet, inches) {
feet = feet/3.2808;
inches = inches/39.370;
return feet + inches;
}
<div id="test"></div>
This is the basic code that doesn't contain correction for when there is no ' or " symbol (but you can figure that out, I'm sure :).

How to make an array with class types and change the html ids?

I want to change #changecolor1, 2, 3, 4... to a "class" and use the class values 1 2 3 4.
How can I do it with an array?
I tried:
<script>
var color=["text-pink","text-pink4","text-pink9"];
var y= document.createAttribute("class");
y.value=(color[0])
var x = document.getElementById("changecolor");
x.setAttributeNode(y);
</script>
You can set the property className
document.getElementById("changecolor").className = color[0];
If you have multiple elements - if I understand it right starting from #changecolor1, you can use a loop
for (var i = 0; i<color.length;i++) {
var x = i + 1;
document.getElementById('changecolor' + x).className = color[i];
}
Note that this will break if there are too few elements with the id. To avoid this, you could add a check if the element exists.
for (var i = 0; i<color.length;i++) {
var x = i + 1;
var el = document.getElementById('changecolor' + x);
if (el) el.className = color[i];
}

how to split & add array values into different 'div' components without using "if" condition?

I am using HTML5 + javascript for developing a webpage. I have an array with 100 values. And i have a 10 different HTML5 "div" components. I'm adding 1st 10 array values into 1st "div", 2nd 10 array values into 2nd "div" and similarly goes on. I am using HTML DOM to add these array values into particular "div" component.
Here i have used "if...elseif" condition & is working fine.
But i'm asked not to use "if" condition to add array values into different 'div' elements. Is there any other possible methods to do this?
My div components are 'div1','div2'.......'div10'(added in body tag)
var myArray = ['user1', 'user2', 'user3', ..., 'user100'];
for(i=0;i<myArray.length;i++)
{
var a = document.createTextNode(myArray[i]);
if(i<=10)
{
var container1 = document.getElementById('div1');
container1.appendChild(a);
}
elseif(i>10 && i<=20)
{
var container2 = document.getElementById('div2');
container2.appendChild(a);
}
...
...
...
...
else
{
var container10 = document.getElementById('div10');
container10.appendChild(a);
}
}
It's bad solution. The better one is following:
for(j=0;j<10;j++)
{
//get div1, div2, div3 etc.
var container = document.getElementById('div'+(j+1));
for(i=0;i<10;i++)
{
//get proper value
var a = document.createTextNode(myArray[i+j*10]);
//insert value into container
container.appendChild(a);
}
}
var set=myArray.length/10; /** no of sets of 10 **/
for(i=0;i<set;i++){ //loop through sets
for(int j=(i*10);j<(i+1)*10;j++){ //loop through each set 0-9, 10-19
var a = document.createTextNode(myArray[j]);
document.getElementById('div'+(i+1)).appendChild(a);
}
}
var myArray = ['user1','user2','user3',...'user100'];
for(var i = 0; i < 10; i++) {
var container = document.getElementById("div" + (i + 1));
for(var j = 0; j < 10; j++) {
container.appendChild(document.createTextNode(myArray[(i * 10) + j]));
}
}
If you don't mind array values being inserted into each div as one text node, you could do:
var div, i;
for (i = 1; i < 11; ++i) {
div = document.getElementById('div' + i);
div.innerHTML = myArray.splice(0, 10).join(' ');
}
You don't need 2 for loops. Do you?
for (var i = 1; i <= 100; i++)
{
document.getElementById('div' + ( i%10 + 1)) //this will give your target div
}
P.S: spare me... Typing on mobile...

jQuery recursive wildcard selector from array and array push dynamically

Link to jsFiddle
I have many elements containing text in which I am using parseInt() to grab the values from a specific number of elements (based on the current month) and a specific selector wildcard and push those values into one of six arrays for use elsewhere. I am trying to clean up the code and make a compact loop to complete all of this.
I am able to get everything to work if I use six separate for loops, but I thought I might try to see if it is able to be done in one single loop.
So in the for loop below, I am trying to make the jQuery wildcard selector for the element ID be the current value of i (from statusArray) by trying something like $('[id*=statusArray[i]]) but that doesn't seem to be working.
Then I would like to push the data into the predefined appropriate array by something like statusArray[i]Array.push(...) but that doesn't work either. I've tried concatenating various ways but can't seem to get it to work.
Any help would be appreciated! Thank you in advance!
HTML:
<div id="jan_connected"></div> <!-- left empty to test for NaN -->
<div id="jan_busy">100</div>
<div id="jan_noanswer">100</div>
<div id="jan_abandoned">100</div>
<div id="feb_minutes">100</div>
<div id="feb_totals_calls_c">100</div>
<div id="feb_connected">100</div>
<div id="feb_busy">100</div>
<div id="feb_noanswer">100</div>
<div id="feb_abandoned">100</div>
Javascript:
var connectedArray = [];
var busyArray = [];
var noanswerArray = [];
var abandonedArray = [];
var minutesArray = [];
var callsArray = [];
// var date = new Date();
// var dateNumber = 1 + date.getMonth();
var dateNumber = 2;
var statusArray = ['minutes', 'total_calls', 'connected', 'busy', 'noanswer', 'abandoned']
for (i=0; i<dateNumber; i++) {
// Below I would like the id* to equal the current value of the statusArray iteration
if (isNaN(parseInt($('[id*=statusArray[i]]').slice(i).html()))) {
statusArray[i]Array.push("0"); // Trying to push into the appropriate array dynamically
} else {
statusArray[i]Array.push(parseInt($('[id*=statusArray[i]]').slice(i).html()));
}
}
You have syntax errors in couple of places..
this line
$('[id*=statusArray[i]]')
supposed to be
$('[id*=' + statusArray[i] + ']')
And
statusArray[i] Array.push("0");
should be
statusArray[i].push("0");
Push method is available on a Array , but statusArray[i] is not an array but a string.
Looks like you are looking for something like this
var connectedArray = [];
busyArray = [];
noanswerArray = [];
abandonedArray = [];
minutesArray = [];
callsArray = [];
dateNumber = 2;
statusArray = ['minutes', 'total_calls', 'connected', 'busy', 'noanswer', 'abandoned'];
var obj = {
'minutes': minutesArray,
'totals_calls': callsArray,
'connected': connectedArray,
'busy': busyArray,
'noanswer': noanswerArray,
'abandoned': abandonedArray
};
for (i = 0; i < statusArray.length; i++) {
$('[id*="' + statusArray[i] + '"]').each(function () {
var val = $(this).html();
if (isNaN(parseInt(val))) {
obj[statusArray[i]].push("0");
} else {
obj[statusArray[i]].push(val);
}
});
}
console.log('Minutes Array: ' + obj['minutes']);
console.log('Total Calls Array: ' + obj['totals_calls']);
console.log('Connected Array: ' + obj['connected']);
console.log('No Answer Array: ' + obj['noanswer']);
console.log('Abandoned Array: ' + obj['abandoned']);
console.log('Busy Array: ' + obj['busy']);
Check Fiddle

Categories

Resources