Using Events 2

In the previous topic we saw how CL-HTTP allows you to associate one or more JavaScript calls with variables, which you can then use as the argument to the :events keyword in a procedure to generate the appropriate HTML.

In the following examples we use events to add two features to the bulletin board example defined earlier:

  • We use a JavaScript function to give the input field focus when the page is loaded.
  • We use a JavaScript function to disable the Submit button until the user has entered text into the input field.

Full listing

Giving a field input focus

The following example uses a call to the JavaScript function focus() to give a text input field focus when the page is loaded. The event is defined as make-focus with the procedure:
(with-event-handlers
        (make-focus (:java-script :load "document.myform.text.focus()"))

It is then emitted in the <body> tag with the procedure:

 (with-document-body (:stream stream :events make-focus) ...

The whole definition is here:

(defun display-bulletin-board (url stream)
  "Form function to display a bulletin board with a text field."
  (let ((title "Feedback"))
    (with-event-handlers
        (make-focus (:java-script :load "document.myform.text.focus()"))
      (with-successful-response (stream :html)
        (with-html-document (:stream stream)
          (with-document-preamble (:stream stream)
            (declare-title title :stream stream))
          (with-document-body (:stream stream :events make-focus)
            (with-section-heading (title :stream stream)
              (dolist (topic (reverse *board*))
                (when topic
                  (with-paragraph (:stream stream) 
                    (write-string-quoting-specials topic stream)))
              (with-fillout-form (:post url :name "myform" :stream stream)
                (accept-input 'string "text" :stream stream)
                (accept-input 'submit-button "Submit" :stream stream))))))))))

We've used the full version of with-successful-response, rather than using the with-page macro we defined in Generating HTML, because we want to include the :events parameter in the document body.

The response function is identical to the original version in Creating a Form:

(defun update-bulletin-board (url stream alist)
  "Response function to add an entry to the bulleting board."
  (bind-query-values (text) (url alist)
    (atomic-push text *board*)
      (display-bulletin-board url stream)))

We export the URL here:

(export-url "http://localhost:8000/board.html"
            :html-computed-form
            :form-function 'display-bulletin-board
            :response-function 'update-bulletin-board)

Validating form input

Another application of events is to call a JavaScript routine to validate user input, before allowing the user to submit the form.

In the following example we disable the Submit button on loading the page, and only enable it when the user has typed into the text input field:

(defun display-bulletin-board (url stream)
  "Routine to display a bulletin board and a form."
  (let ((title "Feedback"))
    (with-event-handlers
        (make-focus 
         (:java-script :load
          (lambda (stream)
            (fast-format stream "\"document.myform.mysubmit.disabled = true\""))))
      (with-event-handlers
          (check-field 
           (:java-script :key-press 
            (lambda (stream)
              (fast-format stream "\"if (this.value == '') document.myform.mysubmit.disabled = false\""))))
        (with-successful-response (stream :html)
          (with-html-document (:stream stream)
            (with-document-preamble (:stream stream)
              (declare-title title :stream stream))
            (with-document-body (:stream stream :events make-focus)
              (with-section-heading (title :stream stream)
                (dolist (topic (reverse *board*))
                  (with-paragraph (:stream stream) (write-string-quoting-specials topic stream)))
                (with-fillout-form (:post url :name "myform" :stream stream)
                  (accept-input 'string "text" :events check-field :stream stream)
                  (accept-input 'submit-button "mysubmit" :stream stream))))))))))

The same approach can be used to validate numeric input, or check the format of an email address, etc.

For more examples of using with-event-handlers see the next topic, Using Scripts.


blog comments powered by Disqus