Forcing a click where i want - javascript

Run my snippet code before you read my question and click on some cells, so you can understand my question better!!
I got Player A = vertical and Player B = horizontal, As you can see, Each click gives turns between each player, moving the green background around some cells, how i can force the players only to be able to click the cells that have green behind them?
note: i tried using $(selector).trigger('click'); (JQuery)
var isCol = 0;
var CellPoint = 0;
var board = [];
var P1 = {
points: 0
};
var P2 = {
points: 0
};
for (r = 0; r < 7; r++) {
var line = [];
for (c = 0; c < 7; c++) {
line.push(RandomGenerator(50, 500));
}
board.push(line);
}
function prs(curr, c, r) {
CellPoint = parseInt($(curr).text());
showTable(curr, c, r);
isCol = (isCol + 1) % 2;
clr = isCol ? 'blue' : 'red';
$(curr).text('S');
$('#turn').css("color", clr)
.text(`Player ${(isCol+1)} turn`);
if (CellPoint) {
if (isCol) {
P1.points += CellPoint;
} else {
P2.points += CellPoint;
}
$('#p1').text(`Player 1: ${P1.points}`);
$('#p2').text(`Player 2: ${P2.points}`);
} else {
console.log('selected S');
}
}
function toColor(col, row, chosen_col, chosen_row) {
var ret = false;
switch (isCol) {
case 0:
if (row == chosen_row) {
ret = true;
}
break;
case 1:
if (col == chosen_col) {
ret = true;
}
break;
}
return ret;
}
function showTable(c, chosen_col, chosen_row) {
if(c!==-1){board[chosen_row][chosen_col] = 'S';}
var str = "";
str += "<table border=1>";
for (row = 0; row < 7; row++) {
str += "<tr>";
for (let col = 0; col < 7; col++) {
str += "<td onclick='prs(this, " + col + "," + row + ")'";
if(board[row][col]=='S'){
str += " class=uniqueCell";
} else{
if (toColor(col, row, chosen_col, chosen_row)) {
str += " class='grn' ";} }
str += ">";
if(board[row][col]=='S') {
str += 'S';
} else str += board[row][col];
str += "</td>";
}
str += "</tr>";
}
str += "</table>";
document.getElementById("ff").innerHTML = str;
}
function RandomGenerator(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
showTable(-1);
var getUnique = function() {
var tdElements = document.querySelectorAll('#ff td');
tdElements[
RandomGenerator(0, tdElements.length)
].classList.add('uniqueCell');
// update the text of the cell using the class
document.querySelector('.uniqueCell').textContent = 'S';
};
getUnique();
td {
border: 2px solid black;
width: 10px;
height: 10px;
text-align: center;
}
td:hover {
background-color: lightgreen;
}
.grn {
background-color: green;
color: white;
}
.turn1 {
background-color: green;
color: red;
}
.turn0 {
background-color: green;
color: blue;
}
.uniqueCell {
background-color: tomato;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><span id='p1' style='color:red;'>Player1: </span> X <span style='color:blue;' id='p2'>Player2: </span></div>
<p id='turn'>Player 1 turn</p>
<div id="ff"></div>

I would suggest to use pointer-events. I have added JavaScript logic as well as modified CSS little bit.
in JavaScript I am checking for class .grn, if its available then allowing click everywhere. But if .grn is available then only td with .grn class will be clickable.
See below JavaScript logic.
if(document.querySelectorAll(".grn").length>0){
document.getElementById("tbl").classList.add("preventclick");
}else{
document.getElementById("tbl").classList.remove("preventclick");
}
See the Snippet below:
var isCol = 0;
var CellPoint = 0;
var board = [];
var P1 = {
points: 0
};
var P2 = {
points: 0
};
for (r = 0; r < 7; r++) {
var line = [];
for (c = 0; c < 7; c++) {
line.push(RandomGenerator(50, 500));
}
board.push(line);
}
function prs(curr, c, r) {
CellPoint = parseInt($(curr).text());
showTable(curr, c, r);
isCol = (isCol + 1) % 2;
clr = isCol ? 'blue' : 'red';
$(curr).text('S');
$('#turn').css("color", clr)
.text(`Player ${(isCol+1)} turn`);
if (CellPoint) {
if (isCol) {
P1.points += CellPoint;
} else {
P2.points += CellPoint;
}
$('#p1').text(`Player 1: ${P1.points}`);
$('#p2').text(`Player 2: ${P2.points}`);
} else {
console.log('selected S');
}
}
function toColor(col, row, chosen_col, chosen_row) {
var ret = false;
switch (isCol) {
case 0:
if (row == chosen_row) {
ret = true;
}
break;
case 1:
if (col == chosen_col) {
ret = true;
}
break;
}
return ret;
}
function showTable(c, chosen_col, chosen_row) {
if(c!==-1){board[chosen_row][chosen_col] = 'S';}
var str = "";
str += "<table id='tbl' border=1>";
for (row = 0; row < 7; row++) {
str += "<tr>";
for (let col = 0; col < 7; col++) {
str += "<td onclick='prs(this, " + col + "," + row + ")'";
if(board[row][col]=='S'){
str += " class=uniqueCell";
} else{
if (toColor(col, row, chosen_col, chosen_row)) {
str += " class='grn' ";
}
}
str += ">";
if(board[row][col]=='S') {
str += 'S';
} else str += board[row][col];
str += "</td>";
}
str += "</tr>";
}
str += "</table>";
document.getElementById("ff").innerHTML = str;
if(document.querySelectorAll(".grn").length>0 || document.querySelectorAll(".uniqueCell").length > 1){
document.getElementById("tbl").classList.add("preventclick");
}
}
function RandomGenerator(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
showTable(-1);
var getUnique = function() {
var tdElements = document.querySelectorAll('#ff td');
tdElements[
RandomGenerator(0, tdElements.length)
].classList.add('uniqueCell');
// update the text of the cell using the class
document.querySelector('.uniqueCell').textContent = 'S';
};
getUnique();
table#tbl.preventclick td{
pointer-events: none;
}
td {
border: 2px solid black;
width: 10px;
height: 10px;
text-align: center;
}
td:hover {
background-color: lightgreen;
}
.grn {
background-color: green;
color: white;
}
table#tbl.preventclick td.grn{
pointer-events: auto;
}
.turn1 {
background-color: green;
color: red;
}
.turn0 {
background-color: green;
color: blue;
}
.uniqueCell {
background-color: tomato;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><span id='p1' style='color:red;'>Player1: </span> X <span style='color:blue;' id='p2'>Player2: </span></div>
<p id='turn'>Player 1 turn</p>
<div id="ff"></div>
Update:
I have added || document.querySelectorAll(".uniqueCell").length > 1 in if condition document.querySelectorAll(".grn").length>0 to fix issue mentioned in comment : there's little problem, try clicking on all the cells, in some cases, where there is no selectable numbers, i can click on anywhere on the S cells

Related

How to create multidimentional array in html tables

I created tables in which each cells will change its class between clicked cells.
When I create this table, I would like to get clicked history array.
In the current state,history array is stored in clicked array.
clicked array is like
array=[1,4,6,9]
but My desired result is like
array=[[1,2,3,4],[6,7,8,9]]
or
array=[[1,4],[6,9]]
I mean in each class change,I would like to get parent keys for manipulation.
If you have some opinion, please let me know.
const $days = $("td");
const range = [-1, -1];
let clicked =[];
$(function() {
$("td").click(function() {
if (range[0] > -1 && range[1] > -1) { // RESET
range[0] = -1;
range[1] = -1;
}
if (range[0] > -1 && range[1] < 0) { // SET END
range[1] = $days.index(this);
$days.slice(range[0],range[1]+1).addClass('is-active');
}
if (range[0] < 0 && range[1] < 0) { // SET START
range[0] = $days.index(this);
}
let clickedID=$days.index(this);
clicked.push(clickedID);
console.log("Array of clicked cells",clicked);
});
});
td {
transition-duration: 0.5s;
border: solid black 1px;
cursor: pointer;
}
div {padding: 5px;}
table {border-collapse: collapse;}
.aqua{background-color: aqua;}
td:hover {
background-color:yellow;}
.is-active{
background-color:aqua;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=calendar></div>
<script>
let html = ''
html += '<table>';
let i = 0;
for (let w = 0; w < 10; w++) {
html += '<tr>';
for (let d = 0; d < 10; d++) {
i = i + 1;
html += '<td>' + '<div>' + i + '</div>' + '</td>'
}
html += '</tr>';
}
html += '</table>'
document.querySelector('#calendar').innerHTML = html;
</script>
Will this help?
let sets = []
clicked.forEach((item,i) => {
if (i===0 || i%2===0) sets.push([])
sets[sets.length-1].push(item)
})
let html = ''
html += '<table>';
let i = 0;
for (let w = 0; w < 10; w++) {
html += '<tr>';
for (let d = 0; d < 10; d++) {
i = i + 1;
html += '<td data-layer=0>' + '<div>' + i + '</div>' + '</td>'
}
html += '</tr>';
}
html += '</table>'
document.querySelector('#calendar').innerHTML = html;
const $days = $("td");
const range = [-1, -1];
let clicked = [];
$(function() {
$("td").click(function() {
if (range[0] > -1 && range[1] > -1) { // RESET
range[0] = -1;
range[1] = -1;
}
if (range[0] > -1 && range[1] < 0) { // SET END
range[1] = $days.index(this);
$days.slice(range[0], range[1] + 1).addClass('is-active');
}
if (range[0] < 0 && range[1] < 0) { // SET START
range[0] = $days.index(this);
}
let clickedID = $days.index(this);
clicked.push(clickedID)
let sets = []
clicked.forEach((item,i) => {
if (i===0 || i%2===0) sets.push([])
sets[sets.length-1].push(item)
})
console.log("Array of clicked cells", sets);
// $(".is-active").each((i,td) => console.log(td.innerText))
});
});
td {
transition-duration: 0.5s;
border: solid black 1px;
cursor: pointer;
}
div {
padding: 5px;
}
table {
border-collapse: collapse;
}
.aqua {
background-color: aqua;
}
td:hover {
background-color: yellow;
}
.is-active {
background-color: aqua;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=calendar></div>

Making an HTML page to display n rows of pascal's triangle, cannot array.push the current row to page

I am new to JavaScript, and decided to do some practice with displaying n rows of Pascal's triangle. I have everything working, and the rows are displayed in the console, however when I try to push the currentRow to the array of triangle, nothing shows up on the page. Here is how I am attempting to do so:
if (typeof currentRow !== 'undefined') {
console.log('Row ', i - 2);
currentRow = currentRow.join(' ');
console.log(currentRow);
console.log(triangle);
triangle.push('n', currentRow)
triangle = triangle.join('');
}
Any help/advice would be apreciated. I am sure this code is not that efficient (I know it is not optimal to just write out the first 3 rows). Below is a code snippet, and a jsfiddle.
https://jsfiddle.net/keuo8za0/
var row0 = [1];
var row1 = [1, 1];
var row2 = [1, 2, 1];
row0 = row0.join(' ');
row1 = row1.join(' ');
row2 = row2.join(' ');
var triangle = [row0];
triangle.push('\n', row1);
triangle.push('\n', row2);
triangle = triangle.join('');
lastRow = [1, 2, 1];
var submit = document.getElementById('submit');
function buildTriangle(pascalNumber) {
for (let i = 4; i < pascalNumber; i++) {
if (typeof currentRow !== 'undefined') {
console.log('Row ', i - 2);
currentRow = currentRow.join(' ');
console.log(currentRow);
console.log(triangle);
}
var x = i;
var currentRow = [1, 1];
for (let y = 1; y + 1 < x; y++) {
var nextNumber = (lastRow[y - 1] + lastRow[y]);
currentRow.splice(1, 0, nextNumber);
}
lastRow = currentRow;
}
}
function drawTriangle() {
document.getElementById('triangle').innerText = triangle;
}
submit.onclick = function() {
var rownum = document.getElementById('pn').value;
buildTriangle(rownum - 1);
drawTriangle();
return false;
}
body {
background: #4286f4;
font-family: arial;
}
h1 {
font-size: 36px;
text-align: center;
}
h1:hover {
color: #ff35c5;
}
form {
font: sans-serif;
text-align: center;
}
p {
font-size: 36px;
font: sans-serif;
text-align: center;
}
#map {
margin: 0 auto;
width: 80%;
height: 80%;
}
<html>
<head>
<title>Pascal's Triangle</title>
<link rel="stylesheet" href="fancy.css" />
</head>
<body>
<h1>Pascal's Triangle</h1>
<form id='numberOfRows'>
Number of Rows:<br>
<input id='pn' type='number'><br>
<button id='submit'>Submit</button>
</form>
<p id='triangle'></p>
<script src="triangler.js"></script>
</body>
</html>
Interesting... I did it row by row. Found really good help from google..
<style>
body {
background: #4286f4;
font-family: arial;
}
h1 {
font-size: 36px;
text-align: center;
}
h1:hover {
color: #ff35c5;
}
form {
font: sans-serif;
text-align: center;
}
p {
font-size: 36px;
font: sans-serif;
text-align: center;
}
#map {
margin: 0 auto;
width: 80%;
height: 80%;
}
</style>
<h1>Pascal's Triangle</h1>
<form id='numberOfRows'>
Number of Rows:<br>
<input id='pn' type='number'><br>
<button id='submit'>Submit</button>
</form>
<p id='triangle'></p>
<script>
var div = document.getElementById('triangle');
submit.onclick = function() {
div.innerHTML = "";
var rownum = document.getElementById('pn').value;
printPascal(rownum);
return false;
};
function printPascal(n) {
// Iterate through every line and
// print entries in it
for (var line=0; line < n; line++)
{
var lineHTML = "<div class='text-center'>";
// Every line has number of
// integers equal to line
// number
for (var i = 0; i <= line; i++) {
lineHTML += "" + binomialCoeff(line, i) + " ";
}
lineHTML += "</div>\n";
div.innerHTML += lineHTML;
}
}
// for details of this function
function binomialCoeff(n, k)
{
var res = 1;
if (k > n - k)
k = n - k;
for (var i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
</script>

Add multiple colspans that line up in HTML

I'm building a calendar scheduler where I am hoping to add multiple tasks to one employee row. Whenever I try to add multiple tasks to the same time span, the spans no longer line up. Here is an example of how it looks now: . What would be the best practice to add tasks to the same day columns while keeping a task like "Slaughter them" similar?
HTML Script:
<script>
var sysDate = new Date();
var sysDay = new Date();
var sysMonth = new Date();
var dayCount = sysDay.getDay();
var weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
let employee;
let typeofKey;
let empArry = [];
let x = 1;
let y = 0;
let trInc= 0;
var drawTable = '<table id = wholeTable>';
drawTable += "<thead>";
drawTable += "<tr>";
drawTable += "<th style='color:white;'>Employee Name<\/th>";
let today = new Date();
let dd = today.getDate();
let mm = today.getMonth()+1; //January is 0!
let mmN = mm;
let yyyy = today.getFullYear();
let oneWeekAhead = new Date();
let nextWeek = (today.getDate()+10) + 10;
/* If next week falls into the next month, print correctly */
if (nextWeek > 30 && (mmN == 9 || mmN == 4 || mmN == 6 || mmN == 11)) {
mmN++;
nextWeek -= 30;
}
else if (nextWeek > 31 && (mmN == 1 || mmN == 3 || mmN == 5 || mmN == 7 || mmN == 8 || mmN == 10 || mmN == 12)) {
mmN++;
nextWeek -= 31;
}
else if (nextWeek > 28 && mmN == 2) {
mmN++;
nextWeek -= 28;
}
/* Formatting of the dates at the top of the table */
if(dd < 10) {
dd = '0'+ dd;
}
if(nextWeek < 10) {
nextWeek = '0' + nextWeek;
}
if(mmN < 10) {
mmN = '0' + mmN
}
if(mm < 10) {
mm = '0' + mm;
}
let edate = yyyy + mmN + nextWeek;
/* Finds the logged earliest and latest dates */
let startDate1 = yyyy.toString() + mm.toString() + dd.toString();
let startDate = parseInt(startDate1);
let endDate = parseInt(edate);
let startDateN = 20180501;
let endDateN = 20180531;
/* Change the strings of dates to ints for calculation of start and end date of the table */
if( localStorage.length > 0){
for (var key in localStorage) {
typeofKey = (typeof localStorage[key]);
if (typeofKey == 'string' || typeofKey instanceof String ){
emp1 = JSON.parse(localStorage.getItem(key));
if ("Task" in emp1) {
for (let i = 0; i < emp1.Task.length; i++) {
startDateN = parseInt(emp1.Task[i]['Task Start Date'].substr(0,4) + emp1.Task[i]['Task Start Date'].substr(5,2) + emp1.Task[i]['Task Start Date'].substr(8,2));
endDateN = parseInt(emp1.Task[i]['Task End Date'].substr(0,4) + emp1.Task[i]['Task End Date'].substr(5,2) + emp1.Task[i]['Task End Date'].substr(8,2));
if(endDateN > endDate) {
endDate = endDateN;
}
if(startDateN < startDate) {
startDate = startDateN;
}
}
}
}
}
}
let numStr = null;
let numStrDay = null;
let finalDay = null;
let finalDayF = null;
let colCount = 0;
/* Correctly print the months and days at the top of the table */
for (let i = startDate; i <= endDate +1; i++) {
numStr = (i.toString()).substr(4,2);
numStrDay = (i.toString()).substr(6,2);
if(numStr == '09' || numStr == '04' || numStr == '06' || numStr == '11') {
if(numStrDay == '31') {
i += 69;
}
else {
finalDay = i.toString()
finalDayF = (finalDay.substr(0,4)) + "-" + (finalDay.substr(4,2)) + "-" + (finalDay.substr(6,2));
drawTable += "<th class = days id = days" + x + '-' + y + ">" + finalDayF + "</th>";
colCount++;
}
}
else if(numStr == '01' || numStr == '03' || numStr == '05' || numStr == '07' || numStr == '08' || numStr == '10' || numStr == '12') {
if(numStrDay == '32') {
i += 68;
}
else {
finalDay = i.toString()
finalDayF = (finalDay.substr(0,4)) + "-" + (finalDay.substr(4,2)) + "-" + (finalDay.substr(6,2));
drawTable += "<th class = days id = days" + x + '-' + y + ">" + finalDayF + "</th>";
colCount++;
}
}
else if(numStr == '02') {
if(numStrDay == '29') {
i += 71;
}
else {
finalDay = i.toString()
finalDayF = (finalDay.substr(0,4)) + "-" + (finalDay.substr(4,2)) + "-" + (finalDay.substr(6,2));
drawTable += "<th class = days id = days" + x + '-' + y + ">" + finalDayF + "</th>";
colCount++;
}
}
else {
finalDay = i.toString()
finalDayF = (finalDay.substr(0,4)) + "-" + (finalDay.substr(4,2)) + "-" + (finalDay.substr(6,2));
drawTable += "<th class = days id = days" + x + '-' + y + ">" + finalDayF + "</th>";
colCount++;
}
x++;
}
drawTable += "</tr>";
drawTable += "</thead>";
drawTable += '<tbody class="dragscroll">';
//drawTable += "<tr id =" + trInc + ">";
//trInc++;
//counters for the employee and date rows/col
x=0;
y=1;
// counter for the main table
let z =1;
for (var key in localStorage) {
typeofKey = (typeof localStorage[key]);
//cols of the employee names
if(typeofKey == 'string' || typeofKey instanceof String ){
drawTable += "<tr id =" + trInc + ">";
trInc++;
employee = JSON.parse(localStorage.getItem(key));
drawTable += "<td class = employ id =emp" + x + '-' + y + ">" + employee['Employee Name'] + "</td>";
// rows and cols of the main table and date
for (let j = 0; j < colCount; j++) {
drawTable += "<td class =" + z + '-' + y + "></td>";
z++;
}
// set z to one to start the main tables x at 1 for off by one error
z=1;
//reset x for each row
x=0;
drawTable += '</tr>';
y++;
}
}
drawTable += '<tr>';
var noRows = 14 - localStorage.length;
for(; noRows >= 0; noRows--){
drawTable += "<td class = employ id =emp" + x + '-' + y + ">" + "" + "</td>";
// rows and cols of the main table and date
for (let j = 0; j < colCount; j++) {
drawTable += "<td class =" + z + '-' + y + "></td>";
z++;
}
// set z to one to start the main tables x at 1 for off by one error
z=1;
//reset x for each row
x=0;
drawTable += '</tr>';
y++;
}
drawTable += "</tbody>";
drawTable += "</table>";
document.write(drawTable);
</script>
CSS:
table {
/* border: 0.0625em solid black; */
table-layout: fixed;
position: relative;
width: auto;
overflow: hidden;
border-collapse: collapse;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
}
html, body{
height: 100%;
width: 100%;
background: linear-gradient(45deg, #e1e1e1, #f6f6f6);
}
/*thead*/
thead {
position: relative;
display: block; /*seperates the header from the body allowing it to be positioned*/
width: 1535px;
overflow: visible;
/* border: 1px solid black; */
}
td, th {
padding: 0.75em 1.5em;
text-align: left;
}
thead th {
min-width: 140px;
max-width: 140px;
height: 35px;
text-align: center;
}
thead th:nth-child(1) { /*first cell in the header*/
position: relative;
display: float;
min-width: 140px;
background-color: #202020;
}
/*tbody*/
tbody {
position: relative;
display: block; /*seperates the tbody from the header*/
width: 1535px;
height: 475px;
overflow: scroll;
}
tbody td {
background-color: white;
min-width: 140px;
max-width: 140px;
border: 2px solid #474747;
white-space: nowrap;
}
tbody tr td:nth-child(1) { /*the first cell in each tr*/
position: relative;
/*display: block; seperates the first column from the tbody*/
height: 40px;
min-width: 140px;
max-width: 140px;
}
.dragscroll {
overflow-y: hidden;
margin-right: 0;
height: 600px;
}
.days {
background-color: #31bc86;
color: white;
text-align: center;
}
.employ {
background-color: #2ea879;
color: white;
text-align: center;
}
#taskDiv {
position: absolute;
border: 2px solid black;
}
#days, #emp{
background-color: #071833;
color: white;
}
::-webkit-scrollbar {
width: 20px;
}
/* Track */
::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px black;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #071833;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #1caf8f
}
JS:
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
$(document).ready(function(){
let typeofKey;
let empArry = [];
let employee;
let myTable = document.getElementById('wholeTable');
let colFill = false;
let color = null;
//cols of the employee names
for (var i = 0; i < localStorage.length; i++){
empArry.push(localStorage.key(i))
}
// loop through the local storage and pull the data
for(let j = 0; j < empArry.length; j++){
color = getRandomColor();
employee = JSON.parse(localStorage.getItem(empArry[j]));
// If employee has any task
if("Task" in employee){
// while employee has task in his array
for(let taskIndex = 0; taskIndex < employee.Task.length; taskIndex++){
for(let k = 1; k < myTable.rows[0].cells.length; k++) {
if(myTable.rows[0].cells[k].innerHTML == employee.Task[taskIndex]["Task Start Date"]) {
colFill = true;
}
if(colFill == true) {
myTable.rows[j+1].cells[k].innerHTML += '<div style="background-color:' + color + '">' + employee.Task[taskIndex]["Task Name"] + '</br></div>';
}
if(myTable.rows[0].cells[k].innerHTML == employee.Task[taskIndex]["Task End Date"]) {
colFill = false;
}
}
}
}
}
});
JSFiddle: https://jsfiddle.net/py5gzw0b/1/#&togetherjs=eM8xgAd5eV
Set the vertical-align CSS property for those table cells to top;
td {
vertical-align:top;
}
https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align
If you need each item to be on its own row [along with all identical tasks] and perfectly aligned there, then you would need to create row 1, and insert only the Slaughter tasks, followed by creating row 2, inserting only the Cry tasks. This would then ensure that they would all correctly line up with one another, although it would take up more space as a result.
Another solution besides creating a row for each task would be to use jQuery to find the "max top of the task" and setting all instances at that top. Since they take the same space it should be doable and more flexible BUT you're in for some css-positioning fun.
To be more specific, you should :
1/ Add an unique identifier to each task : <div id_task="1" style=...
2/ Loop on each instance to find max top value :
maxTop=0;
$('[id_task=1]').each(function(){
newTop=$(this).position().top;
if(newTop>maxTop)maxTop=newTop;
});
3/ Use maxTop to set all id_task=1 to the same top, probably set these divs to relative too : $('[id_task=1]').css({'top':maxTop,'position':'relative');
4/ Enjoy fine-tuning this to close in on your desired goal, it'll take a while ^^
I made the code quickly as an example, there's no guarantee to it.
Take a look at this:
var cols = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
var employees = [
{
Name: 'Jason',
Task:[
{'Task Start Date':'Mon','Task End Date':'Thu','Task Name':'Do nothing'},
{'Task Start Date':'Thu','Task End Date':'Fri','Task Name':'Do a bit'},
{'Task Start Date':'Sat','Task End Date':'Sun','Task Name':'Do everything'}
]
},
{
Name: 'Timmy',
Task:[
{'Task Start Date':'Mon','Task End Date':'Sun','Task Name':'On vacation'},
{'Task Start Date':'Sat','Task End Date':'Sun','Task Name':'Still on vacation'},
]
}
]
function RowCompound(employee,columns){
var tasks = employee.Task
var spans = []
var max_rows = 1
var rowmap = []
var rows = []
function calcSpans(){
for(var i=0;i<tasks.length;i++){
var cspan = null
for(var u=0;u<columns.length;u++){
if(tasks[i]['Task Start Date']==columns[u]){
cspan = {row:0,start:u,task:tasks[i]}
}
if(cspan && tasks[i]['Task End Date']==columns[u]){
cspan.end = u
spans.push(cspan)
cspan = null
}
}
if(cspan){
cspan.end = columns.length-1
spans.push(cspan)
}
}
}
function solveConflicts(){
var conflict = true
while(conflict){
conflict = false
for(var i=0;i<spans.length;i++){
for(var u=i+1;u<spans.length;u++){
if(spans[i].row!=spans[u].row) continue
if(spans[i].start>spans[u].end || spans[i].end<spans[u].start) continue
conflict = true
max_rows = Math.max(max_rows,++spans[u].row + 1)
}
}
}
}
function createRowMap(){
for(var u=0;u<max_rows;u++){
var row = []
for(var i=0;i<columns.length;i++){
var empty = true
for(var k=0;k<spans.length;k++){
if(spans[k].row!=u) continue
if(i==spans[k].start){
empty = false
var span = spans[k].end-spans[k].start+1
row.push({task:spans[k].task,colspan:span,rowspan:1})
i += span-1
break
}
}
if(empty)
row.push({task:null,colspan:1,rowspan:1})
}
rowmap.push(row)
}
}
function buildDom(){
for(var i=0;i<rowmap.length;i++){
var row = document.createElement('tr')
for(var u=0;u<rowmap[i].length;u++){
if(rowmap[i][u].rowspan==0) continue
var cell = document.createElement('td')
cell.colSpan = rowmap[i][u].colspan
cell.rowSpan = rowmap[i][u].rowspan
if(rowmap[i][u].task){
cell.innerHTML = rowmap[i][u].task['Task Name']
cell.className = 'busy'
}
row.appendChild(cell)
}
rows.push(row)
}
var head = document.createElement('td')
head.rowSpan = max_rows
head.innerHTML = employee.Name
rows[0].prepend(head)
}
calcSpans()
solveConflicts()
createRowMap()
buildDom()
return rows
}
// example use
employees.forEach(function (emp){
var result_rows = RowCompound(emp,cols)
for(var i in result_rows){
document.getElementById('table').appendChild(result_rows[i])
}
})
table{
width: 100%;
border-collapse: collapse;
}
table td{
border: solid 1px #ccc;
width: 50px;
}
table td.busy{
background-color: dodgerblue;
color: white;
}
<table id="table">
<thead>
<th>Employee</th>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
<th>Sun</th>
</thead>
</table>
What this does is:
Create virtual spans for each task
If the spans overlap, push them one row lower
Create multiple rows utilizing the rowSpan attribute
Append the said rows to the table
You're gonna need to rewrite your code a little for this to work, but i think its the way to go.
Please note, the createRowCompound function requires the columns of the table as array in order to create the layout. See the example use.
Questions?
This is more of a conceptual answer/idea, but I think that you might be able to use the Isotope javascript layout library with the "vertical" layout mode:
https://isotope.metafizzy.co/layout-modes.html
You can disable all kinds of animations, so in that sense, this would be a shortcut to the "css positioning fun" that #Nomis mentions in the answer above. There's also the https://masonry.desandro.com library by the same person - might be worth a look.

Using a for loop to set background images using Javascript

I am trying to set background URL of all the tiles to the name in the memory array.
I have tried:
document.getElementById('tile_' + i).style.background = 'url(' + memory_array[i] + ') no-repeat';;
But this does not work!
I wasn't sure what to put the arrays names as ... I think url(img.gif) is correct?
var memory_array = ['url(img1.gif)', 'img1.gif', 'img2.gif', 'img2.gif', 'img3.gif', 'img3.gif', 'img4.gif', 'img4.gif', 'img5', 'img5'];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
Array.prototype.memory_tile_shuffle = function() {
var i = this.length,
j, temp;
while (--i > 0) {
j = Math.floor(Math.random() * (i + 1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
}
function newBoard() {
tiles_flipped = 0;
var output = '';
memory_array.memory_tile_shuffle();
for (var i = 0; i < memory_array.length; i++) {
output += '<div id="tile_' + i + '" onclick="memoryFlipTile(this,\'' + memory_array[i] + '\')"></div>';
}
document.getElementById('memory_board').innerHTML = output;
// This is the relevant line
document.getElementById('tile_' + i).style.background = 'url(' + memory_array[i] + ') no-repeat';
}
function memoryFlipTile(tile, val) {
if (tile.innerHTML == "" && memory_values.length < 2) {
tile.style.background = 'url(qm.gif) no-repeat';
tile.innerHTML = val;
if (memory_values.length == 0) {
memory_values.push(val);
memory_tile_ids.push(tile.id);
} else if (memory_values.length == 1) {
memory_values.push(val);
memory_tile_ids.push(tile.id);
if (memory_values[0] == 1) {
tiles_flipped += 2;
//Clear both arrays
memory_values = [];
memory_tile_ids = [];
// Check to see if the whole board is cleared
if (tiles_flipped == memory_array.length) {
alert("Well done your a smart person ... Can you do it again ?");
document.getElementById('memory_board').innerHTML = "";
newBoard();
}
} else {
function flip2back() {
//Flip the 2 tiles back over
var tile_1 = document.getElementById(memory_tile_ids[0]);
var tile_2 = document.getElementById(memory_tile_ids[1]);
tile_1.style.background = 'url(qm.gif) no-repeat';
tile_1.innerHTML = "";
tile_2.style.background = 'url(qm.gif) no-repeat';
tile_2.innerHTML = "";
// Clear both array
memory_values = [];
memory_tile_ids = [];
}
setTimeout(flip2back, 700);
}
}
}
}
div#memory_board {
background: black;
border: 1px solid black;
width: 900px;
height: 540px;
padding: 24px;
margin: 0px auto;
margin-bottom: 10px;
}
div#memory_board > div {
background: url(qm.gif) no-repeat;
background-size: 100% 100%;
border: 1px solid #fff;
width: 120px;
height: 120px;
float: left;
margin: 8px;
padding: 20px;
font-size: 20px;
cursor: pointer;
text-align: center;
color: white;
border-radius: 5px;
}
<!DOCTYPE html>
<html>
<head>
<title>Basic Java</title>
<link href='style.css' type='text/css' rel='stylesheet' />
<script src="java.js"></script>
</head>
<body>
<!--HEADER-->
<div class='holder header'>
<h1>Simple picture guessing game</h1>
</div>
<!--Container-->
<div id='memory_board'>
<script>
newBoard();
</script>
<!--Add window.addEventListener() for window load.-->
</div>
<!--footer-->
<div class='holder footer'>
</div>
</body>
</html>
// This is the relevant line
That line should be
document.getElementById('tile_' + i).style.background = 'url(' + memory_array[i] + ') no-repeat';
And your array should be
var memory_array = ['img1.gif', 'img1.gif', 'img2.gif', 'img2.gif', 'img3.gif', 'img3.gif', 'img4.gif', 'img4.gif', 'img5.gif', 'img5.gif'];
Also make sure the path to your images is correct
Alternatively you can use backgroundImage
document.getElementById('tile_' + i).style.backgroundImage = 'url(' + memory_array[i] + ')';
Few things here
you might consider changing the code at newBoard function as the following
function newBoard() {
tiles_flipped = 0;
var output = '';
memory_array.memory_tile_shuffle();
for (var i = 0; i < memory_array.length; i++) {
output += '<div id="tile_' + i + '" onclick="memoryFlipTile(this,\'' + memory_array[i] + '\')"></div>';
}
document.getElementById('memory_board').innerHTML = output;
// This is the relevant line
var title=document.getElementById('tile_' + i);
var imageUrl=url(memory_array[i] + 'no-repeat');
title.style.backgroundImage = imageUrl;
}
Always store your dom search into a variable and then operate on the variable.
ex: var title=document.getElementById('tile_' + i);
Hope this helps

Merge two HTML tables using Javascript Objects as data feed?

I am going to have multiple arrays of arrays and I want to make objects from the array and then merge it into one table. I already did that, however I need help using the object to make one larger table?
If a key exists in one object but not the others the value can just be blank for the object the key doesnt exist. I am able to make multiple different tables but how can I merge them to make the table one larger one?
var data =[["default_PROJECT","Allow","Connect","Allow","AddComment","Allow","Write",
"Allow","ViewComments","Allow","ExportData","Allow","ExportImage","Allow","ViewUnderlyingData","Allow","Read","Allow","ShareView","Allow","Filter"],
["Allow","ExportImage","Allow","Write","Allow","ViewComments",
"Allow","ShareView","Allow","Filter","Allow","ExportData","Allow","Connect","Allow",
"Read","Allow","ViewUnderlyingData","Allow","AddComment","Allow","ViewComments","Deny","ExportData","Allow",
"AddComment","Deny","Write","Allow","Read","Deny","ExportXml","Deny","ShareView","Allow","Connect","Allow","ChangeHierarchy","Allow",
"WebAuthoring","Deny","ViewUnderlyingData","Deny","Filter","Deny","ExportImage"]];
var result = [];
for(var i = 0, len = data.length; i < len; i++) {
var list = data[i];
result[i] = { name: list[0] };
for (var j = list.length - 1; j >= 1; j = j - 2) {
var key = list[j];
var value = list[j - 1];
if( result[i][key] !== "Deny" ) {
result[i][key] = value;
}
}
}
console.log(result);
var resultElement = document.getElementById('result1');
var tpl = '';
for(var t = 0, tLen = result.length; t < tLen; t++) {
var item = result[t];
tpl+= '<table align=center style="width:25%;">' +
'<thead>' +
'<tr><td colspan="2">Project: ' + item.name + '</td></tr>' +
'<tr><th>Permission</th><th>Value</th></tr>' +
'</thead>' +
'<tbody>'
;
for(var key in item) {
if(!item.hasOwnProperty(key) || key === 'name') { continue; }
if(item[key] == "Allow"){
tpl += '<tr style="background-color:greenyellow;"><td>'+ key +'</td><td>'+ item[key] +'</td></tr>';
}
else{
tpl += '<tr style="background-color:red;"><td>'+ key +'</td><td>'+ item[key] +'</td></tr>';
}
}
}
resultElement.innerHTML = tpl;
table { text-align: left; width: 100%; margin-bottom: 50px; border-collapse: collapse;}
td, th { width: 50%; border: 1px solid black; line-height: 1; padding:2px 10px;}
[colspan="2"] { color: blue; font-weight: bolder;text-transform: uppercase; text-align: center;}
<div id="result1"></div>
http://jsfiddle.net/h2s17hac/
This merges the two tables.
Fiddle
var data =[["default_PROJECT","Allow","Connect","Allow","AddComment","Allow","Write",
"Allow","ViewComments","Allow","ExportData","Allow","ExportImage","Allow","ViewUnderlyingData","Allow","Read","Allow","ShareView","Allow","Filter"],
["test_PROJECT", "Allow","ExportImage","Allow","Write","Allow","ViewComments",
"Allow","ShareView","Allow","Filter","Allow","ExportData","Allow","Connect","Allow",
"Read","Allow","ViewUnderlyingData","Allow","AddComment","Allow","ViewComments","Deny","ExportData","Allow",
"AddComment","Deny","Write","Allow","Read","Deny","ExportXml","Deny","ShareView","Allow","Connect","Allow","ChangeHierarchy","Allow",
"WebAuthoring","Deny","ViewUnderlyingData","Deny","Filter","Deny","ExportImage"]];
function makeObjects(data){
result = [];
for(var i = 0, len = data.length; i < len; i++) {
var list = data[i];
result[i] = { Name: list[0] };
for (var j = list.length - 1; j >= 1; j = j - 2) {
var key = list[j];
var value = list[j - 1];
if( result[i][key] !== "Deny" ) {
result[i][key] = value;
}
}
}
return result;
}
function sortObject(obj) {
return Object.keys(obj).sort().reduce(function (result, key) {
result[key] = obj[key];
return result;
}, {});
}
function getKeys(data){
var keys = [];
for(i=0; i<data.length; i++){
key = Object.keys(data[i]);
for(j =0; j<key.length; j++){
if(keys.indexOf(key[j]) == -1){
keys.push(key[j]);
}
}
}
return keys;
}
function addMissingKeys(keys, data){
var filtData = [];
for(i=0; i<data.length; i++){
for(j=0; j<keys.length; j++){
if(data[i][keys[j]] == undefined){
data[i][keys[j]] = "";
}
}
}
for(num=0; num<data.length; num++){
filtData.push(sortObject(data[num]));
}
return filtData;
}
var dataa = makeObjects(data);
var keys = getKeys(dataa);
var filtData = addMissingKeys(keys, dataa);
console.log(filtData);
var resultElement = document.getElementById('result1');
var tpl = '<table align=center style="width:75%;">';
for(var t = 0, tLen = filtData.length; t < tLen; t++) {
var item = filtData[t];
tpl+= '<tr><td>' + item.Name + '</td>';
for(var key in item) {
if(!item.hasOwnProperty(key) || key === 'Name') { continue; }
if(item[key] != "") {
if(item[key] == "Allow"){
tpl += '<td style="background-color:greenyellow;">'+ key +':<br>'+ item[key] +'</td>';
}
else{
tpl += '<td style="background-color:red;">'+ key +':<br>'+ item[key] +'</td>';
}
} else {
tpl += '<td></td>';
}
}
tpl += '</tr>';
}
tpl += '</table>';
resultElement.innerHTML = tpl;
table { text-align: left; width: 100%; margin-bottom: 50px; border-collapse: collapse;}
td, th { width: 50%; border: 1px solid black; line-height: 1; padding:2px 10px;}
[colspan="2"] { color: blue; font-weight: bolder;text-transform: uppercase; text-align: center;}
<div id="result1"></div>
<div id="test"></div>

Categories

Resources