Forms, Events, and Dialoging in KRL


spider web

As part of the push for Impact, I released a preview functionality of using KRL with Web forms and demonstrated it at the conference. The ability to interact with forms is built on KRL's new event capabilities. In my previous blog post on this, I hinted at primitive events beyond pageview, but didn't go into much detail. In this blog post, I introduce three new primitive events in the web event domain: change, click, and submit.

The change event is based on the change event that most browers support. The event fires whenever a form element changes. You set it up using the watch action like so:

rule setup is active {
  select when pageview ".*" setting ()
  watch("#form-keys", "change");
}

When this rule fires, it says to "watch" the form element with id #form-keys for any change. The following rule responds to that event:

rule respond_change is active {
  select when web change "#form-keys"
  pre {
     text = "Thanks!!!";
  }
  prepend("#userLogin", text);
}

In this case whenever the form element with id #form-keys changes, the message "Thanks!!!" will be prepended to the element with id #userLogin.

A note about watch. Our goal is to remove the need to do this. The rule respond_change above has all the same information in it and we ought to be able to automatically issue the "watch" action when needed with just a little more information (like what page to watch). That functionality will be added in a future release. For now, you have to explicitly "watch" something.

A click event is similar, although it applies to any element, not just form elements. Again we issue an explicit watch on the right page or pages:

rule setup is active {
  select when pageview ".*" setting ()
  watch("#breadcrumb", "click");
}

Then we can respond to the click:

rule respond_click is active {
  select when web click "#breadcrumb"
  pre {
     text = "<li> Stop clicking me!!!!</li>";
  }
  append("#breadcrumb", text);
}

Again this is a silly example of just appending some text, but the action could be anything that KRL is capable of.

The most powerful of these new primitive events is submit. Suppose that setup paints a form on the page and issues the watch action like so:

rule set_form is active {
  select when pageview ".*" setting ()
  pre {   
    a_form = <<
<div id="my_div">
<form id="my_form" onsubmit="return false">
<input type="text" name="first"/>
<input type="text" name="last"/>
<input type="submit" value="Submit" />
</form>
<ul id="mydata">
</ul>
</div>
    >>;
  }
  {
    notify("Tell us your name...", a_form)
      with sticky=true;
    watch("#my_form", "submit");
  }
}

This rule places a simple form asking for a first and last name on the page along with an empty ul element named #mydata. The watch action watches that form for a submit event. The following rule responds to this event:

rule respond_submit is active {
  select when web submit "#my_form"
  pre {
     first = page:param("first");
     last = page:param("last");
     text = "<li>Your name is #{first} #{last}</li>";
  }
  append("#mydata", text);
}

The rule is selected when a submit event from the form named #my_form happens. It grabs the first and last name from the parameters and places them in a list item inside the list #mydata. After it's run a few times, this looks like so:

A screenshot showing a form submission processing using KRL

Events provide a very flexible foundation for extending KRL to operate in areas that have previously been off limits. The model is not limited to the Web, of course, although that's the first place we're using it. My current work is in getting events for email built into the system. Stand by...