Todo with ugly af filter
parent
60b55382f8
commit
da0c4e925d
|
@ -0,0 +1,43 @@
|
|||
const app = Vue.createApp({
|
||||
data: () => ({
|
||||
inputValue: "",
|
||||
items: [
|
||||
{name: "aaa1", done: false},
|
||||
{name: "bbb2", done: true},
|
||||
{name: "ccc3", done: false}
|
||||
],
|
||||
toggle: false,
|
||||
searchString: ""
|
||||
}),
|
||||
methods: {
|
||||
addToList () {
|
||||
//this.items.push(this.inputValue) // nicht mehr brauchbar, da wir jetzt ein objekt haben
|
||||
this.items.push({name: this.inputValue, done: false})
|
||||
this.inputValue = "" //löscht das inputfeld wieder
|
||||
},
|
||||
deleteAll() {
|
||||
this.items = []
|
||||
},
|
||||
deleteItem(index){
|
||||
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
|
||||
this.items.splice(index, 1) // mit (index, 2) löscht es zwei elemente
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredElements () {
|
||||
return this.items.filter(e => e.name.includes(this.searchString))
|
||||
},
|
||||
totalCompletedTasks() {
|
||||
let count = 0;
|
||||
for (let i = 0; i < this.items.length; i++){
|
||||
if (this.items[i].done){
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.mount("#app");
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>TITLE</title>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Jost:wght@400;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<script src="https://unpkg.com/vue@next" defer></script>
|
||||
<script src="app.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
ein todo app
|
||||
+ liste (v-for, array)
|
||||
+ inputfield mit item (databinding)
|
||||
+ bei enter speichern und anzeigen (event)
|
||||
+ items müssen gelöscht werden können (methode?)
|
||||
+ todos als absolviert markieren (checkbox)
|
||||
+ button clear all
|
||||
+ erledigte durchstreichen
|
||||
+ zählen wie viele tasks erledigt sind
|
||||
|
||||
reihenfolge:
|
||||
1. inputfield :)
|
||||
2. array erstellen
|
||||
3. button erstellen
|
||||
4. item hinzufügen
|
||||
5. vorheriger input löschen
|
||||
6. enter zum hinzufügen (GESCHAFFT DANK GOOGLEN!)
|
||||
7. todos anzeigen (hämmer, aber in hässlech)
|
||||
8. alles löschen button (entschäuschend einfach gewesen)
|
||||
9. Spezifisches löschen (hard af)
|
||||
10. checkbox hinzufügen
|
||||
11: css klasse erstellen
|
||||
12: style binding
|
||||
|
||||
-->
|
||||
<section id="app">
|
||||
<input
|
||||
type="text"
|
||||
v-model="inputValue"
|
||||
@keyup.enter="addToList"
|
||||
/>
|
||||
<button @click="addToList">Add</button> Anzahl erledigter Tasks: {{totalCompletedTasks}}<br>
|
||||
<input
|
||||
type="text"
|
||||
v-model="searchString"
|
||||
placeholder="type to filter"
|
||||
/>
|
||||
|
||||
<hr>
|
||||
<ul>
|
||||
<li v-for="(item, index) in filteredElements">
|
||||
<input type="checkbox" v-model="item.done" />
|
||||
<!-- geht aber ist nicht so schön
|
||||
<del v-if="item.done">{{item.name}}</del>
|
||||
<span v-else>{{item.name}}</span>
|
||||
-->
|
||||
<!-- schöner mit CSS class: ich-bin-durchgestrichen-->
|
||||
<span :class="{ 'ich-bin-durchgestrichen': item.done }">{{item.name}}</span>
|
||||
|
||||
<button @click="deleteItem(index)">delete</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button @click="deleteAll">Delete all</button>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: 'Jost', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
section {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
|
||||
margin: 3rem;
|
||||
border-radius: 10px;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
border-bottom: 4px solid #ccc;
|
||||
color: #970076;
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
background-color: #970076;
|
||||
padding: 0.5rem;
|
||||
color: white;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
input {
|
||||
font: inherit;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
border-color: #1b995e;
|
||||
background-color: #d7fdeb;
|
||||
}
|
||||
|
||||
button {
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ff0077;
|
||||
background-color: #ff0077;
|
||||
color: white;
|
||||
padding: 0.05rem 1rem;
|
||||
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
|
||||
button:hover,
|
||||
button:active {
|
||||
background-color: #ec3169;
|
||||
border-color: #ec3169;
|
||||
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
|
||||
.ich-bin-durchgestrichen {
|
||||
text-decoration: line-through;
|
||||
}
|
Loading…
Reference in New Issue