gloopit gloopit - 3 months ago 11
Javascript Question

Why can't '.appendChild' be read? How can page be undefined?

I have creating a program that is supposed to paginate 10 students per page. There are 54 total students.

I have added all of the student listitems into an array of objects.

I then hide all the original html of the students, and based on the pagination link clicked, it will then display the right amount students, taken from the array of objects.

For some reason in my

displayPagination()
function, an error being shown that my wrapper is not being added to the page, and thus none of the program will work. It says "app.js:167 Uncaught TypeError: Cannot read property 'appendChild' of undefined".

Any idea what's happening here?

Please ignore my comments for the search function at the bottom. I have not implemented that just yet.

//Problem: Shows too many people per page
//Solution: Incorporate pagination and add search functionality

'useStrict';


//Find total number of students
var studentTotal = document.getElementsByClassName("student-item").length;
var itemsToShowPerPage = 10;

//empty array of objects for students
var studentArray = [];


//Call buildSearch()
buildSearch();
//display initial page
initialDisplay();


//Cach DOM elements for easy access
var page = document.querySelector(".page");
var paginationLink = document.getElementsByClassName("pagination-link");
var studentList = document.querySelector(".student-list");

function studentShow(start, end) {
studentList.innerHTML = '';

for(var i = start; i <= end; i++){
var newStudent = displayStudents(studentArray[i]);
studentList.appendChild(newStudent);
}
}

//Calculate the number of pages needed
function calculatePageCount() {
var pagesNeeded = Math.ceil(studentTotal/itemsToShowPerPage);
console.log("Amount of pages needed :" + pagesNeeded);
return pagesNeeded;
}

//builds search
function buildSearch () {
var pageHeader = document.querySelector('.page-header');
var searchWrap = document.createElement('div');
var searchInput = document.createElement('input');
var searchButton = document.createElement('button');

searchWrap.classList.add('student-search');
searchButton.classList.add('search-button');
searchInput.setAttribute('placeholder', 'Search for students...');
searchInput.classList.add('student-search-input');
searchButton.textContent = ('Search');
searchWrap.appendChild(searchInput);
searchWrap.appendChild(searchButton);
pageHeader.appendChild(searchWrap);
}

//create student object
function studentObject(name, avatar, email, dateJoined) {
this.name = name;
this.avatar = avatar;
this.email = email;
this.dateJoined = dateJoined;
}

//filter students and create an array of objects
function studentFilter() {
var student, name, avatar, email, dateJoined;

var studentList = document.querySelectorAll('.student-list')[0].children;
for(var i = 0; i < studentList.length; i++) {
avatar = studentList[i].children[0].children[0].src;
name = studentList[i].children[0].children[1].innerHTML;
email = studentList[i].children[0].children[2].innerHTML;
dateJoined = studentList[i].children[1].children[0].innerHTML;

//create new object
student = new studentObject(name,avatar, email, dateJoined);

//add each student into the array for later use
studentArray.push(student);
}
}

//construct html for student
function displayStudents(student) {
var listItem, detailsDiv, joinedDetails, avatarImg, nameH, emailSpan, date;

//Create student list item
listItem = document.createElement('li');
//add it's classes
listItem.classList.add('student-item');
listItem.classList.add('cf');

//create first div for student details
detailsDiv = document.createElement('div');
//add it's class
detailsDiv.classList.add('student-details');

//create the details to go into detailsDiv
avatarImg = document.createElement('img');
avatarImg.src = student.avatar;
nameH = document.createElement('h3');
nameH.innerHTML = student.name;
emailSpan = document.createElement('span');
email.innerHTML = student.email;
//add their classes
avatarImg.classList.add('avatar');
emailSpan.classList.add('email');

//add details to detailsDiv
detailsDiv.appendChild(avatarImg);
detailsDiv.appendChild(emailSpan);
detailsDiv.appendChild(nameH);

//create second div for joinedDetails
joinedDetails = document.createElement('div');
//add it's class
joinedDetails.classList.add('joined-details');

//create date to put into joinedDetails
date = document.createElement('span');
date.innerHTML = student.dateJoined;
//add it's class
date.classList.add('date');

//add date to joinDetails
joinedDetails.appendChild(date);

//add divs to listItem
listItem.appendChild(detailsDiv);
listItem.appendChild(joinedDetails);

return listItem;
}


function displayPaginationLinks() {
var link, pagLink;

//create template
var wrapper = document.createElement('div');
wrapper.classList.add('pagination');
var pagList = document.createElement('ul');
pagList.classList.add("pagination-links");
wrapper.appendChild(pagList);


var pageCount = calculatePageCount();

//add individual elements
for(var i = 1; i <= pageCount; i++) {
pagLink = document.createElement('li');
link = document.createElement('a');
link.innerHTML = i;
link.href = "#";
pagLink.appendChild(link);
pagList.appendChild(pagLink);
}

//make first link 'active'
pagList.children[0].children[0].classList.add("active");
//add to wrapper
wrapper.appendChild(pagList);
//add wrapper to page
page.appendChild(wrapper);
}

function paginate(event) {
event.preventDefault();

//variables for
var start, end;

//reset link class
for(var i = 0; i < paginationLink.length; i++) {
paginationLink[i].className = "pagination-link";
}

//THIS link's class will be active
this.classList.add('active');

//show the right section of item lists
start = (this.innerHTML * 10) - 10;
end = (this.innerHTML * 10) - 1;

//make sure if end of list, only show the remaining few
if(end < studentArray.length){
end = studentArray.length -1;
}

studentShow(start, end);
}



function initialDisplay() {
studentFilter();
//displayStudents(studentArray);
if (calculatePageCount() > 1) {
displayPaginationLinks();
}
//show first 10 students
studentShow(0, 9);
}


//Add search function
//Using progressive enhancement, add the student search markup as presented in the filters-example.html file to the index.html file.
//Make sure it's case insensitive
//User can search by name or e-mail address. Also partial matches
//Dynamically filter the student listings.
//Results should also be paginated. Don't use jQuery
//If no matches are found, add HTML message to say so


//Event Listeners
//Search button

//Pagination
for(var i = 0; i < paginationLink.length; i++) {
paginationLink[i].addEventListener("click", paginate);
}


Here is the html:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Students</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/design.css">
</head>
<body>
<div class="page">
<div class="page-header cf">
<h2>Students</h2>
</div>
<ul class="student-list">
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/67.jpg">
<h3>iboya vat</h3>
<span class="email">iboya.vat@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/15/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/75.jpg">
<h3>aapo niskanen</h3>
<span class="email">aapo.niskanen@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/15/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/34.jpg">
<h3>phillip cox</h3>
<span class="email">phillip.cox@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 09/11/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/38.jpg">
<h3>zilda moreira</h3>
<span class="email">zilda.moreira@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/15/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/23.jpg">
<h3>lilou le gall</h3>
<span class="email">lilou.le gall@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/16/13</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/94.jpg">
<h3>lucy hall</h3>
<span class="email">lucy.hall@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 09/11/16</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/24.jpg">
<h3>mark colin</h3>
<span class="email">mark.colin@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 01/14/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/14.jpg">
<h3>sara alves</h3>
<span class="email">sara.alves@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/19/16</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/49.jpg">
<h3>ramon macrae</h3>
<span class="email">ramon.macrae@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 05/13/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/15.jpg">
<h3>connor taylor</h3>
<span class="email">connor.taylor@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 05/18/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/11.jpg">
<h3>aymeric morel</h3>
<span class="email">aymeric.morel@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/13/13</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/49.jpg">
<h3>lorenz otto</h3>
<span class="email">lorenz.otto@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 05/11/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/29.jpg">
<h3>karl williamson</h3>
<span class="email">karl.williamson@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 01/12/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/34.jpg">
<h3>ouassim heering</h3>
<span class="email">ouassim.heering@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 01/18/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/91.jpg">
<h3>roberto molina</h3>
<span class="email">roberto.molina@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/13/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/28.jpg">
<h3>jordan hubert</h3>
<span class="email">jordan.hubert@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/13/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/29.jpg">
<h3>melvin baker</h3>
<span class="email">melvin.baker@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 09/18/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/26.jpg">
<h3>everett gordon</h3>
<span class="email">everett.gordon@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/17/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/82.jpg">
<h3>aiden ma</h3>
<span class="email">aiden.ma@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/18/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/62.jpg">
<h3>florent gerard</h3>
<span class="email">florent.gerard@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 02/12/13</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/96.jpg">
<h3>amber chen</h3>
<span class="email">amber.chen@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/12/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/9.jpg">
<h3>alexandra davies</h3>
<span class="email">alexandra.davies@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 05/11/13</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/57.jpg">
<h3>sergio cole</h3>
<span class="email">sergio.cole@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 02/17/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/98.jpg">
<h3>edgar dixon</h3>
<span class="email">edgar.dixon@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/17/11</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/94.jpg">
<h3>kirk myers</h3>
<span class="email">kirk.myers@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 09/17/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/28.jpg">
<h3>ani hesseling</h3>
<span class="email">ani.hesseling@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 08/14/16</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/24.jpg">
<h3>victoire bonnet</h3>
<span class="email">victoire.bonnet@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 05/13/16</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/44.jpg">
<h3>marcos morales</h3>
<span class="email">marcos.morales@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 01/12/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/75.jpg">
<h3>nils neumann</h3>
<span class="email">nils.neumann@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 03/11/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/86.jpg">
<h3>emily harrison</h3>
<span class="email">emily.harrison@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/18/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/41.jpg">
<h3>matthew fortin</h3>
<span class="email">matthew.fortin@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 03/18/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/32.jpg">
<h3>charlotte steward</h3>
<span class="email">charlotte.steward@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 02/18/11</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/3.jpg">
<h3>marceau rodriguez</h3>
<span class="email">marceau.rodriguez@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/13/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/91.jpg">
<h3>hudson anderson</h3>
<span class="email">hudson.anderson@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 09/12/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/33.jpg">
<h3>warren phillips</h3>
<span class="email">warren.phillips@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 01/11/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/41.jpg">
<h3>leo niva</h3>
<span class="email">leo.niva@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 09/14/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/3.jpg">
<h3>hani prevoo</h3>
<span class="email">hani.prevoo@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 01/11/15</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/79.jpg">
<h3>veronica rodriguez</h3>
<span class="email">veronica.rodriguez@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 07/17/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/41.jpg">
<h3>ginestal das neves</h3>
<span class="email">ginestal.das neves@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 06/19/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/63.jpg">
<h3>devon barnes</h3>
<span class="email">devon.barnes@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 09/19/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/10.jpg">
<h3>elsa lahti</h3>
<span class="email">elsa.lahti@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 04/15/12</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/12.jpg">
<h3>soline leclercq</h3>
<span class="email">soline.leclercq@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 05/12/14</span>
</div>
</li>
<li class="student-item cf">
<div class="student-details">
<img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/89.jpg">
<h3>henri kruse</h3>
<span class="email">henri.kruse@example.com</span>
</div>
<div class="joined-details">
<span class="date">Joined 05/14/13</span>
</div>
</li>
</ul>
</div>
</body>
<script type="text/javascript" src="js/app.js"></script>
</html>

Answer

The issue seems to be calling initialDisplay before assigning anything to the page variable - thus, page is undefined when displayPaginationLinks calls page.appendChild.

Comments