fun step(state, id, items) client {
receive {
case GetList(pid) -> pid ! items; step(state, id, items)
case SetList(items) ->
draw(id, items);
step(state, id, items)
case MouseDown(elem) ->
if (isElementNode(elem) && (parentNode(elem) == getNodeById(id)))
step(Dragging(elem), id, items)
else
step(Waiting, id, items)
case MouseUp -> step(Waiting, id, items)
case MouseOut(toElem) ->
switch (state) {
case Waiting -> step(Waiting, id, items)
case Dragging(elem) ->
if (isElementNode(toElem) && (parentNode(toElem) == getNodeById(id))) {
var items = swap(items,
getTextContent(getValue(firstChild(elem))),
getTextContent(getValue(firstChild(toElem))));
draw(id, items);
step(Dragging(elem), id, items)
} else step(Dragging(elem), id, items)
}
}
}
fun draw(id, items) {
domReplaceChildren(
for (item <- items)
{stringToXml(item)}
,
getNodeById(id)
)
}
fun draggableList(id, items)
{
var dragger = spawnClient { step(Waiting, id, items) };
(
{for (item <- items)
{stringToXml(item)}
}
,
fun () {spawnWait { dragger ! GetList(self()); receive { case v -> v} }},
fun (items) {dragger ! SetList(items);}
)
}
fun itemsTable() server {
table "items" with (i : Int, name : String)
from database "draggable"
}
fun load() server {
var t = itemsTable();
var items =
query { for (item <-- t)
orderby (item.i)
[(name=item.name)]};
map ((.name), items)
}
sig save : ([String]) ~> ()
fun save(itemsList) server {
ignore(mapi(
fun (item, i) {
update (r <-- itemsTable())
where (r.i == i)
set (name=item)
},
itemsList))
}
fun main() {
var (bears, read, write) = draggableList("bears", load());
var marshaller = spawnClient {
fun listen() {
receive {
case Load -> write(load())
case Save -> save(read())
};
listen()
}
listen()
};
page