Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Charlie Huemmler School Explorer #30

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
8 changes: 4 additions & 4 deletions REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Requirements

## Core
- [ ] An text box on the page that can be used to filter based on the name of a school. When the value of this text box changes, only schools that have the value as a substring of their name should be shown on the map and in the list.
- [x] An text box on the page that can be used to filter based on the name of a school. When the value of this text box changes, only schools that have the value as a substring of their name should be shown on the map and in the list.

**The `input` element should be available on the global `window` object as a variable named `window.schoolNameFilter`.**

- [ ] A set of checkboxes that can be used to filter based on the grades (K-12) served at a school. When a box is checked, only schools that serve the corresponding grade should be shown on the map. (_You can alternatively choose to include filters for grade levels. If you do, only include options for Elementary, Middle, High, and Transition/Overage -- not, for example, `Elementary-Middle`_).
- [x] A set of checkboxes that can be used to filter based on the grades (K-12) served at a school. When a box is checked, only schools that serve the corresponding grade should be shown on the map. (_You can alternatively choose to include filters for grade levels. If you do, only include options for Elementary, Middle, High, and Transition/Overage -- not, for example, `Elementary-Middle`_).

**An array of `input` elements should be available on the global `window` object as a variable named `window.schoolGradeFilters` (or `window.schoolLevelFilters` if using school levels instead of grades).**

- [ ] A marker should be present on the map for each school that meets the current filter criteria, and no markers should be present for schools that _do not_ meet the filter criteria.
- [x] A marker should be present on the map for each school that meets the current filter criteria, and no markers should be present for schools that _do not_ meet the filter criteria.

**The Leaflet Map object that represents the map on the page should be available on the global `window` objects as a variable named `window.schoolMap`.**

- [ ] A list item should be present in the schools list for each school that meets the current filter criteria, and no list items should be present for schools that _do not_ meet the filter criteria. List items should contain at least:
- [x] A list item should be present in the schools list for each school that meets the current filter criteria, and no list items should be present for schools that _do not_ meet the filter criteria. List items should contain at least:
- School name
- Grades served

Expand Down
2 changes: 1 addition & 1 deletion TASKS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
- [ ] Create an _index.html_ with a basic HTML page structure
- [ x] Create an _index.html_ with a basic HTML page structure
- [ ] Create an empty CSS file for the project
- [ ] Create an empty JavaScrip file for the project
- [ ] Link to the empty CSS file from the bottom of the `head` of your HTML file
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"devDependencies": {
"eslint": "^8.22.0",
"http-server": "^14.1.1",
"jest": "^29.0.1",
"jest": "^29.1.2",
"jest-puppeteer": "^6.1.1",
"stylelint": "^14.11.0",
"stylelint-config-standard": "^28.0.0"
Expand Down
54 changes: 54 additions & 0 deletions site/css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
html {
font-family: "Comic Sans MS", sans-serif;
overflow: hidden;
}

#school-map {
height: 100%;
}

.mapcontainer {
height: 80vh;
width: 50%;
}

.filtercontainer {
width: 50%;
height: 80vh;
}

#school-list {
overflow-y: scroll;
height: 54vh;
}

.textinput {
display: flex;
justify-content: center;
width: 50%;
}

.content {
display: flex;
flex-direction: row;
justify-content: center;
font-size: 10px;
}

.checkboxes {
display: flex;
direction: row;
height: 20vh;
}

.checkbox-grid {
marker: none;
}

.title {
display: flex;
justify-content: center;
border: 3px;
border-style: solid;
border-color: coral;
}
63 changes: 63 additions & 0 deletions site/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>

<html>
<head>
<title>Charlie's School Explorer</title>

<!-- Leaflet's default styles-->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin=""/>

<!-- My CSS files-->
<link rel="stylesheet" href="css/styles.css">
</head>

<body>
<div class="title">
<h1 style="font-family: 'Comic Sans MS'">Charlie's School Explorer</h1>
</div>

<div class="content">
<div class='filtercontainer'>
<div class = 'textinput'>
<input type="text" id="school-name-filter" placeholder="Enter school name...">
</div>

<div class = checkboxes>
<div class = grade-cb>
<ul class="checkbox-grid">
Filter by School Level
<li><label><input type="checkbox" class="grade-checkbox" value="Elementary"> Elementary</label></li>
<li><label><input type="checkbox" class="grade-checkbox" value="Middle"> Middle</label></li>
<li><label><input type="checkbox" class="grade-checkbox" value="High"> High</label></li>
<li><label><input type="checkbox" class="grade-checkbox" value="Transition"> Transition</label></li>
</ul>
</div>
<div>
<ul class="checkbox-grid">
Filter by Admission Type
<li><label><input type="checkbox" id="1" class="admit-type-cb" value="Neighborhood" onclick="selectOnlyThis(this.id)"> Neighborhood</label></li>
<li><label><input type="checkbox" id="2" class="admit-type-cb" value="Citywide" onclick="selectOnlyThis(this.id)"> Citywide</label></li>
<li><label><input type="checkbox" id="3" class="admit-type-cb" value="Citywide With Criteria" onclick="selectOnlyThis(this.id)"> Citywide With Criteria</label></li>
<li><label><input type="checkbox" id="4" class="admit-type-cb" value="Special Admit" onclick="selectOnlyThis(this.id)"> Special Admit</label></li>
<li><label><input type="checkbox" id="5" class="admit-type-cb" value="Alternative" onclick="selectOnlyThis(this.id)"> Alternative</label></li>
</ul>
</div>
</div>
<div>
School List:
<ul id="school-list"></ul>
</div>
</div>
<div class="mapcontainer">
<div id="school-map"></div>
</div>
</div>


<!-- Leaflet JavaScript-->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>

<!-- My project JS modules-->
<script type="module" src="jsscript/main.js"></script>
</body>
</html>
119 changes: 119 additions & 0 deletions site/jsscript/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import schools from '../data/schools.js';

import { initSchoolMap, showSchoolsOnMap } from './mapfunctions.js';
import { showSchoolsInList } from './schoolList.js';

import { gradefun } from './schoollevels.js';

let schoolMap = initSchoolMap();
showSchoolsOnMap(schools, schoolMap);

schools.map(gradefun);

let schoolList = document.querySelector('#school-list');
showSchoolsInList(schools, schoolList);




// Expose variable to the global scope

//grab selectors
let schoolLevelFilters = document.querySelectorAll('.grade-checkbox');
let schoolNameFilter = document.querySelector('#school-name-filter');
let admitCheckboxes = document.querySelectorAll('.admit-type-cb');

function selectOnlyThis(id) {
if (document.getElementById(id).checked == true){
for (let i = 1; i <= 5; i++)
{
document.getElementById(i).checked = false;
}
document.getElementById(id).checked = true;
}

if (document.getElementById(id).checked == false) {
for (let i = 1; i <= 5; i++)
{
document.getElementById(i).checked = false;
}
}
}


function shouldShowSchool() {
let filteredSchools = schools;

// Filter based on school name
const text = schoolNameFilter.value;
filteredSchools = filteredSchools.filter(function (school) {
const name = school['name'].toLowerCase();
const hasText = name.includes(text);
return hasText;
});

// Filter based on grade checkboxes
for (const checkbox of schoolLevelFilters) {
if (checkbox.checked) {
filteredSchools = filteredSchools.filter(function (school) {
const schoollevel = checkbox.value;
const hasGrade = school[`School Level`].includes(schoollevel);
return hasGrade;
});
}
}

// Filter based on admission type checkboxes
for (const checkbox of admitCheckboxes) {
if (checkbox.checked) {
filteredSchools = filteredSchools.filter(function (school) {
const admitType = checkbox.value;
const isAdmitType = school[`Admission Type`] === admitType;
return isAdmitType;
});
}
}

return filteredSchools;
}



for (const cb of schoolLevelFilters) {
cb.addEventListener('change', () => {
const filteredSchools = shouldShowSchool();
showSchoolsOnMap(filteredSchools, schoolMap);
schoolList.innerHTML = '';
showSchoolsInList(filteredSchools, schoolList);
});
}



for (const cb of admitCheckboxes) {
cb.addEventListener('change', () => {
const filteredSchools = shouldShowSchool();
showSchoolsOnMap(filteredSchools, schoolMap);
schoolList.innerHTML = '';
showSchoolsInList(filteredSchools, schoolList);
});
}


schoolNameFilter.addEventListener('input', () => {
const filteredSchools = shouldShowSchool();
showSchoolsOnMap(filteredSchools, schoolMap);
schoolList.innerHTML = '';
showSchoolsInList(filteredSchools, schoolList);
});





window.schoolMap = schoolMap;
window.schools = schools;
window.schoolLevelFilters = schoolLevelFilters;
window.schoolNameFilter = schoolNameFilter;
window.schoolList = schoolList;
window.selectOnlyThis = selectOnlyThis;
64 changes: 64 additions & 0 deletions site/jsscript/mapfunctions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@


function initSchoolMap(){
const southWest = L.latLng(39.88, -75.27),
northEast = L.latLng(40.195, -74.98),
bounds = L.latLngBounds(southWest, northEast);

let schoolMap = L.map('school-map', { maxBounds: bounds, maxZoom: 19, minZoom: 10.5 }).setView([39.95, -75.16], 11);

const mapboxAccount = 'mapbox';
const mapboxStyle = 'satellite-v9';
const mapboxToken = 'pk.eyJ1IjoiY2h1ZW1idWNrZXQiLCJhIjoiY2w5dTl6M3V1MG0xejN1bGVqbzQyZTZjbiJ9.VfiDkqAOIvCv1KdQdrgnSQ';
L.tileLayer(`https://api.mapbox.com/styles/v1/${mapboxAccount}/${mapboxStyle}/tiles/256/{z}/{x}/{y}@2x?access_token=${mapboxToken}`, {
maxZoom: 19,
attribution: '© <a href="https://www.mapbox.com/about/maps/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> <strong><a href="https://www.mapbox.com/map-feedback/" target="_blank">Improve this map</a></strong>',
}).addTo(schoolMap);
return schoolMap;
}

function makeSchoolFeature(school){
return {
"type": "Feature",
"id": school['sdp_id'],
"properties": {
"school_name": school['name'],
"admission_type": school['Admission Type'],
"year_open": school['Year Opened'],
},
"geometry": school['geom'],
};
}

function showSchoolsOnMap(SchoolsToShow, schoolMap) {
if (schoolMap.schoolLayers !== undefined) {
schoolMap.removeLayer(schoolMap.schoolLayers);
}
const schoolFeatureCollection = {
"type": "FeatureCollection",
"features": SchoolsToShow.map(makeSchoolFeature),
};
schoolMap.schoolLayers = L.geoJSON(schoolFeatureCollection, {
pointToLayer: (geoJsonPoint, latlng) => L.circleMarker(latlng),
style: function(Feature) {
switch (Feature.properties['admission_type']) {
case "Neighborhood": return { color: "orange" };
case "Citywide": return { color: "blue" };
case "Citywide With Criteria": return { color: "#1ca0d9" };
case "Special Admit": return { color: "green" };
case "Alternative": return { color: "yellow" };
}

},
},
)
.bindTooltip(layer => layer.feature.properties['school_name'])
.addTo(schoolMap);
}



export {
initSchoolMap,
showSchoolsOnMap,
};
15 changes: 15 additions & 0 deletions site/jsscript/schoolList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { htmlToElement } from './template-tools.js';

function showSchoolsInList(schoolstoShow, schoolList) {
for(const school of schoolstoShow){
const html = `
<li class ="school-list-item">${school['name']} ${school['gradelevel']} </li>
`;
const li = htmlToElement(html);
schoolList.append(li);
}
}

export{
showSchoolsInList,
};
20 changes: 20 additions & 0 deletions site/jsscript/schoollevels.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function gradefun(school) {
const gradearray = ['K', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', "12"];
let minfound = false;
let mingrade = null;
let maxgrade = null;
for(const grade of gradearray) {
if(school[`Grade ${grade}`] === "1" && minfound === false){
mingrade = grade;
minfound = true;
}
if(school[`Grade ${grade}`] === "1"){
maxgrade = grade;
}
}
return school.gradelevel = `(${mingrade}-${maxgrade})`;
}



export{ gradefun };
File renamed without changes.