How to get 8 columns per row? [Javascript , Bootstrap] - javascript

So i am here wrote this simple function for searching movies and manipulating them in the dom.and the problem here is when a movie name is typed the api response back with at least 20/30 recommendations.And i want the fetched data to be distributed in 8 columns per row.So i wrote this function :
Javascript part :
db.multisearch()
.then(data=>{
var div=document.getElementById('call');
var output='';
for(let i=0;i<data.length;i++){
var poster=data[i].poster_path;
var title=data[i].title;
for(let j=0;j<=8;j++){
output +=`<div class="col-sm">
<div class="card mb-3">
<img class="card-img-top" src='https://image.tmdb.org/t/p/w342//${poster}' alt="Card image cap">
<div class="text-block"><p>${title}</p></div>
</div>
</div>`;
}
}
div.innerHTML=output;
});
HTML part that im manipulating :
<section class="movie-page">
<div class="container">
<div class="row" id="call"></div>
</div>
But Instead of the desired outcome ,it just repeats one movie 8 times.
And I am trying to get the model to be somewhat like this each row without repeating any movie:
I am a newbie so i might have missed something. Please do help .

Your loop should be like the following; you need to close the current row after every 8th item and then open a new row.
var output = '<div class="row">';
for(let j=1; j<=data.lenght; j++){
output +=`<div class="col-xs-1">
content into column
</div> \n`;
if(j !== 0 && j%8 === 0) {
output += '</div><div class="row">';
}
}
output += '</div>';
See the working example below:
var output = '<div class="row">';
for(let j = 1; j<= 50; j++){
output +=`<div class="col-xs-1">
${j}
</div> \n`;
if(j !== 0 && j%8 === 0) {
output += '</div><div class="row">';
}
}
output += '</div>';
document.getElementById('container').innerHTML = output;
.row {
margin-bottom: 10px;
overflow: hidden;
display: block;
}
.row .col-xs-1 {
float: left;
box-sizing: border-box;
color: red;
text-align: center;
display: block;
margin-bottom: 10px;
width: 8.33%;
padding: 10px;
}
<div class="container" id="container"></div>

Related

How to sort `divs` based on user's number of clicks using JS?

I'm using a script that counts how many times the user clicks each link and sort their order based on that number...
It works fine as is, however it doesn't work if the <a> tags is nested inside a div. It's ignoring the divs and the content/image/icon inside, while showing only the links..
How to change it so that it will show and reorder the entire div instead of just the link?
Please see what I have so far:
function updateClicks(ele) {
const storage = window.localStorage.getItem(ele.innerHTML + " clicks");
if (storage === null) {
window.localStorage.setItem(ele.innerHTML + " clicks", "1");
} else {
var clicks = parseInt(window.localStorage.getItem(ele.innerHTML + " clicks")) + 1;
localStorage.removeItem(ele.innerHTML + " clicks");
window.localStorage.setItem(ele.innerHTML + " clicks", clicks);
}
}
function orderItems() {
var order = [];
var href = [];
var links = document.getElementById("links-list");
var link = links.getElementsByTagName("a");
for (i = 0; i < link.length; i++) {
href.push(link[i].href);
}
links = links.innerHTML.split("</a>");
document.getElementById("links-list").innerHTML = "";
for (i = 0; i < links.length - 1; i++) {
var lastChar = links[i].charAt(links[i].length - 1);
var clicks = parseInt(window.localStorage.getItem(lastChar + " clicks"));
if (isNaN(clicks)) {
clicks = 0;
}
order.push([lastChar, clicks, href[i]]);
}
order.sort(function(a, b) {
return a[1] - b[1]
});
order.reverse();
console.log(order)
for (i = 0; i < order.length; i++) {
document.getElementById("links-list").innerHTML += "<a href='" + order[i][2] + "' onclick='updateClicks(this)'>" + order[i][0] + "</a>";
}
}
.link-container {
display: inline-block;
}
.link-container a {
padding: 10px;
background-color: #c0c0c0;
}
.link-img {
width: 16px;
height: 16px;
}
<body onload="orderItems();">
<div id="links-list">
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/6ZpMxiG.png" />
A
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/sFUFOyO.png" />
B
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/M5a2gh8.png" />
C
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/mbrEuvR.png" />
D
</div>
</div>
</body>
I'm still trying to learn JS and I need this feature for a project I'm building.. Thank you in advance for any help.
Here is one way of keeping track of the click counts and sorting the divs accordingly:
// The cnt values in the divs array could be initialised from local storage:
const
list=document.getElementById("links-list"),
divs=[...list.querySelectorAll(".card")];
divs.forEach(e=>e.cnt=0)
list.onclick=ev=>{
if (ev.target.tagName!=="A") return;
ev.target.closest(".card").cnt++;
divs.sort((a,b)=>a.cnt-b.cnt)
.forEach(el=>list.append(el))
console.log(divs.map(e=>e.textContent.trim()+e.cnt).join(","))
}
.link-container {
display: inline-block;
border:1px solid grey;
}
.link-img {
width: 16px;
height: 16px;
}
<body">
<div id="links-list">
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/6ZpMxiG.png" />
A
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/sFUFOyO.png" />
B
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/M5a2gh8.png" />
C
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/mbrEuvR.png" />
D
</div>
</div>
</body>

Form to fill excel spreadsheet

I've been trying to build an application to submit form selections to an existing spreadsheet on a local machine. This is intended for a windows machine, but I am working on ubuntu, and don't have access to a windows development environment. With this, I'm trying to parse an excel document, find the bottom row, capture the 'ingredients' list, or other form values, then insert the value of the hash into the excel column and save the changes to the document. Any suggestions on where I should start would be great.
-- Thanks a million
//Script
$(document).ready(doInput);
function doInput(){
var ingreds = $('.ingredients');
var count = $('.count');
var runs = $('#runs');
var cb = $('.cb');
var bb = $('.bb');
var fullDate = new Date();
var twoDigitMonth = ((fullDate.getMonth().length+1) === 1)? (fullDate.getMonth()+1) : '0' + (fullDate.getMonth()+1);
var currentDate = twoDigitMonth + "/" + fullDate.getDate() + "/" + fullDate.getFullYear();
var bbDate = fullDate.getMonth() + 8;
cb.html("C&B:<br />" + currentDate);
if (bbDate > 12){
bb.html("BB:<br />" + "0" + (bbDate - 12) + "/" + fullDate.getDate() + "/" + (fullDate.getFullYear() + 1));
}else{
bb.html("Best By:<br />" + bbDate + "/" + fullDate.getDate() + "/" + fullDate.getFullYear());
}
var recipes = {
'Volvo': {
'Torq': 1231,
'Leather': 131,
'Blue': 22
},
'Jet': {
'HP': 1233,
'Leather': 121,
'Candy': 1313,
'Gas': 1313,
'Billiard': 223
},
'Mac': {
'Torq': 12111,
'Cheddar': 123
},
'Hog': {
'Torq': 475,
'Sugar': 12,
'Sheer': 11,
'Water': 2323,
'Wheels': 3
}
}
var recipe;
ingreds.html("Ingredients:<br />");
count.html("The Yield is:" + $('#yield').val() + "?<br />");
if ($("option:selected").val() == 'volv') {
recipe = recipes['Volvo'];
}else if($("option:selected").val() == 'jet') {
recipe = recipes['Jet'];
}else if($("option:selected").val() == 'mac') {
recipe = recipes['Mac'];
}else if($("option:selected").val() == 'hog') {
recipe = recipes['Hog'];
}
for (key in recipe){
if(key == 'Sugar'){
ingreds.append(key + ": " + recipe[key] * runs.val() + 'Lbs<br />');
}else{
ingreds.append(key + ": " + recipe[key] * runs.val() + 'g<br />');
}
}
return true;
}
body {
background: rgba(150,150,150,.5);
}
.container {
width: 80%;
margin: auto;
padding: 10px;
}
.ingredients {
padding: 10px;
padding-left: 20px;
}
.count {
margin-top: 25px;
font-weight: Bold;
color: #700;
}
.submit,
.ingredients,
.flavor,
.runs,
.yieldShell,
.bestBy,
.cb,
.bb {
min-width: 215px;
}
.count {
min-width: 190px;
}
.row {
margin-right: -15px;
margin-left: -15px;
}
.row:before,
.row:after {
display: table;
content: " ";
}
.row:after {
clear: both;
}
.col-sm-4{
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
#media (min-width: 540px) {
.container {
width: 750px;
}
.col-sm-4 {
float: left;
width: 33.33333333333333%;
}
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<div class="container">
<form oninput="doInput()">
<div class="row">
<div class="flavor col-sm-4">
Flavor:<br />
<select name="flavors">
<option value="volv" selected="selected">Volvo</option>
<option value="jet">Jet</option>
<option value="mac">Mac</option>
<option value="hog">Hog</option>
</select>
</div>
<div class="runs col-sm-4">
Number of runs:<br />
<input type="number" id="runs" name="runs" value="1">
</div>
</div>
<div class="row">
<div class="ingredients col-sm-4"></div>
<div class="yieldShell col-sm-4">
<div class="yield">Yield:<br />
<input type="number" id="yield" name="yield" value="450">
</div>
<div class="count col-sm-4"></div>
</div>
</div>
<div class="row">
<div class="submit col-sm-4">
<input type="submit" value="Save to Production Log?">
</div>
<div class="bestBy col-sm-4">
<div class="row">
<div class="col-sm-4 cb"></div>
</div>
<div class="row">
<div class="col-sm-4 bb"></div>
</div>
</div>
</div>
</form>
</div>
Are you not looking at this from the wrong angle?
Rarely would you try to access an Excel document directly, since the quantity of 'irrelevant' data is huge (data needed by Excel to reconstruct the page itself, but not directly related to the data the user is storing - meta-data if you will; i.e. font used, size of font, etc.).
Usually you would output the data to a CSV and allow the user to import the data into any spreadsheet program, which gives you greater flexibility and is simpler to code.
In terms of adding the data, you could easily open the existing CSV and append new data, or search the file and insert the data where required. However, if others are to use the CSV then I'd save the data in a single-table database as well as in the CSV. Then you simply construct a new CSV each time, overwriting any existing file if necessary.
No code help here at present, and I might be wrong, but this is the approach I have used and seen used.

Print after dragged items are placed

I need the final page (after going through and submitting everything) to print with the student names dragged into the team boxes, but whatever I try with the display/float/position properties, the student cards won't show when printing the page.
My code is using interact_min.js from Interact.io as well which is in the codepen project.
Codepen Project Link
Here is a screenshot of the final page when students are distributed into teams. I need the page to print out like this for teachers. (Class sizes vary so it has to work for >= 8 students which will be #ofTeams >= 2)
I have tried quite a few "fixes" from various sites, but none of them are working for me. Any help is appreciated. I am relatively new to coding, so please explain thoroughly.
This is what it looks like when I try to print.
Here I have changed the scale to 30% and you can see 7/8 of the student cards.
function isInputNumber(){
const inputNumber = parseInt($("#numberOfStudents").val());
if(isNaN(inputNumber)) {
alert('Must input a number');
return ;
} else {
return ;
}
}
function isNumberBigEnough() {
const numberS = parseInt($("#numberOfStudents").val());
if (numberS > 7 && isInputNumber) {
$('#submitTeams').removeAttr('disabled');
} else {
return ;
}
}
$('#numberOfStudents').keyup(isInputNumber).keyup(isNumberBigEnough);
//First submit function on the team form gives the user a response
$( "#submitTeams" ).click(function( event ) {
event.preventDefault();
const numberOfStudents = parseInt($("#numberOfStudents").val());
const divideByFour = numberOfStudents % 4;
let responseHTML = '<p id="numberOverall">'+numberOfStudents+'</p><p class="responseText">';
if (divideByFour === 0){
responseHTML += 'You will have ' + numberOfStudents / 4 + ' teams of 4 in your class.';
}
else if (divideByFour === 1) {
responseHTML += 'You will have ' + (numberOfStudents - 1) /4 + ' teams of 4 in your class and one team of 5.';
}
else if (divideByFour === 2) {
responseHTML += 'You will have ' + (numberOfStudents - 6) /4 + ' teams of 4 in your class and two teams of 3.';
}
else {
responseHTML += 'You will have ' + (numberOfStudents - 3) /4 + ' teams of 4 in your class and one team of 3.';
}
responseHTML += '</p>';
$('#studentNumberResponse').css('display', 'block').html(responseHTML);
//second submit function on the team form that makes the second form (studentsForm)
let responseHTMLSecond = '<div class="card-block"> <h4 class="card-title">Step 2: Enter Your Students</h4> <p class="card-text">Add your students to create each individual team.</p> <form id="studentsForm" onsubmit="return false;">';
let i = 0;
do {
i++;
responseHTMLSecond += '<h4 class="numberingStudents">Student ' + i + '</h4>';
responseHTMLSecond += '<div class="form-group"> <h4> <input type="text" class="form-control" id="studentFirstName'+i+'" aria-describedby="studentFirstName" placeholder="First Name"> </div> <div class="form-group"> <input type="text" class="form-control" id="studentLastName'+i+'" aria-describedby="studentLastName" placeholder="Last Name"> </div> <div class="form-group"> <label for="exampleSelect1">Select Student Level</label> <select class="form-control" id="exampleSelect'+i+'"> <option>High</option> <option>Mid-High</option> <option>Mid-Low</option> <option>Low</option> </select> </div>';
} while (i < numberOfStudents);
responseHTMLSecond += '<button type="submit" class="btn btn-primary" id="submitStudents" onclick="addStudentsClicked()">Submit</button> </form> <small class="text-muted">Click the Submit button when you have finished adding all students or after making any changes to student names.</small> </div>';
$('#secondsStep').show().html(responseHTMLSecond);
$('#numberOfStudents').val('');
});
//submit function on the studentsForm to show a response
function addStudentsClicked()
{
let responseHTMLThird = '<h4 class="card-title">Step 3: Review Class Roster</h4> <p class="card-text">Review your class roster before moving on to the next step. If you need to make any changes, scroll back up to Step 2 and hit submit again after changes have been made.</p>';
const numberOfStudentsTwo = parseInt($("#numberOverall").text());
let Students = [];
for (i =1; i < numberOfStudentsTwo+1; i++) {
let $firstName = $('#studentFirstName'+i+'').val();
let $lastName = $('#studentLastName'+i+'').val();
let $studentLevel = $('#exampleSelect'+i+' :selected').text();
Students[i] = new Object({$firstName, $lastName, $studentLevel});
responseHTMLThird += '<p class="studentRosterList">'+Students[i].$firstName+' '+Students[i].$lastName+' : '+Students[i].$studentLevel+'</p>';
}
responseHTMLThird += '<button type="submit" class="btn btn-primary" id="submitOverall" onclick="finalSubmit()">Submit</button>';
alert('Scroll down to review your student roster.');
$('#studentListResponse').show().html(responseHTMLThird);
}
function finalSubmit () {
if(confirm("Are you sure everything is correct?") === true){
$('.hideMe').hide();
document.location.href = "#top";
makingCards();
} else {
alert('Please make your changes before submitting again.');
}
}
function makingCards () {
let makeTeams = '<div class="card-block clearfix" id="makeTeams"><h4 class="card-title">Step 4: Make Teams</h4><p class="card-text">Use your mouse to click and drag students into team groupings. Remember, you don\'t want to have 2 Highs or 2 Lows on a team together.</p></div>';
const numberOfStudentsTwo = parseInt($("#numberOverall").text());
const numero = numberOfStudentsTwo % 4;
let fourthResponse = '';
let StudentsTwo = [];
for (i =1; i < numberOfStudentsTwo+1; i++) {
let $firstName = $('#studentFirstName'+i+'').val();
let $lastName = $('#studentLastName'+i+'').val();
let $studentLevel = $('#exampleSelect'+i+' :selected').text();
StudentsTwo[i] = new Object({$firstName, $lastName, $studentLevel});
fourthResponse += '<div class="card teamCard draggable" style="width: 10rem;"><div class="card-block teamCard-block">';
fourthResponse += '<h4 class="card-title teamCard-title">'+ StudentsTwo[i].$firstName;
fourthResponse += ' '+ StudentsTwo[i].$lastName;
fourthResponse += '</h4>';
fourthResponse += '<h6 class="card-subtitle mb-2 text-muted teamCard-subtitle">Student Level: '+ StudentsTwo[i].$studentLevel;
fourthResponse += '</h6>';
fourthResponse += '</div></div>';
}
$('#top').append(makeTeams);
teamNumber();
$('#teamDropBox').after(fourthResponse);
$('.teamCard').mousedown(handle_mousedown);
}
function teamNumber (numero) {
const numberOfStudentsTwo = parseInt($("#numberOverall").text());
let $teamDrops = '<table id="teamDropBox"><tbody>';
if (numero === 0){
let $teams = numberOfStudentsTwo / 4;
for (j=1; j < $teams; j++){
$teamDrops += '<tr><th class="teamDrops">Team ' + j +':</th><td class="dropzone"></td></tr>';
}
} else if (numero === 1) {
let $teams = (numberOfStudentsTwo - 1) / 4 + 1;
for (j=1; j < $teams; j++){
$teamDrops += '<tr><th class="teamDrops">Team ' + j +':</th><td class="dropzone"></td></tr>';
}
} else if (numero === 2) {
let $teams = (numberOfStudentsTwo - 6) / 4 + 2;
for (j=1; j < $teams; j++){
$teamDrops += '<tr><th class="teamDrops">Team ' + j +':</th><td class="dropzone"></td></tr>';
}
} else {
let $teams = (numberOfStudentsTwo - 3) / 4 + 1;
for (j=1; j < $teams; j++){
$teamDrops += '<tr><th class="teamDrops">Team ' + j +':</th><td class="dropzone"></td></tr>';
}
$teamDrops += '</tbody></table>';
}
$('#makeTeams').append($teamDrops);
}
//dragging code from online site - changed to interact.js code below
/*
function handle_mousedown(e){
window.my_dragging = {};
my_dragging.pageX0 = e.pageX;
my_dragging.pageY0 = e.pageY;
my_dragging.elem = this;
my_dragging.offset0 = $(this).offset();
function handle_dragging(e){
var left = my_dragging.offset0.left + (e.pageX - my_dragging.pageX0);
var top = my_dragging.offset0.top + (e.pageY - my_dragging.pageY0);
$(my_dragging.elem)
.offset({top: top, left: left});
}
function handle_mouseup(e){
$('body')
.off('mousemove', handle_dragging)
.off('mouseup', handle_mouseup);
}
$('body')
.on('mouseup', handle_mouseup)
.on('mousemove', handle_dragging);
}
*/
//interact.js code here:
// target elements with the "draggable" class
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// keep the element within the area of it's parent
restrict: {
restriction: "parent",
restriction: ".dropzone",
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
// enable autoScroll
autoScroll: true,
// call this function on every dragmove event
onmove: dragMoveListener,
});
function dragMoveListener (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '.draggable',
// Require a 75% element overlap for a drop to be possible
overlap: 0.75,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
}
});
* {
box-sizing: border-box;
}
#studentNumberResponse, #secondsStep, #studentListResponse {
display: none;
}
#numberOverall {
color: #fff;
}
.responseText {
font-size: 2rem;
}
.teamCard {
float: right;
margin: 2rem;
}
table {
border-collapse: collapse;
border: 1px solid grey;
margin: 3rem 0 5rem 1rem;
float: left;
}
table th {
border: 1px solid grey;
vertical-align: center;
text-align: center;
width: 18rem;
padding: 0 5rem;
text-transform: uppercase;
font-size: 2rem;
}
table td {
height: 15rem;
border: 1px solid grey;
width: 50rem;
}
#media print {
body * {
visibility: hidden;
}
#top, #top * {
visibility: visible;
}
#top {
position: absolute;
left: 0;
top: 0;
}
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>OnPoint Team Generator</title>
<meta name="description" content="OnPoint Team Generator">
<meta name="author" content="MeganRoberts">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>
<div class="card" id="top">
<h3 class="card-header" style="text-align: center;">OnPoint Team Generator</h3>
<div class="card-block hideMe">
<h4 class="card-title">Step 1: Number of Teams</h4>
<p class="card-text">How many students do you have in your class?</p>
<form id="teamForm">
<div class="form-group">
<input type="text" class="form-control" id="numberOfStudents" aria-describedby="numberStudents" placeholder="Enter Number of Students" data-toggle="tooltip" data-placement="top" title="Please enter a number larger than 7.">
</div>
<button type="submit" class="btn btn-primary" id="submitTeams" disabled>Submit</button>
</form>
</div>
</div>
<div class="card hideMe">
<div class="card-block" id="studentNumberResponse">
</div>
</div>
<div id="secondsStep" class="card hideMe">
</div>
<div id="listResponse" class="card hideMe">
<div class="card-block" id="studentListResponse">
</div>
</div>
<script src="interact_min.js"></script>
<script src="app.js"></script>
</body>
</html>
I had to overhaul my code a bit to get it to print. I changed the drag and drop to jquery UI sortable instead.
Codepen Project
Requires jquery UI to fully function so check out the codepen link -> below is the "final" code
$('#printbtn').hide();
$('#studentNumberResponse').hide();
$('#secondsStep').hide();
$('#listResponse').hide();
//Checking to make sure the input is a number for the rest of the program to work
function isInputNumber(){
//get user input
const inputNumber = parseInt($("#numberOfStudents").val());
//check if input is a number or not
if(isNaN(inputNumber)) {
alert('Must input a number');
return ;
} else {
return ;
}
}
//Checking to make sure that the input is larger than 7 in order to create teams and remove the disabled from the submit button
function isNumberBigEnough() {
//get user input
const numberS = parseInt($("#numberOfStudents").val());
//check to make sure that the number is large enough and then remove the disabled attribute
if (numberS > 7 && isInputNumber) {
$('#submitTeams').removeAttr('disabled');
} else {
return ;
}
}
//watching user input to determine if they can submit using the above functions
$('#numberOfStudents').keyup(isInputNumber).keyup(isNumberBigEnough);
//First submit function on the team form gives the user a response of how many teams and what kind of teams depending on their input
$( "#submitTeams" ).click(function( event ) {
//prevent the window from refeshing after submit event
event.preventDefault();
//get user input
const numberOfStudents = parseInt($("#numberOfStudents").val());
//DRY for repeated calc
const divideByFour = numberOfStudents % 4;
//response to user to tell them the number of teams there will be in their class
let responseHTML = '<p id="numberOverall">'+numberOfStudents+'</p><p class="responseText">';
if (divideByFour === 0){
responseHTML += 'You will have ' + numberOfStudents / 4 + ' teams of 4 in your class.';
}
else if (divideByFour === 1) {
responseHTML += 'You will have ' + (numberOfStudents - 5) /4 + ' teams of 4 in your class and one team of 5.';
}
else if (divideByFour === 2) {
responseHTML += 'You will have ' + (numberOfStudents - 6) /4 + ' teams of 4 in your class and two teams of 3.';
}
else {
responseHTML += 'You will have ' + (numberOfStudents - 3) /4 + ' teams of 4 in your class and one team of 3.';
}
responseHTML += '</p>';
//show and add the above html to the studentNumberResponse so the user can view the response
$('#studentNumberResponse').css('display', 'block').html(responseHTML);
//second submit function on the team form that makes the second form (studentsForm) to allow the user to enter student names for sorting later
//create form to match the student numbered entered
let responseHTMLSecond = '<div class="card-block"> <h4 class="card-title"><span>Step 2:</span> Enter Your Students</h4> <p class="card-text lightText">Add your students to create each individual team.</p> <form id="studentsForm" onsubmit="return false;">';
//needed for the do while loop
let i = 0;
do {
i++;
//firstname and lastname and level input for each student
responseHTMLSecond += '<h4 class="numberingStudents">Student ' + i + '</h4>';
responseHTMLSecond += '<div class="form-group"> <input type="text" class="form-control" id="studentFirstName'+i+'" aria-describedby="studentFirstName" placeholder="First Name"> </div> <div class="form-group"> <input type="text" class="form-control" id="studentLastName'+i+'" aria-describedby="studentLastName" placeholder="Last Name"> </div> <div class="form-group"> <label for="exampleSelect1">Select Student Level</label> <select class="form-control" id="exampleSelect'+i+'"> <option>High</option> <option>Mid-High</option> <option>Mid-Low</option> <option>Low</option> </select> </div>';
} while (i < numberOfStudents);
//add submit button to end of the student info form
responseHTMLSecond += '<button type="submit" class="btn btn-primary opbtn" id="submitStudents" onclick="addStudentsClicked()">Submit</button> </form> <small class="text-muted">Click the Submit button when you have finished adding all students or after making any changes to student names.</small> </div>';
//show and add the above html for the student info form
$('#secondsStep').show().html(responseHTMLSecond);
//clear the number of students input field
$('#numberOfStudents').val('');
});
//submit function on the studentsForm to show the class roster for a final check before moving on
function addStudentsClicked() {
//html for the third response
let responseHTMLThird = '<h4 class="card-title"><span>Step 3:</span> Review Class Roster</h4> <p class="card-text lightText">Review your class roster before moving on to the next step. If you need to make any changes, scroll back up to Step 2 and hit submit again after changes have been made.</p>';
//hidden numberOfStudents to use in future functions like this one = user input from first step
const numberOfStudentsTwo = parseInt($("#numberOverall").text());
//create empty array to add students from student info form
let Students = [];
//for each student, create an object with the input information from the previous form
for (i =1; i < numberOfStudentsTwo+1; i++) {
let $firstName = $('#studentFirstName'+i+'').val();
let $lastName = $('#studentLastName'+i+'').val();
let $studentLevel = $('#exampleSelect'+i+' :selected').text();
Students[i] = new Object({$firstName, $lastName, $studentLevel});
//use the data in the array to print out a student roster for the user to review
responseHTMLThird += '<p class="studentRosterList">'+Students[i].$firstName+' '+Students[i].$lastName+' : '+Students[i].$studentLevel+'</p>';
}
//final submit button for the user to click on after reviewing the student roster
responseHTMLThird += '<button type="submit" class="btn btn-primary opbtn" id="submitOverall" onclick="finalSubmit()">Submit</button>';
//response appears below the viewport, so an alert to let them know to scroll down
alert('Scroll down to review your student roster.');
//show and add response to the page
$('#listResponse').show();
$('#studentListResponse').show().html(responseHTMLThird);
}
//asking the user if everything is correct before moving on (cant go back and change)
function finalSubmit () {
if(confirm("Are you sure everything is correct?") === true){
//hide forms that are no longer needed
$('.hideMe').hide();
//move the user back to the top of the screen
document.location.href = "#top";
//cal the function to make the team boxes
makingTeams();
} else {
alert('Please make your changes before submitting again.');
}
}
//making the teams dropzone containers
function makingTeams () {
//header for step 4
let makeTeams = '<div class="card-block clearfix printMe" id="makeTeams"><h4 class="card-title"><span>Step 4:</span> Make Teams</h4><p class="card-text lightText">Use your mouse to click and drag students into team groupings. Remember, you don\'t want to have 2 Highs or 2 Lows on a team together.</p><p id="reminderTeams" class="lightText"></p></div>';
//get the number of students for creating the correct amount of teams
const numberOfStudentsTwo = parseInt($("#numberOverall").text());
//get the remainder to split the loops depending on the number of students
const numero = numberOfStudentsTwo % 4;
//start the response string
let $teamDrops = '';
//creating the team ul for sorting ui
if (numero === 0){
//if equally divisible, then the number divided by four = the number of teams
let $teams = numberOfStudentsTwo / 4;
for (let j=1; j < $teams +1; j++){
$teamDrops += '<ul class="teamDrops connected printMe"><h4>Team ' + j +':</h4></ul>';
}
} else if (numero === 1) {
//if remainder 1, then subtract the one team of five from the total, divide by four to get the number of teams and add back the 1 team of 5
let $teams = (numberOfStudentsTwo - 5) / 4 + 1;
for (let j=1; j < $teams +1; j++){
$teamDrops += '<ul class="teamDrops connected printMe"><h4>Team ' + j +':</h4></ul>';
}
} else if (numero === 2) {
//if remainder 2, then subtract 6 for the two teams of 3 then divide by four to get the number of teams and add back the 2 teams of 3
let $teams = (numberOfStudentsTwo - 6) / 4 + 2;
for (let j=1; j < $teams+1; j++){
$teamDrops += '<ul class="teamDrops connected printMe"><h4>Team ' + j +':</h4></ul>';
}
} else {
//if remainder 3, then subtract the one team of 3 then divide by four and add back the 1 team of 3
let $teams = (numberOfStudentsTwo - 3) / 4 + 1;
for (let j=1; j < $teams+1; j++){
$teamDrops += '<ul class="teamDrops connected printMe"><h4>Team ' + j +':</h4></ul>';
}
}
//append the instructions to the top
$('#top').append(makeTeams);
//append the team ul drops to the top
$('#top').append($teamDrops);
//create empty list for student roster to fill into
let studentRoster = '<ul id="rosterDrag" class="connected printMe"><h4>Student Roster</h4></ul>';
//append the student roster to the top
$('#top').append(studentRoster);
//call the function to make the student roster list for dragging
makingCards();
}
//making the individual student cards based off of the input from step 2
function makingCards () {
//get student number info
const numberOfStudentsTwo = parseInt($("#numberOverall").text());
//start response html
let fourthResponse = '';
//start array to hold student data
let StudentsTwo = [];
//start loop to create object for each student
for (i =1; i < numberOfStudentsTwo+1; i++) {
let $firstName = $('#studentFirstName'+i+'').val();
let $lastName = $('#studentLastName'+i+'').val();
let $studentLevel = $('#exampleSelect'+i+' :selected').text();
StudentsTwo[i] = new Object({$firstName, $lastName, $studentLevel});
//add html to the response
fourthResponse += '<li class="card teamCard'+i+' draggable printMe" style="width: 10rem;">';
fourthResponse += '<h4 class="card-title teamCard-title">'+ StudentsTwo[i].$firstName;
fourthResponse += ' '+ StudentsTwo[i].$lastName;
fourthResponse += '</h4>';
fourthResponse += '<h6 class="card-subtitle mb-2 text-muted teamCard-subtitle">Student Level: '+ StudentsTwo[i].$studentLevel;
fourthResponse += '</h6>';
fourthResponse += '</li>';
}
//append the student roster to the ul
$('#rosterDrag').append(fourthResponse);
//jquery ui to sort students into teams
$( function() {
//making the individual team ul's sortable and connected to each other
$( ".teamDrops" ).sortable({
connectWith: ".connected"
}).disableSelection();
//making the student roster ul sortable and connected to the others
$( "#rosterDrag" ).sortable({
connectWith: ".connected"
}).disableSelection();
});
//get number of teams info from first response
let reminder = $('.responseText').text();
//set reminder text to last page
$('#reminderTeams').text(reminder);
//show the print button
$('#printbtn').show();
}
//print the page
function pdfPrint () {
//hide unwanted elements from the printed page
$('#printbtn').hide();
$('#rosterDrag').hide();
$('#makeTeams').hide();
//print the window
window.print();
}
* {
box-sizing: border-box;
}
body {
background-color: lightgrey;
}
#opArrows {
width: 10rem;
height: auto;
}
.opbtn {
color: #fff;
background-color: #434343;
border-color: #434343;
}
.opbtn:hover {
color: #fff;
background-color: #f5822d;
border-color: #f5822d;
}
.opbtn:disabled {
color: #fff;
background-color: #8c8c8c;
border-color: #8c8c8c;
}
#title {
background-color: #0a6c8e;
color: black;
}
h4 span {
color: #c4da59;
}
#numberOverall {
color: #fff;
display: none;
}
#studentNumberResponse {
padding-top: 2rem;
font-size: 1.5rem;
color: #8c8c8c;
}
#listResponse p:nth-child(odd) {
background-color: lightgrey;
}
.studentRosterList {
width: 25%;
padding-left: 0.5rem;
}
.lightText {
color: #8c8c8c;
}
.form-group {
width: 50%;
}
.teamDrops, #rosterDrag {
border: 1px solid #eee;
width: 75%;
min-height: 5rem;
list-style-type: none;
margin: 1rem;
padding: 1rem 0rem;
}
.teamDrops h4, #rosterDrag h4 {
margin-bottom: 1.5rem;
padding-left: 1rem;
}
.draggable {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2rem;
width: 20rem;
display: inline-block;
}
#reminderTeams {
font-weight: bold;
}
#printbtn {
margin: 2rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>OnPoint Team Generator</title>
<meta name="description" content="OnPoint Team Generator">
<meta name="author" content="MeganRoberts">
<script src="scripts/jquery-3.2.1.min.js"></script>
<script src="scripts/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<link rel="stylesheet" href="styles/main.css" type="text/css">
</head>
<body>
<div class="card printMe" id="top">
<h3 id="title" class="card-header" style="text-align: center;"><img src="https://lh6.googleusercontent.com/N8Syzsw2aCV_qrh4pKOFgdamHSgD6gDQvGeKayDJBVfHBK2TMeQ3PnlpJ5BHD5ZVXk7YE4toSpav1co=w1920-h950-rw" alt="OnPoint Arrows" id="opArrows"> Team Generator</h3>
<div id="stepOne" class="card-block hideMe">
<h4 class="card-title"><span>Step 1:</span> Number of Teams</h4>
<p class="card-text lightText">How many students do you have in your class?</p>
<form id="teamForm">
<div class="form-group">
<input type="text" class="form-control" id="numberOfStudents" aria-describedby="numberStudents" placeholder="Enter Number of Students" data-toggle="tooltip" data-placement="top" title="Please enter a number larger than 7.">
</div>
<button type="submit" class="btn btn-primary opbtn" id="submitTeams" disabled>Submit</button>
</form>
</div>
</div>
<div class="card hideMe">
<div class="card-block" id="studentNumberResponse">
</div>
</div>
<div id="secondsStep" class="card hideMe">
</div>
<div id="listResponse" class="card hideMe listResponse">
<div class="card-block" id="studentListResponse">
</div>
</div>
<footer>
<div>
<button type="submit" id="printbtn" class="btn btn-primary btn-lg clearfix opbtn" onclick="pdfPrint()">Print</button>
</div>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>

How to create pair game using node values and set a setTimeout() method

I want to create a pair game that if the same textnode is matched it will set the background in white to reveal the matched textnode if not it will set a timeout and get back in original state.
The Problem of this is if I use the childNodes.nodeValue in match it saids that ChildNodes.nodeValue is not a function. And I try another code. I declare a variable that calls the element tag name of div which is I append a textNode in div. I want to compare two consecutive childNodes of div and if it is the same node, I change the color of the background to white. and I use the setTimout method, if not the color of background will go back again in original state which is black, I am pretty confused about this.
can you scan my code and help me to figure out what is the problem of this code?
here is the code.
<html>
<head>
<style>
div.row {
clear : left;
margin: auto;
width: 520px;
}
div.col {width:100px;
height:100px;
border: 3px solid black;
float : left;
margin: 10px;
font-size: 75px;
text-align: center;
background-color: black;
}
</style>
</head>
<body>
<div class="row">
<div id="00" class="col"></div>
<div id="01"class="col"></div>
<div id="02"class="col"></div>
<div id="03"class="col"></div>
</div>
<div class="row">
<div id="10" class="col"></div>
<div id="11"class="col"></div>
<div id="12"class="col"></div>
<div id="13"class="col"></div>
</div>
<div class="row">
<div id="20" class="col"></div>
<div id="21"class="col"></div>
<div id="22"class="col"></div>
<div id="23"class="col"></div>
</div>
<div class="row">
<div id="30" class="col"></div>
<div id="31"class="col"></div>
<div id="32"class="col"></div>
<div id="33"class="col"></div>
</div>
<script>
var size = 4;
var player = 0;
var board = new Array(size);
for (var i = 0; i < size; i++) {
board[i] = new Array(size);
for (var j = 0; j < size; j++) {
board[i][j] = 0;
}
}
var div_elements = document.getElementsByClassName("col");
for (var i = 0; i < div_elements.length;i++) {
div_elements[i].addEventListener("click", function() {mclick(this);});
}
var count=0;
function mclick(obj) {
if(match(div_elements.childNodes[0].nodeValue) == match(div_elements.childNodes[1].nodeValue)
{
obj.style.backgroundColor="white";
}
else{
setTimeout(function(){ obj.style.backgroundColor="white" }, 1000);
}
}
function shuffle() {
var value;
var text;
var text_node;
for (var i = 0; i < (size * size) ; i++) {
value = Math.ceil(Math.random() * 8);
board[Math.floor(i/4)][i %4] = value;
}
for (var i = 0; i < div_elements.length; i++)
{
text = board[Math.floor(i/4)][i%4];
text_node = document.createTextNode( text);
div_elements[i].appendChild(text_node);
}
}
shuffle();
</script>
</body>
</html>
You must be more specific. What kind of problem are you having? What are the error messages? What do you do that triggers the problem?
At least, put the code in a pastebin.com or something similar so that others don't need to setup a project for testing your whole stuff.

How can I add up numbers that appear in class names?

Take the following code:
<div id="work">
<div class="large-{{columns}} large-offset-{{columns}} columns projects">
</div>
</div>
The idea is that <div class="large-{{columns}} large-offset-{{columns}} columns projects"> can be generated an indefinite amount of times inside #work, and {{columns}} generates a number between 0 and 12.
What I want to do is run some JavaScript that goes through the numbers generated by {{columns}} and every time the sum is about to surpass 12, the associated divs get wrapped inside a new div with class "row".
The resulting HTML might look like this:
<div id="work">
<div class="row">
<div class="large-8 large-offset-4 columns projects"></div>
</div>
<div class="row">
<div class="large-6 large-offset-0 columns projects></div>
<div class="large-6 large-offset-0 columns projects"></div>
</div>
<div class="row">
<div class="large-4 large-offset-0 columns projects"></div>
<div class="large-8 large-offset-0 columns projects"></div>
</div>
<div class="row">
<div class="large-12 large-offset-0 columns projects"></div>
</div>
</div>
How can I accomplish this?
You can extract the {{columns}} values from each div's class name with the following regular expression:
/large-(\d+)\s* large-offset-(\d+)/
This computes the delta that should be added to the running sum:
var matches = /large-(\d+)\s* large-offset-(\d+)/.exec(item.className),
delta = parseInt(matches[1], 10) + parseInt(matches[2], 10);
You can make new row divs with document.createElement and fill them with clones of the original divs.
Demonstration:
function makeRowDiv(buildRow) {
var row = document.createElement('div');
row.className = 'row';
for (var i = 0; i < buildRow.length; ++i) {
row.appendChild(buildRow[i]);
}
return row;
}
window.onload = function () {
var work = document.getElementById('work'),
items = work.getElementsByTagName('div'),
newWork = document.createElement('div');
var buildRow = [],
count = 0;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if (item.className.indexOf('columns') == -1) {
continue;
}
// Extract the desired value.
var matches = /large-(\d+)\s* large-offset-(\d+)/.exec(item.className),
delta = parseInt(matches[1], 10) + parseInt(matches[2], 10);
if (count + delta > 12 && buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
count = 0;
buildRow = [];
}
buildRow.push(item.cloneNode(true));
count += delta;
}
if (buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
}
// Replace work with newWork.
work.parentNode.insertBefore(newWork, work);
work.parentNode.removeChild(work);
newWork.id = 'work';
};
body {
font-family: sans-serif;
font-size: 14px;
color: #444;
}
#work .row {
padding: 1px;
margin: 8px;
background: #deedff;
border: 1px solid #c4d1e1;
}
#work .row div {
/* display: inline; */
padding: 1px 4px 2px 4px;
margin: 4px;
background: #fff3fc;
border: 1px solid #ded3dc;
}
#work .row div div {
/* display: inline; */
padding: 1px 4px 2px 4px;
margin: 4px;
background: #eee;
border: 1px solid #ddd;
}
p {
padding: 0;
margin: 0;
}
<div id="work">
<div class="large-8 large-offset-4 columns projects">
<div class="child-div"><p>8</p></div>
<div class="child-div"><p>4</p></div>
</div>
<div class="large-6 large-offset-0 columns projects">
<div class="child-div"><p>6</p></div>
</div>
<div class="large-3 large-offset-3 columns projects">
<div class="child-div"><p>3</p></div>
<div class="child-div"><p>3</p></div>
</div>
<div class="large-4 large-offset-0 columns projects">
<div class="child-div"><p>4</p></div>
</div>
<div class="large-8 large-offset-0 columns projects">
<div class="child-div"><p>8</p></div>
</div>
<div class="large-6 large-offset-6 columns projects">
<div class="child-div"><p>6</p></div>
<div class="child-div"><p>6</p></div>
</div>
</div>
If you have enough horizontal space, you can uncomment the CSS line /* display: inline; */ to see the children of each row div arranged side by side.
I would use split or replace to get your integers and sum them up as suggested here.
Example:
var str = 'large-8 large-offset-6';
var large = str.replace(/.*large-(\d+)/, '$1');
var offset = str.replace(/.*large-offset-(\d+)/, '$1');
Then use a solution such as this to get your wrappers.
Example:
var divs = $("#work > .columns");
var count = <count how many cols are need to reach sum>
for(var i = 0; i < divs.length; i+=count) {
divs.slice(i, i+count).wrapAll("<div class='new'></div>");
}
I'm sure you can clean it up and finish it off but should give you the idea. I will complete when I get time tonight.

Categories