मिनी प्रोजेक्ट — इंटरैक्टिव टू-डू
खुली पंक्ति पर buy tea दिखता है। बीच का निशान लगते ही वही पंक्ति done: buy tea बन जाती है। यह छोटी सूची आप खुद बनाते हैं: buy tea जोड़ते हैं, उसे पूरा चिह्नित करते हैं, फिर हटा देते हैं।
नाम वहीं रह गए थे
पिछला पेज हुनर के नाम गिनाकर रुक गया था और कोई सूची नहीं दिखाता था। यह पेज खुद सूची है। हाथ में सरणी, फ़ॉर्म, textContent और एक क्लिक हैं। जोड़ते समय पेज फिर से लोड नहीं होना चाहिए।
text और done एक जोड़ी हैं
tasks वस्तुओं की सरणी है। हर वस्तु में text और done होते हैं। नई वस्तु में done शुरू में false रहता है। addTask शब्दों पर trim चलाता है। कुछ शेष न बचे तो push नहीं होता और वस्तु सहेजी नहीं जाती।
const tasks = [];
function addTask(text) {
const clean = text.trim();
if (!clean) {
return;
}
tasks.push({ text: clean, done: false });
}
addTask("buy tea");
console.log(tasks[0].text);
console.log(tasks[0].done);
दो लॉग क्रम से buy tea और false हैं। addTask(" ") trim के बाद खाली रह जाता है, कुछ सहेजा नहीं जाता, और लंबाई 0 पर टिकी रहती है।
फ़ॉर्म भेजते ही दस्तावेज़ फिर से लोड होता है
सरणियाँ सिर्फ़ मेमोरी में रहती हैं, इसलिए फिर से लोड होते ही वे गिर जाती हैं और सूची खाली लगती है। event.preventDefault() वह फिर से लोड रोक देता है। उसके बाद शब्द जुड़ते हैं, इनपुट खाली होता है, और render फिर चलता है।
const form = document.querySelector("#add-form");
const input = document.querySelector("#task-text");
form.addEventListener("submit", (event) => {
event.preventDefault();
addTask(input.value);
input.value = "";
render();
});
दस्तावेज़ टिका रहता है। इनपुट खाली है। render चलता है। केवल रिक्त स्थान वाला इनपुट कोई पंक्ति नहीं जोड़ता।
हर पंक्ति पर दो बटन
render पहले #tasks खाली करता है, फिर हर वस्तु के लिए एक li बनाता है। खुली वस्तु text दिखाती है। पूरी हुई वस्तु done: और उसके बाद शब्द दिखाती है। हर पंक्ति पर दो बटन हैं, दोनों type="button", ताकि वे फ़ॉर्म न भेजें। Done बूलियन को पलटता है। हटाना splice से होता है। दोनों के बाद render फिर चलता है, क्योंकि पुराने इंडेक्स गलत वस्तु की ओर इशारा करते।
function toggleTask(index) {
tasks[index].done = !tasks[index].done;
}
function removeTask(index) {
tasks.splice(index, 1);
}
function render() {
const list = document.querySelector("#tasks");
list.textContent = "";
tasks.forEach((task, index) => {
const item = document.createElement("li");
item.textContent = task.done ? "done: " + task.text : task.text;
const doneButton = document.createElement("button");
doneButton.type = "button";
doneButton.textContent = "Done";
doneButton.addEventListener("click", () => {
toggleTask(index);
render();
});
const removeButton = document.createElement("button");
removeButton.type = "button";
removeButton.textContent = "Remove";
removeButton.addEventListener("click", () => {
removeTask(index);
render();
});
item.append(doneButton, removeButton);
list.append(item);
});
}
क्रम यह है: addTask("buy tea"), फिर toggleTask(0), फिर render। पंक्ति done: buy tea हो जाती है। एक बार और पलटें तो फिर buy tea। removeTask(0) लंबाई 0 कर देता है और अगली बार बनने पर कोई पंक्ति नहीं होती। इनपुट के शब्द textContent से रखें। उन्हें HTML की तरह पृष्ठ पर न चिपकाएँ।
अनुक्रम उसी चक्कर का है
forEach उस चक्कर का इंडेक्स पकड़ लेता है। splice के बाद पुराने इंडेक्स गलत काम की ओर देखते हैं। दोबारा बनाने से पुराने बटन फेंक दिए जाते हैं और नए बनते हैं। दोबारा न बनाया जाए तो Remove गलत पंक्ति हटा देता है।
तीन काम बँटे हुए हैं
फ़ॉर्म जोड़ता है। सूची चित्र बनाती है। Done और Remove केवल tasks बदलते हैं, फिर चित्र फिर से बनता है।
<!DOCTYPE html>
<html>
<body>
<form id="add-form">
<input id="task-text" type="text">
<button type="submit">Add</button>
</form>
<ul id="tasks"></ul>
<script>
const tasks = [];
function addTask(text) {
const clean = text.trim();
if (!clean) return;
tasks.push({ text: clean, done: false });
}
function toggleTask(index) {
tasks[index].done = !tasks[index].done;
}
function removeTask(index) {
tasks.splice(index, 1);
}
function render() {
const list = document.querySelector("#tasks");
list.textContent = "";
tasks.forEach((task, index) => {
const item = document.createElement("li");
item.textContent = task.done ? "done: " + task.text : task.text;
const doneButton = document.createElement("button");
doneButton.type = "button";
doneButton.textContent = "Done";
doneButton.addEventListener("click", () => {
toggleTask(index);
render();
});
const removeButton = document.createElement("button");
removeButton.type = "button";
removeButton.textContent = "Remove";
removeButton.addEventListener("click", () => {
removeTask(index);
render();
});
item.append(doneButton, removeButton);
list.append(item);
});
}
document.querySelector("#add-form").addEventListener("submit", (event) => {
event.preventDefault();
addTask(document.querySelector("#task-text").value);
document.querySelector("#task-text").value = "";
render();
});
</script>
</body>
</html>
buy tea लिखकर Add दबाएँ। पंक्ति buy tea होती है और इनपुट साफ़ हो जाता है। Done दबाएँ तो पंक्ति done: buy tea हो जाती है। Remove दबाएँ तो सूची खाली है। खाली इनपुट पर Add कुछ नहीं जोड़ता।
मेज़ पर पाँच कदम
- addTask("buy tea") चलाएँ। पहला text buy tea है और done false है।
- फ़ॉर्म भेजें। पेज फिर से लोड नहीं होता और पंक्ति दिखती है।
- Done दबाएँ। पंक्ति done: buy tea दिखाती है।
- Remove दबाएँ। tasks.length 0 हो जाता है।
- केवल रिक्त स्थान भेजें। सूची नहीं बढ़ती।
जो गलतियाँ सच में होती हैं
- preventDefault छोड़ देना, जिससे भेजते ही सरणी मर जाती है
- खाली स्ट्रिंग का push करना
- Done या Remove पर type="submit" लगाना
- स्क्रीन से पंक्ति मिटाकर splice भूल जाना, जिससे अगला चित्र उसे वापस लाता है
- splice के बाद render न करना
- इनपुट को पृष्ठ पर HTML की तरह लिखना
याद रखने लायक
- एक काम { text, done } है और done false से शुरू होता है
- addTask("buy tea") buy tea सहेजता है, खाली इनपुट कुछ नहीं सहेजता
- preventDefault पेज रखता है और render पंक्तियाँ बनाता है
- Done done: buy tea दिखाता है और Remove लंबाई 0 छोड़ता है
- हर बदलाव के बाद फिर से चित्र बनाएँ
🧠 अपने ज्ञान की परीक्षा करें
अपने ज्ञान की परीक्षा करें
इस इंटरैक्टिव क्विज़ के साथ अपनी चुनौती लें और देखें कि आप विषय को कितनी अच्छी तरह समझते हैं
📝 निर्देश
- हर प्रश्न को ध्यान से पढ़ें
- हर प्रश्न के लिए सबसे अच्छा उत्तर चुनें
- आप जितनी बार चाहें क्विज़ दोबारा दे सकते हैं
- आपकी प्रगति शीर्ष पर दिखाई जाएगी