Flexbox: display elements with number of columns and rows given - javascript

I have an empty div.
<div id="container"></div>
With the following CSS:
#container{
display: flex;
position: relative;
flex-flow: row wrap;
width: 100%;
}
In which I want to insert more divs via JavaScript but let the user choose how many rows and columns the container will have.
At the moment this is the code I have:
var container = document.getElementById('container');
var rows = prompt("How much lines do you want?");
var columns = prompt("And how much columns do you want?");
for(var i = 0; i < rows; i++){
for(var j = 0; j < columns; j++){
var div = document.createElement("div");
div.classList.add("square");
div.innerHTML="<p>" + i + "</p>";
container.appendChild(div);
}
}
where square class has the following:
.square{
flex: 1;
height: 50px;
}
but all the divs inside the container are displayed in one row.
What I want to do is to set the divs inside the container with the same dimensions that the user inputs, but I cannot get it.
Is it possible to set these divs inside the container as rows/columns given by the user?
Note: As you can see, I am only using JavaScript and I would like to keep it, so please avoid answers with plugins/libraries/etc.

If you have N columns, one solution is to set the flex-basis property to a percentage of 100/N.
You can set it in javascript without libraries (as required) with:
div.style['flex-basis'] = 100/columns + '%';
Keeping the same settings as yours, you just have to add the previous line in the script like this:
var container = document.getElementById('container');
var rows = prompt("How much lines do you want?");
var columns = prompt("And how much columns do you want?");
for(var i = 0; i < rows; i++){
for(var j = 0; j < columns; j++){
var div = document.createElement("div");
div.classList.add("square");
div.innerHTML="<p>" + i + "</p>";
div.style['flex-basis'] = 100/columns + '%';
container.appendChild(div);
}
}
You can test it with the codepen : http://codepen.io/anon/pen/wGYKdY

Related

Append string to specific div only once if same div is used throughout DOM

I'm working on building a portfolio site and I'm pulling content from a JSON file. It's working, but I'm having a hard time generating the content only one time. I'm creating a div with the project type's name, and then adding container and row inside to make it work with Bootstrap. Then, I'm going through the projects and pulling the data, and creating a new div inside row that's called port-card, and port-card will contain the data. It's working, but in my for loop I'm using jQuery's append and it's appending the data to EVERY single row, which means I'm adding the data twice (or however many rows there currently are) instead of just one time.
EDIT: Thanks to T.J. Crowder, I tried using .eq(n) and I've added a runnable snippet below. Now I'm trying to figure out how to keep the generated data in the first wordpress-plugins div rather than having the second iteration of the for loop add it to the second div.
var catList = ["WordPress Plugins", "Websites"];
var categories = [{cat: "WordPress Plugins", title: "Price Quote Plugin"}, {cat: "WordPress Plugins", title: "House Plan Search"}];
for (var i = 0; i < catList.length; i++) {
temp = catList[i];
temp = temp.replace(/\s+/g, '-').toLowerCase();
$('.projects').append('<div class="' + temp + '"><div class="container"><div class="row"></div></div></div>');
}
if ($('.wordpress-plugins')[0]) {
var rows = $(".row");
for (var i = 0; i < categories.length; i++){
var catNameTemp = categories[i].cat;
var projectTitle = categories[i].title;
if(catNameTemp == "WordPress Plugins"){
rows.eq(i).append('<div class="port-card"><h3>' + projectTitle + '</h3></div>');
}
}
}
.projects {
text-align: center;
margin-top: 5%;
}
.port-card {
background-color: #333;
width: 400px;
height: 800px;
}
h3 {
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="projects">
</div>
$('.row') will create a jQuery set with all elements with class row in it. If you want to access just a single element in that set, you can use .eq(n) to do so (n = the index, starting with 0).
So for instance, if you have as many rows as categories, you might do:
var rows = $(".row");
...before the loop, then rows.eq(i).append(...) within the loop.
Looking at the runnable snippet you added, you don't have a row-per-category, so the above wouldn't apply. See comments in the snippet:
var catList = ["WordPress Plugins", "Websites"];
var categories = [
{cat: "WordPress Plugins", title: "Price Quote Plugin"},
{cat: "WordPress Plugins", title: "House Plan Search"},
// Added this to show putting things in other category lists
{cat: "Websites", title: "Some Website"}
];
// A map of category names to the divs that represent them
var catDivs = Object.create(null);
// Look up the projects div once and reuse it
var projects = $(".projects");
for (var i = 0; i < catList.length; i++) {
var catName = catList[i];
var clsName = catName.replace(/\s+/g, '-').toLowerCase();
// Create and add the category div, remember it in the map
catDivs[catName] = $('<div class="' + clsName + '"><div class="container"><div class="row"></div></div></div>').appendTo(projects);
}
// Done with this
projects = null;
// Add categories to their container
for (var i = 0; i < categories.length; i++) {
var catDiv = catDivs[categories[i].cat];
if (catDiv) {
var projectTitle = categories[i].title;
catDiv.find(".row").append('<div class="port-card"><h3>' + projectTitle + '</h3></div>');
}
}
.projects {
text-align: center;
margin-top: 5%;
}
.port-card {
background-color: #333;
width: 400px;
height: 800px;
}
h3 {
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="projects">
</div>
Add a unique Id on the row that you want to append data in and then append data in that row only. Like shown below
for (var i = 0; i < catList.length; i++) {
temp = catList[i];
temp = temp.replace(/\s+/g, '-').toLowerCase(); //convert string to lower case and make spaces dashes to create class names
$('.projects').append('<div class="' + temp + '"><div class="container"><div class="row" id="uniqueId"></div></div></div>');
}
if ($('.wordpress-plugins')[0]) {
for (var i = 0; i < categories.length; i++){
var catNameTemp = categories[i].cat;
var projectTitle = categories[i].title;
if(catNameTemp == "WordPress Plugins"){
$('#uniqueId').append('<div class="port-card"><h3>' + projectTitle + '</h3></div>');
}
}
In this line of code $('.row').append('<div class="port-card"><h3>' + projectTitle + '</h3></div>'); notice how you wrote $('.row').append(.
This makes jQuery append your new div to the every instance of the class of "row".
What you need to do is be more specific about which row you want your new div to be appended to.

Assign Set Class To HTML Table Created in JavaScript

I'm trying to use JavaScript to create a table based off the amount of rows from one table and amount of columns from another. When doing this, I want to assign the table a couple div id's and a table class in order to have the generated table line up on the right side of my employee table.
My problem is, when I create the table in JavaScript this way, I lose the scroll bars for the x and y axis of the table and it appears below the employee table. Scrolling the table is then done with the window scroll instead of having the table set and scrollable itself. I'm still new to HTML and JavaScript and I can't seem to find where I'm going wrong on my own. Here's my code and a JSFiddle for clarification:
var rows = document.getElementById('dayRow').getElementsByTagName("td").length;
var cols = document.getElementById('employeeCol').getElementsByTagName("tr").length;
var myTable = document.createElement('table');
myTable.classList.add("tableTasks");
var tr1 = null;
var td1 = null;
var text1 = null;
for(let i = 0; i < rows; i++) {
tr1 = document.createElement('tr');
for(let j = 0; j < cols; j++) {
td1 = document.createElement('td');
text1 = document. createTextNode('cell');
td1.appendChild(text1);
tr1.appendChild(td1);
}
myTable.appendChild(tr1);
}
document.body.appendChild(myTable);
.tableTasks {
width:100%;
margin-top:5px;
empty-cells: show;
height:1000px;
line-height: 35px;
width: 100px;
}
#table-wrapper-tasks {
position: relative;
width:81%;
float:right;
}
#table-scroll-tasks {
overflow-x: scroll;
overflow-y: scroll;
max-height: 522px;
}
<div id="table-wrapper-tasks">
<div id="table-scroll-tasks">
</div>
</div>
I'm trying to get something like the image attached.
https://jsfiddle.net/kk05x1cg/#&togetherjs=8kJlzomlvg

arrange the div in sequence format using javascript

I am working on scenario where when I enter number in the textbox i need generate dynamically div's. Actually I am struggling not aligned properly with the current div. Then I need to generate ID's for the div's. For this also code is available but the code not considered the default div as preview1 then it has to go on like preview2, preview3 so on. The div has to arrange sequence like first it has to show preview1......
var inputElement = document.getElementById("inputAdd_page");
var totalCount = 0;
inputElement.addEventListener('blur', function () {
var count = this.value;
// Gaurd condition
// Only if it is a number
if (count && !isNaN(count)) {
fragment = document.createDocumentFragment();
for (var j = 0; j < count; ++j) {
spancount = document.createElement('span');
prevPage = document.createElement('div');
navbutton = document.createElement('button');
preview_PageSize = document.getElementById('page');
navbutton.className = "div_navig";
navbutton.setAttribute('id', ['pag_navg' + totalCount]);
navbutton.innerHTML = [1 + totalCount];
spancount.className = "spanCount";
spancount.innerHTML = [1 + totalCount];
prevPage.className = "preview_windowSize";
prevPage.setAttribute('id', ['page' + totalCount]);
prevPage.appendChild(spancount);
prevPage.style.position = "absolute";
preview_PageSize.appendChild(prevPage);
//fragment.appendChild(prevPage);
fragment.appendChild(navbutton);
totalCount++;
}
inputElement.value = "";
document.body.appendChild(fragment);
}
});
Here is the fiddle Link
Thanks in advance.
Kindly help me.
if I get you right, change the javascript as follows:
//prevPage.style.position="absolute";
//preview_PageSize.appendChild(prevPage);
prevPage.style.width="100%";
preview_PageSize.parentNode.insertBefore(prevPage, preview_PageSize);
to improve positioning, you could apply a diffrent class to the child elements, like so:
prevPage.className = "preview_windowSize_element";
and use CSS:
.preview_windowSize_element {
position: absolute;
left: 31px;
top: 0px;
width: 100%;
height: 100%;
}
to start with page ID 1 you could modify your script:
prevPage.setAttribute('id', ['page' + (totalCount + 1)]);
Do you search something like this jsFiddle?.
I just add a left position in each div, because you set them to position:absolute.
So I added this line:
prevPage.style.left= (26 * totalCount) + "px";
I just put 26 like this, it will be the width of the button

JavaScript: creating an array of text boxes

I am looking to create a grid of 3x3 text input boxes, relative to an existing square div, using pure JavaScript. Preferably I would like to construct the grid of a single 1D array that cycles through every third box (if not, then an array of an array of input boxes would do - I hope this makes sense). This is what my code looks like at the moment, but only three of the boxes show when I cycle the array length (if I don't then the array extends linearly across beyond the div confines):
var row0 = new Array(9);
for (var i = 0; i < 9; ++i)
{
row0[i] = document.createElement('input');
row0[i].style.position = "absolute";
row0[i].type = "text";
row0[i].style.marginLeft = 35px *i % 105 + "px";
row0[i].style.width = "35px";
row0[i].style.height = "35px";
document.getElementById('block1').appendChild(row0[i]);
}
How can I get the grid to display correctly?
I would use a combination of javascript and CSS
DEMO http://jsfiddle.net/x8dSP/3010/
JS
window.onload = function () {
var parent_div = document.createElement("div")
parent_div.id = "parent"
document.body.appendChild(parent_div);
var x = 0;
while (x < 9) {
var child_input = document.createElement("input")
child_input.className = "child"
document.getElementById(parent_div.id).appendChild(child_input);
x++;
}
}
CSS
div {
width: 150px;
}
input {
display: inline-block;
width: 30px;
height: 30px;
margin: 5px;
}

chess board using javascript and dom

I'm trying to create a chessboard just like this.
I did create a table And don'r know how to colour it. A also need to print the board name (like A1, A2, ... H8) and be able to pust any figuere in any of the cell.
For start this is the code to create a table:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ChessBoard</title>
<script type="text/javascript">
function CreateTable(){
var poz = document.getElementById('space');
// createing table adn inserting into document
tab = document.createElement('table');
poz.appendChild(tab);
tab.border = '5';
for (var i = 0; i < 8; i++){
// creating row and inserting into document
var row = tab.insertRow(i);
for(var j = 0; j < 8; j++){
// creating cells and fill with data (numbers)
var cell = row.insertCell(j);
cell.innerHTML = i*j;
cell.style.backgroundColor = 'blue';
cell.style.color = 'white';
cell.style.height = '50px';
cell.style.width = '50px';
};
};
}
</script>
</head>
<body onload="CreateTable()" id ="space">
</body>
</html>
How do i fill specific cell with figure (like A3, E5, H8, ...)? Figure are imgages.
Part 2:
I did create a board with your help.
Now I'm trying to do some more from this code.
How do I put several different images into several cells? I'm trying to get right working code, but with no success. This images should appear when the tabel will be loaded (when i press button CreateTable).
I try to create with this code:
In this point I would like to put figures on board. When i create table it should be blank. Then there will be buttons to add figures. At the beginning for each different figure own button
something like this:
function addKing(idStr){
cell = document.getElementById(idStr);
if(cell != null){
// works for color, doesn't work for images!!
// cell.style.backgroundColor = 'red';
cell.src = 'http://akramar.byethost8.com/images/SplProg/DN3/images/50px/king_m.png'
}
}
Button addKing in html:
<button id="king" onclick="addKing(prompt('Insert field'))">Add King</button>
upgrading previousu code to even better if i can put all together and select which one I like to insert (promtpt window 1: what figure:'king, queen, ...', prompt window 2: on what position would you like to insert: 'A1, B3, ...')).
function addImage (type, position){
var img = ??
}
When I pres button add image the prompt window should appear and ask for type (king, queen, root, ...) and location (A1, B4, ...) (for further update perhaps even color (black or white) but let build step by step).
All tis chessboard I would like to build just in javascript and with dom.
link to not working exaple: jsfiddle
Assuming you need to support only modern browsers, the chess-board is entirely do-able with CSS using counters, and generated-content:
table {
empty-cells: show;
}
td {
width: 2em;
height: 2em;
line-height: 2em;
text-align: center;
border: 1px solid #000;
}
tbody tr:nth-child(odd) td:nth-child(even),
tbody tr:nth-child(even) td:nth-child(odd) {
color: #fff;
background-color: #00f;
}
tbody tr:nth-child(even) td:nth-child(even),
tbody tr:nth-child(odd) td:nth-child(odd) {
background-color: #999;
}
tbody {
counter-reset: rowNumber;
}
tr {
counter-increment: rowNumber;
counter-reset: cellNumber;
}
td {
counter-increment: cellNumber;
}
td::before {
content: counter(rowNumber, upper-alpha) counter(cellNumber, decimal);
}
JS Fiddle demo.
The above tested in Chromium 24 and Firefox 19, both on Ubuntu 12.10.
And for a JavaScript approach:
var chess = {
createBoard: function (dimension) {
if (!dimension || isNaN(dimension) || !parseInt(dimension, 10)) {
return false;
} else {
dimension = typeof dimension === 'string' ? parseInt(dimension, 10) : dimension;
var table = document.createElement('table'),
tbody = document.createElement('tbody'),
row = document.createElement('tr'),
cell = document.createElement('td'),
rowClone,
cellClone;
table.appendChild(tbody);
for (var r = 0; r < dimension; r++) {
rowClone = row.cloneNode(true);
tbody.appendChild(rowClone);
for (var c = 0; c < dimension; c++) {
cellClone = cell.cloneNode(true);
rowClone.appendChild(cellClone);
}
}
document.body.appendChild(table);
chess.enumerateBoard(table);
}
},
enumerateBoard : function (board) {
var rows = board.getElementsByTagName('tr'),
text = document.createTextNode(),
rowCounter,
len,
cells;
for (var r = 0, size = rows.length; r<size; r++){
rowCounter = String.fromCharCode(65 + r);
cells = rows[r].getElementsByTagName('td');
len = cells.length;
rows[r].className = r%2 == 0 ? 'even' : 'odd';
for (var i = 0; i<len; i++){
cells[i].className = i%2 == 0 ? 'even' : 'odd';
cells[i].appendChild(text.cloneNode());
cells[i].firstChild.nodeValue = rowCounter + i;
}
}
}
};
chess.createBoard(10);
JS Fiddle demo.
You can tie an ID to the cell, and then use that ID to reference and updated the background as needed. Here is one example using your code: http://jsfiddle.net/7Z6hJ
function CreateTable(){
var poz = document.getElementById('space');
// createing table adn inserting into document
tab = document.createElement('table');
poz.appendChild(tab);
tab.border = '5';
for (var i = 0; i < 8; i++){
// creating row and inserting into document
var row = tab.insertRow(i);
for(var j = 0; j < 8; j++){
// creating cells and fill with data (numbers)
var cell = row.insertCell(j);
var idStr = String.fromCharCode(97 + i).toUpperCase() + (j+1);
cell.innerHTML = idStr;
cell.id = idStr;
cell.style.backgroundColor = 'blue';
cell.style.color = 'white';
cell.style.height = '50px';
cell.style.width = '50px';
};
};
}
function updateRow(idStr)
{
cell = document.getElementById(idStr);
if(cell != null)
{
cell.style.backgroundColor = 'red';
}
}
As some have mentioned, there is probably a better way to go about this (using css and jQuery, etc) but this answer sticks with what you have so far.
Create a new variable inside the top loop to save the "letter" name of the row (eg. A, B, C).
// creating row and inserting into document
var row = tab.insertRow(i);
var row_letter = String.fromCharCode(65 + i);
Then in the second loop combine the row name and column number.
cell.innerHTML = row_letter + j;
Actually, you need to do some math for correctly coloring and adding labels. Here is the part of code for doing magic:
1 cell.innerHTML = String.fromCharCode(65 + i) + (j + 1);
2 if((i+j)%2){ cell.style.backgroundColor = 'white'; }
3 else{ cell.style.backgroundColor = 'blue'; }
4 cell.style.color = 'black';
5 cell.style.height = '50px';
6 cell.style.width = '50px';
Let me explain. In first line, you take constant 65, which is ASCII code for letter 'A'. While you change the letter by rows, you add i counter to it, so you get 65+0, 65+1, ..., 65+7. Their ASCII equivalents (which you get with String.fromCharCode()) are A, B, ..., H. Now when you have that letter, easily add number of cell to it (j + 1). You can remove '1' and leave just j and make inner loop go from 1 to 8.
Lines 2, 3: Colors are alternating - every second row have the same color. So, just test if is i+j dividable by 2.
For adding figure, you have to make some function that will do cell.innerHTML = <SOME IMAGE>. But, I guess, it's for second question.
Hope I helped you understand the logic.
I case if someone is looking for a way to visualize a chessboard using JS (as I was doing and accidentally came to this question), here is an excellent JS library to do this.
It can create something like this
and much more in no time just by doing the following:
JavaScript
var ruyLopez = 'r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R';
var board = new ChessBoard('board', ruyLopez);
HTML
<div id="board" style="width: 400px"></div>

Categories