From 8f7b03b5b8cb654af1af6170a4fcbe2094efb1c5 Mon Sep 17 00:00:00 2001 From: rnentjes Date: Fri, 15 Nov 2019 19:13:45 +0100 Subject: [PATCH] Update readme --- readme.md | 379 ++++++++++-------- src/main/kotlin/nl/astraeus/komp/todo/Todo.kt | 3 +- 2 files changed, 211 insertions(+), 171 deletions(-) diff --git a/readme.md b/readme.md index b99fa05..369d533 100644 --- a/readme.md +++ b/readme.md @@ -16,9 +16,29 @@ Complete source: ```kotlin package nl.astraeus.komp.todo -import kotlinx.html.* -import kotlinx.html.js.* +import kotlinx.html.HtmlBlockTag +import kotlinx.html.InputType +import kotlinx.html.TagConsumer +import kotlinx.html.a +import kotlinx.html.button +import kotlinx.html.classes +import kotlinx.html.div +import kotlinx.html.footer +import kotlinx.html.h1 +import kotlinx.html.header +import kotlinx.html.id +import kotlinx.html.input +import kotlinx.html.js.onClickFunction +import kotlinx.html.js.onDoubleClickFunction +import kotlinx.html.js.onKeyPressFunction +import kotlinx.html.label +import kotlinx.html.li +import kotlinx.html.section +import kotlinx.html.span +import kotlinx.html.strong +import kotlinx.html.ul import nl.astraeus.komp.Komponent +import nl.astraeus.komp.include import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLInputElement import org.w3c.dom.events.Event @@ -27,206 +47,227 @@ import kotlin.browser.document import kotlin.js.Date /** - * https://github.com/tastejs/todomvc/ + * see: https://github.com/tastejs/todomvc/ */ class Todo( - val dataId: String, - var title: String, - var completed: Boolean = false, - var editing: Boolean = false + val dataId: String, + var title: String, + var completed: Boolean = false, + var editing: Boolean = false ) enum class Selection(val title: String) { - ALL("All"), - ACTIVE("Active"), - COMPLETED("Completed") + ALL("All"), + ACTIVE("Active"), + COMPLETED("Completed") } -class TodoApp: Komponent() { - val todoList: MutableList = ArrayList() - var selected: Selection = Selection.ALL +fun HtmlBlockTag.todo(app: TodoApp, todo: Todo) { + this.include(TodoKomponent(app, todo)) +} - fun addTodo(e: Event) { - val target = e.target +class TodoKomponent( + val app: TodoApp, + val todo: Todo +) : Komponent() { - if (target is HTMLInputElement) { - todoList.add(Todo("${Date().getTime()}", target.value)) - - refresh() + override fun render(consumer: TagConsumer) = consumer.li { + if (todo.editing) { + classes += "editing" + input(classes = "edit") { + value = todo.title + onKeyPressFunction = { e -> + val target = e.target + if (target is HTMLInputElement && e is KeyboardEvent && e.keyCode == 13 && target.value.isNotBlank()) { + app.editTodo(e, todo) + } } + } + } else { + if (todo.completed) { + classes += "completed" + } + attributes["data-id"] = todo.dataId + div(classes = "view") { + input(classes = "toggle") { + type = InputType.checkBox + checked = todo.completed + onClickFunction = { + app.todoClicked(todo) + } + } + label(classes = "todo-content") { + +todo.title + + onDoubleClickFunction = { + app.setEditing(todo) + } + } + button(classes = "destroy") { + onClickFunction = { + app.destroyTodo(todo) + } + } + } + } + } + +} + +class TodoApp : Komponent() { + val todoList: MutableList = ArrayList() + var selected: Selection = Selection.ALL + + fun addTodo(e: Event) { + val target = e.target + + if (target is HTMLInputElement) { + todoList.add(Todo("${Date().getTime()}", target.value)) + + refresh() + } + } + + fun editTodo(e: Event, todo: Todo) { + val target = e.target + + if (target is HTMLInputElement) { + todo.title = target.value + todo.editing = false + + refresh() } - fun editTodo(e: Event, todo: Todo) { - val target = e.target + } - if (target is HTMLInputElement) { - todo.title = target.value - todo.editing = false + fun destroyTodo(todo: Todo) { + todoList.remove(todo) - refresh() - } + refresh() + } - } + fun selectSelection(selection: Selection) { + selected = selection - fun destroyTodo(todo: Todo) { + refresh() + } + + fun clearCompleted() { + for (todo in ArrayList(todoList)) { + if (todo.completed) { todoList.remove(todo) - - refresh() + } } - fun selectSelection(selection: Selection) { - selected = selection + refresh() + } - refresh() + fun todoClicked(todo: Todo) { + todo.completed = !todo.completed + + refresh() + } + + fun getItemsLeft(): Int { + var result = 0 + for (todo in todoList) { + if (!todo.completed) { + result++ + } + } + return result + } + + fun setEditing(editTodo: Todo) { + for (todo in todoList) { + todo.editing = todo == editTodo } - fun clearCompleted() { - for (todo in ArrayList(todoList)) { - if (todo.completed) { - todoList.remove(todo) - } + refresh() + } + + override fun refresh() { + super.refresh() + + val inputBox = document.getElementById("todo_input") + + if (inputBox is HTMLInputElement) { + inputBox.focus() + } + } + + override fun render(consumer: TagConsumer) = consumer.section(classes = "todoapp") { + header(classes = "header") { + h1 { +"todos" } + input(classes = "new-todo") { + id = "todo_input" + placeholder = "What needs to be done?" + autoFocus = true + onKeyPressFunction = { e -> + val target = e.target + if (target is HTMLInputElement && e is KeyboardEvent && e.keyCode == 13 && target.value.isNotBlank()) { + addTodo(e) + + target.value = "" + target.defaultValue = "" + } } - - refresh() + } } - fun todoClicked(todo: Todo) { - todo.completed = !todo.completed - - refresh() - } - - fun getItemsLeft(): Int { - var result = 0 + section(classes = "main") { + input(classes = "toggle-all") { + type = InputType.checkBox + } + label { + htmlFor = "toggle-all" + +"Mark all as complete" + } + ul(classes = "todo-list") { for (todo in todoList) { - if (!todo.completed) { - result++ - } + if (selected == Selection.ALL || + (todo.completed && selected == Selection.COMPLETED) || + (!todo.completed && selected == Selection.ACTIVE)) { + todo(this@TodoApp, todo) + } } - return result + } } - fun setEditing(editTodo: Todo) { - for (todo in todoList) { - todo.editing = todo == editTodo - } - - refresh() - } - - override fun refresh() { - super.refresh() - - val inputBox = document.getElementById("todo_input") - - if (inputBox is HTMLInputElement) { - inputBox.focus() - } - } - - override fun render(consumer: TagConsumer) = consumer.section(classes = "todoapp") { - header(classes = "header") { - h1 { + "todos" } - input(classes = "new-todo") { - id = "todo_input" - placeholder = "What needs to be done?" - autoFocus = true - onKeyPressFunction = { e -> - if (e is KeyboardEvent && e.keyCode == 13) { - addTodo(e) - } - } - } - } - - section(classes = "main") { - input(classes = "toggle-all") { - type = InputType.checkBox - } - label { - for_ = "toggle-all" - + "Mark all as complete" - } - ul(classes = "todo-list") { - for (todo in todoList) { - if (selected == Selection.ALL || - (todo.completed && selected == Selection.COMPLETED) || - (!todo.completed && selected == Selection.ACTIVE)) { - li { - if (todo.editing) { - classes += "editing" - input(classes = "edit") { - value = todo.title - onKeyPressFunction = { e -> - if (e is KeyboardEvent && e.keyCode == 13) { - editTodo(e, todo) - } - } - } - } else { - if (todo.completed) { - classes += "completed" - } - attributes["data-id"] = todo.dataId - div(classes = "view") { - input(classes = "toggle") { - type = InputType.checkBox - checked = todo.completed - onClickFunction = { - todoClicked(todo) - } - } - label(classes = "todo-content") { - +todo.title - - onDoubleClickFunction = { - setEditing(todo) - } - } - button(classes = "destroy") { - onClickFunction = { - destroyTodo(todo) - } - } - } - } - } - } - } - } - } - - footer(classes = "footer") { - span(classes = "todo-count") { - strong { + "${getItemsLeft()}" } - + " item left" - } - ul(classes = "filters") { - for (selection in Selection.values()) - li { - a { - if (selection == selected) { classes += "selected" } - href = "#" - + selection.title - onClickFunction = { - selectSelection(selection) - } - } - } - } - button(classes = "clear-completed") { - + "Clear completed" - onClickFunction = { - clearCompleted() - } - } + footer(classes = "footer") { + span(classes = "todo-count") { + strong { +"${getItemsLeft()}" } + +" item left" + } + ul(classes = "filters") { + for (selection in Selection.values()) { + li { + a { + if (selection == selected) { + classes += "selected" + } + href = "#" + +selection.title + onClickFunction = { + selectSelection(selection) + } + } + } } + } + button(classes = "clear-completed") { + +"Clear completed" + onClickFunction = { + clearCompleted() + } + } } + } } -fun main(args: Array) { - Komponent.create(document.body!!, TodoApp(), true) +fun main() { + Komponent.create(document.body!!, TodoApp(), true) } -``` \ No newline at end of file +``` diff --git a/src/main/kotlin/nl/astraeus/komp/todo/Todo.kt b/src/main/kotlin/nl/astraeus/komp/todo/Todo.kt index a152da8..1adaf80 100644 --- a/src/main/kotlin/nl/astraeus/komp/todo/Todo.kt +++ b/src/main/kotlin/nl/astraeus/komp/todo/Todo.kt @@ -21,7 +21,6 @@ import kotlinx.html.section import kotlinx.html.span import kotlinx.html.strong import kotlinx.html.ul -import kotlinx.html.video import nl.astraeus.komp.Komponent import nl.astraeus.komp.include import org.w3c.dom.HTMLElement @@ -32,7 +31,7 @@ import kotlin.browser.document import kotlin.js.Date /** - * https://github.com/tastejs/todomvc/ + * see: https://github.com/tastejs/todomvc/ */ class Todo(