webapp simplestate;
import HTMLDocument;
import Webapp;
data AppState(String name, String address, PersonStatus status);
data PersonStatus = PSUnknown | PSNewCustomer | PSCurrentCustomer | PSValuedCustomer;
HTMLDocument webmain() {
doc = HTMLDocument::new(HTML4Strict,"Simple state handling");
void(addHeading(doc.body,1,"Simple state handling application"));
void(addParagraph(doc.body,"This web application demonstrates basic state handling."));
appendExisting(doc.body,runHandler(@startApp));
return doc;
}
ElementTree startApp() {
newstate = AppState("","",PSUnknown);
form = addLocalForm(anonymousBlock);
f1 = addFieldset(form,"Add a new customer record!");
void(addLabelledInput(f1,"Customer's name:",InputText,"cname","",30));
void(addLocalControlInput(f1,"Next step",formStage2@(),newstate));
void(addParagraph(form,"At this stage, no particular state exists, so the default 'handler' function is called, which initialises the application workflow."));
return form;
}
ElementTree formStage2(AppState state) {
// other examples demonstrate how to check that the name is valid
// and redisplay the first form if not.
cname = incomingValue("cname",DataPost);
state.name = cname;
form = addLocalForm(anonymousBlock);
f1 = addFieldset(form,"Set the customer status");
statuses = [SelectOption("New customer","new",true),
SelectOption("Current customer","current",false),
SelectOption("Valued customer","valued",false)];
void(addOptionList(f1,"Select status","status",statuses,false));
// at this point, the name is encoded into the state.
void(addLocalControlInput(f1,"Next step",formStage3@(),state));
return form;
}
ElementTree formStage3(AppState state) {
status = incomingValue("status",DataPost);
if (status == "new") {
state.status = PSNewCustomer;
} else if (status == "current") {
state.status = PSCurrentCustomer;
} else if (status == "valued") {
state.status = PSValuedCustomer;
} else {
// for simplicity of this example, the error handling code for
// this stage has been omitted.
state.status = PSNewCustomer;
}
form = addLocalForm(anonymousBlock);
f1 = addFieldset(form,"Enter the customer's address");
void(addLabelledTextarea(f1,"address","Address"));
// at this point, the name is encoded into the state.
void(addLocalControlInput(f1,"Next step",formFinish@(),state));
void(addParagraph(form,"Obviously, in a real application, the individual forms would probably be longer, or the options at later stages would be affected by earlier stages."));
return form;
}
ElementTree formFinish(AppState state) {
state.address = incomingValue("address",DataPost);
results = anonymousBlock;
void(addHeading(results,2,"The new customer record is:"));
void(addParagraph(results,"Name: "+state.name));
void(addParagraph(results,"Address: "+state.address));
case state.status of {
PSUnknown -> status = "unknown";
|PSNewCustomer -> status = "new";
|PSCurrentCustomer -> status = "current";
|PSValuedCustomer -> status = "valued";
}
void(addParagraph(results,"Status: "+status));
void(appendInlineElement(results,Hyperlink("simplestate.cgi"),"Add another customer"));
return results;
}