@@ -26,4 +26,81 @@ asynchronicity largely invisible to the programmer.
26
26
27
27
#### What does it look like?
28
28
29
- Check out the included [ demos] ( https://github.com/sanity/kweb/tree/master/src/main/kotlin/com/github/sanity/kweb/demos ) .
29
+ Here we create a simple "todo" list app, note this is heavily commented, excluding comments it is
30
+ fewer than 40 lines of code.
31
+
32
+ ``` kotlin
33
+ import com.github.sanity.kweb.KWeb
34
+ import com.github.sanity.kweb.dom.element.creation.*
35
+ import com.github.sanity.kweb.dom.element.events.on
36
+ import com.github.sanity.kweb.dom.element.modification.addText
37
+ import com.github.sanity.kweb.dom.element.modification.delete
38
+ import kotlinx.coroutines.experimental.future.await
39
+ import kotlinx.coroutines.experimental.future.future
40
+
41
+ fun main (args : Array <String >) {
42
+ // Starts a web server listening on port 8091
43
+ KWeb (8091 , debug = true ) {
44
+ doc.body.apply {
45
+ // Add a header parent to the body, along with some simple instructions.
46
+ h1().addText(" Simple KWeb demo - a to-do list" )
47
+ p().addText(" Edit the text box below and click the button to add the item. Click an item to remove it." )
48
+
49
+ // If you're unfamiliar with the `apply` function, read this:
50
+ // http://beust.com/weblog/2015/10/30/exploring-the-kotlin-standard-library/
51
+
52
+ // We create a <ul> parent, and then use apply() to add things to it
53
+ val ul = ul().apply {
54
+
55
+ // Add some initial items to the list
56
+ for (text in listOf (" one" , " two" , " three" )) {
57
+ // We define this below
58
+ newListItem(text)
59
+ }
60
+ }
61
+
62
+ // Next create an input parent
63
+ val inputElement = input(type = InputType .text, size = 20 )
64
+
65
+ // And a button to add a new item
66
+ val button = button()
67
+ button.addText(" Add Item" )
68
+ // Here we register a callback, the code block will be called when the
69
+ // user clicks this button.
70
+ button.on.click {
71
+ // This looks simple, but it is deceptively cool, and in more complex applications is
72
+ // the key to hiding the client/server divide in a fairly efficient matter. It uses
73
+ // Kotlin 1.1's new coroutines functionality, see
74
+ // https://github.com/Kotlin/kotlinx.coroutines
75
+
76
+ // We start an async block, which will allow us to use `await` within the block
77
+ future {
78
+ // This is where async comes in. inputElement.getValue() sends a message to the
79
+ // browser asking for the `value` of inputElement. This will take time so
80
+ // inputElement.getValue() actually returns a future. `await()` then uses
81
+ // coroutines to effectively wait until the future comes back, but crucially,
82
+ // without tying up a thread (which would getString very inefficient very quickly).
83
+ val newItemText = inputElement.getValue().await()
84
+
85
+ // And now we add the new item using our custom function
86
+ ul.newListItem(newItemText)
87
+
88
+ // And finally reset the value of the inputElement parent.
89
+ inputElement.setValue(" " )
90
+ }
91
+ }
92
+ }
93
+ }
94
+ Thread .sleep(10000 )
95
+ }
96
+
97
+ // Here we use an extension method which can be used on any <UL> parent to add a list item which will
98
+ // delete itself when clicked.
99
+ fun ULElement.newListItem (text : String ) {
100
+ li().apply {
101
+ addText(text)
102
+ on.click { event ->
103
+ delete() }
104
+ }
105
+ }
106
+ ```
0 commit comments