Skip to content
Closed

lab4 #20

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
8 changes: 8 additions & 0 deletions .idea/.gitignore

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

9 changes: 9 additions & 0 deletions .idea/JS_Template.iml

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

6 changes: 6 additions & 0 deletions .idea/misc.xml

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

8 changes: 8 additions & 0 deletions .idea/modules.xml

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

6 changes: 6 additions & 0 deletions .idea/vcs.xml

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

59 changes: 55 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,63 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple HTML Page</title>
<title>Polls</title>
<link rel="stylesheet" href="./style/style.css">
<script src="./src/main.js" defer></script>
</head>
<body>
<div class="upper-panel">
<div class="search-bar">
<input type="text" placeholder="Search polls...">
<select>
<option value="">Category</option>
<option value="tech">Tech</option>
<option value="social">Social</option>
<option value="food">Food</option>
<option value="media">Media</option>
<option value="custom">Custom</option>

</select>
</div>

<button class="create-btn">Create Poll</button>
</div>

<div id="modal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h2>Poll Question</h2>
<p id="poll-question-text"></p>
<form id="vote-form"></form>
</div>
</div>
<div id="create-modal" class="modal">
<div class="modal-content">
<span class="close-create">&times;</span>
<h2>Create Poll</h2>
<label>Question</label>
<input type="text" id="poll-question" placeholder="Enter your question">
<label>Category</label>
<select id="poll-category">
<option value="">Category</option>
<option value="tech">Tech</option>
<option value="social">Social</option>
<option value="food">Food</option>
<option value="media">Media</option>
<option value="custom">Custom</option>
</select>
<label>Options</label>
<div id="options-container">
<input type="text" placeholder="Option 1">
<input type="text" placeholder="Option 2">
<input type="text" placeholder="Option 3">
<input type="text" placeholder="Option 4">
</div>
<a href="#" id="add-option" style="color:#2563eb; display:block; margin-top:10px;">Add option</a>
<button id="create-poll-btn">Create</button>
</div>

</div>
<a href="report.html" class="report-btn">Summary(WebDataRocks)</a>
<script src="./src/main.js"></script>
</body>
</html>
</html>
210 changes: 210 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
let polls = [];

fetch("./src/polls.json")
.then(response => response.json())
.then(data => {
polls = data;
renderPolls();
})
.catch(error => console.error("Error loading JSON:", error));

function totalVotes(poll) {
return poll.options.reduce((acc, option) => acc + option.votes, 0);
}


function renderPolls(filterText = "", filterCategory = "") {
const container = document.querySelector("body");
document.querySelectorAll(".poll-card").forEach(el => el.remove());

let filtered = polls.filter(poll => {
const matchText = poll.question.toLowerCase().includes(filterText.toLowerCase());
const matchCategory = filterCategory === "" || poll.category === filterCategory;
return matchText && matchCategory;
});

filtered.forEach(poll => {
const pollDiv = document.createElement("div");
pollDiv.className = "poll-card";
pollDiv.style.cursor = "pointer";
pollDiv.dataset.pollId = poll.id;

const questionDiv = document.createElement("div");
questionDiv.className = "poll-question";
questionDiv.textContent = poll.question;
pollDiv.appendChild(questionDiv);

const total = totalVotes(poll);
poll.options.forEach(option => {
const optionDiv = document.createElement("div");
optionDiv.className = "poll-option";

const spanText = document.createElement("span");
spanText.textContent = option.text;
optionDiv.appendChild(spanText);

const barContainer = document.createElement("div");
barContainer.className = "poll-bar-container";

const bar = document.createElement("div");
bar.className = "poll-bar";
const widthPercent = total > 0 ? (option.votes / total) * 100 : 0;
bar.style.width = widthPercent + "%";

barContainer.appendChild(bar);
optionDiv.appendChild(barContainer);

const spanPercent = document.createElement("span");
spanPercent.className = "percentage";
spanPercent.textContent = Math.round(widthPercent) + "%";
optionDiv.appendChild(spanPercent);

pollDiv.appendChild(optionDiv);
});

const votesDiv = document.createElement("div");
votesDiv.className = "poll-votes";
votesDiv.textContent = `${total} votes`;
pollDiv.appendChild(votesDiv);
container.appendChild(pollDiv);
pollDiv.addEventListener("click", () => openVoteModal(poll.id));
});
}

const voteModal = document.getElementById("modal");
const voteModalContent = voteModal.querySelector(".modal-content");

voteModal.addEventListener("click", (e) => {
if (!voteModalContent.contains(e.target)) {
voteModal.style.display = "none";
}
});

function openVoteModal(pollId) {
voteModal.style.display = "flex";

voteModal.addEventListener("click", (e) => {
if (!voteModalContent.contains(e.target)) {
voteModal.style.display = "none";
}
});

const poll = polls.find(p => p.id === pollId);

document.getElementById("poll-question-text").textContent = poll.question;


const form = voteModal.querySelector("form");
form.innerHTML = "";

poll.options.forEach((option, idx) => {
const label = document.createElement("label");

const input = document.createElement("input");
input.type = "radio";
input.name = "voteOption";
input.value = idx;

label.appendChild(input);
label.appendChild(document.createTextNode(" " + option.text));
form.appendChild(label);
});

const submitBtn = document.createElement("button");
submitBtn.type = "submit";
submitBtn.textContent = "Submit Vote";
form.appendChild(submitBtn);

form.onsubmit = function (e) {
e.preventDefault();
const selected = form.querySelector('input[name="voteOption"]:checked');
if (!selected) return alert("Choose option");
const idx = Number(selected.value);
poll.options[idx].votes++;
voteModal.style.display = "none";
renderPolls();
};
}

document.querySelector(".close").addEventListener("click", () => {
document.getElementById("modal").style.display = "none";
});

document.querySelector(".search-bar input").addEventListener("input", function () {
renderPolls(this.value, document.querySelector(".search-bar select").value);
});

document.querySelector(".search-bar select").addEventListener("change", function () {
renderPolls(document.querySelector(".search-bar input").value, this.value);
});
document.querySelector(".create-btn").addEventListener("click", () => {
document.getElementById("create-modal").style.display = "flex";
});

document.querySelector(".close-create").addEventListener("click", () => {
document.getElementById("create-modal").style.display = "none";
});

document.getElementById("add-option").addEventListener("click", (e) => {
e.preventDefault();
const container = document.getElementById("options-container");
const input = document.createElement("input");
input.type = "text";
input.placeholder = "Option " + (container.children.length + 1);
container.appendChild(input);
});

document.getElementById("create-poll-btn").addEventListener("click", () => {
const category = document.getElementById("poll-category").value;
const question = document.getElementById("poll-question").value.trim();
const inputs = document.querySelectorAll("#options-container input");
const options = Array.from(inputs)
.map(input => input.value.trim())
.filter(text => text !== "")
.map(text => ({ text, votes: 0 }));

if (!question || options.length < 2) {
alert("Enter a question and at least 2 options.");
return;
}
polls.push({
id: Date.now(),
question,
category,
options
});
document.getElementById("create-modal").style.display = "none";
renderPolls();
});
document.getElementById("create-poll-btn").addEventListener("click", () => {
const modal = document.getElementById("create-modal");

document.getElementById("poll-question").value = "";

document.getElementById("poll-category").selectedIndex = 0;

const optionsContainer = document.getElementById("options-container");
optionsContainer.innerHTML = "";

for (let i = 1; i <= 4; i++) {
const input = document.createElement("input");
input.type = "text";
input.placeholder = "Option " + i;
optionsContainer.appendChild(input);
}

modal.style.display = "flex";
});

window.addEventListener("DOMContentLoaded", () => {
renderPolls();
});
const createModal = document.getElementById("create-modal");
const createModalContent = createModal.querySelector(".modal-content");

createModal.addEventListener("click", (e) => {
if (!createModalContent.contains(e.target)) {
createModal.style.display = "none";
}
});

Loading