Add a working css demo

This commit is contained in:
illyum 2024-09-06 02:40:50 -06:00
parent 2964af1227
commit bafef90dc8
4 changed files with 5386 additions and 0 deletions

23
demo/main.go Normal file
View File

@ -0,0 +1,23 @@
package main
import (
"log"
"net/http"
)
func main() {
// Serve static files from the "static" directory
fs := http.FileServer(http.Dir("./static"))
// Serve static content at the root URL ("/")
http.Handle("/", http.StripPrefix("/", fs))
// Log the server status
log.Println("Serving at http://localhost:8080")
// Start the web server on port 8080
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}

5158
demo/static/course_list.json Normal file

File diff suppressed because it is too large Load Diff

77
demo/static/script.js Normal file
View File

@ -0,0 +1,77 @@
document.addEventListener('DOMContentLoaded', function () {
let courseList = {};
// Fetch the course_list.json file
fetch('course_list.json')
.then(response => response.json())
.then(data => {
courseList = data; // Load the data into courseList variable
})
.catch(error => {
console.error('Error loading course list:', error);
});
const courseInput = document.getElementById('course');
const autocompleteList = document.getElementById('autocomplete-list');
// Event listener for course input keyup (every time user types)
courseInput.addEventListener('input', function () {
const query = this.value.toUpperCase(); // Convert input to uppercase to match course ID and name
autocompleteList.innerHTML = ''; // Clear any previous suggestions
if (!query) {
return false; // If input is empty, stop here
}
let matchCount = 0; // Keep track of the number of matches
// Filter through the courseList object
for (const courseCode in courseList) {
const courseName = courseList[courseCode].toUpperCase();
// Match either the course ID or part of the course name
if (courseCode.startsWith(query) || courseName.includes(query)) {
const suggestionItem = document.createElement('div');
suggestionItem.innerHTML = `<strong>${courseCode}</strong> - ${courseList[courseCode]}`;
suggestionItem.addEventListener('click', function () {
// On click, set the input value and close the dropdown
courseInput.value = `${courseCode} - ${courseList[courseCode]}`;
autocompleteList.innerHTML = '';
});
autocompleteList.appendChild(suggestionItem);
matchCount++;
if (matchCount >= 10) break; // Limit suggestions to 10 for better performance
}
}
// If no matches, show a 'no results' message
if (matchCount === 0) {
const noResultsItem = document.createElement('div');
noResultsItem.innerHTML = `<em>No courses found</em>`;
autocompleteList.appendChild(noResultsItem);
}
});
// Close the autocomplete dropdown when clicking outside
document.addEventListener('click', function (e) {
if (e.target !== courseInput) {
autocompleteList.innerHTML = '';
}
});
// Handle form submission
document.getElementById('mainForm').addEventListener('submit', function(event) {
event.preventDefault(); // Prevent the default form submission
// Trigger the sliding animation
document.getElementById('formCard').classList.add('active');
document.getElementById('resultsCard').classList.add('active');
// Optional: Log form data to the console for testing
const formData = new FormData(this);
const name = formData.get('name');
const course = formData.get('course');
console.log(`Name: ${name}, Course: ${course}`);
});
});

128
demo/static/styles.css Normal file
View File

@ -0,0 +1,128 @@
/* Define CSS variable for transition speed at the root level */
:root {
--transition-speed: 0.5s; /* Define the transition speed variable */
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
}
.container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.form-card, .results-card {
position: absolute;
width: 300px;
padding: 20px;
background-color: white;
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.1);
border-radius: 10px;
/* Use the CSS variable for the transition speed */
transition: all var(--transition-speed) ease-in-out;
}
.form-card {
z-index: 2; /* Ensure form card is on top */
left: 50%;
transform: translateX(-50%);
width: 320px; /* Define a fixed width for the form */
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.1);
transition: all var(--transition-speed) ease-in-out;
}
.results-card {
z-index: 1; /* Ensure results card is behind the form card */
left: 50%;
transform: translateX(-50%);
opacity: 0; /* Initially invisible */
/* Apply the CSS variable for transition speed */
transition: all var(--transition-speed) ease-in-out, opacity var(--transition-speed) ease-in-out;
}
/* When active, form slides to the left and results slide to the right */
.form-card.active {
/* Move the form when the results card is shown */
left: 40%;
transform: translateX(-40%);
}
.results-card.active {
left: 60%;
transform: translateX(-60%);
opacity: 1; /* Gradually fade in */
}
form {
display: flex;
flex-direction: column;
}
input[type="text"], input[type="email"] {
padding: 10px; /* Padding inside text boxes */
margin-bottom: 15px; /* Space between form fields */
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
width: 100%; /* Make the input take the full width of the form */
box-sizing: border-box; /* Ensure padding doesn't affect width */
}
button {
padding: 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #0056b3;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
top: 100%;
left: 0;
right: 0;
max-height: 200px;
overflow-y: auto;
background-color: white;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
.autocomplete-items div:hover {
background-color: #e9e9e9;
}