Skip to content

Instantly share code, notes, and snippets.

@matstani
Last active December 14, 2015 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matstani/5055544 to your computer and use it in GitHub Desktop.
Save matstani/5055544 to your computer and use it in GitHub Desktop.
Compojure、lib-noirを使ってフォームバリデーション
(ns helloworld.handler
(:use compojure.core)
(:require [compojure.handler :as handler]
[compojure.route :as route]
[hiccup.form :as form]
[hiccup.core :refer [html]]
[noir.validation :as vali]))
;; レイアウト
(defn layout [& content]
(html
[:head [:title "Form validation using lib-noir."]]
[:body
content]))
;; エラーメッセージ
(defn error-message [[first-error]]
[:span.error first-error])
;; 日付・時刻をPOSTするフォーム
(defn date-time-form [& [{:keys [date time]}]]
(layout
(form/form-to
[:post "."]
[:div
(form/label "date" "日付")
(form/text-field "date" date)
;; バリデーション失敗時はエラーメッセージ
(vali/on-error :date error-message)]
[:div
(form/label "time" "時刻")
(form/text-field "time" time)
;; バリデーション失敗時はエラーメッセージ
(vali/on-error :time error-message)]
[:div (form/submit-button "送信")])))
;;日付チェック用正規表現
(def regex-date-pattern
(re-pattern "^\\d{4}/(1[0-2]|0?[1-9])/(0?[1-9]|[1-2][0-9]|3[01])$"))
;;時刻チェック用正規表現
(def regex-time-pattern
(re-pattern "^([01]?[0-9]|2[0-3]):([0-5][0-9])$"))
;;POSTデータのバリデーションルール
(defn valid-date-time? [{:keys [date time]}]
;; dateをバリデート
(vali/rule (re-matches regex-date-pattern date)
;; 失敗したら :date にエラーメッセージ追加
[:date "日付を入力してください(yyyy/MM/dd)"])
;; timeをバリデート
(vali/rule (re-matches regex-time-pattern time)
;; 失敗したら :time にエラーメッセージ追加
[:time "時刻を入力してください(HH:mm)"])
;; バリデーション結果を返す
(not (vali/errors? :date :time)))
;; POSTされた値を表示
(defn show-date-time [{:keys [date time]}]
(layout
[:p (str "日付は「" date "」です。")]
[:p (str "時刻は「" time "」です。")]))
(defroutes app-routes
(GET "/" [] (date-time-form))
(POST "/" {param :params}
(if (valid-date-time? param)
;; バリデーション成功
(show-date-time param)
;; バリデーション失敗
(date-time-form param)))
(route/not-found "Not Found"))
(def app
(-> app-routes
;;バリデーション用ミドルウェア
vali/wrap-noir-validation
handler/site))
(defproject helloworld "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:dependencies [[org.clojure/clojure "1.4.0"]
[compojure "1.1.5"]
[lib-noir "0.4.6"]
[hiccup "1.0.2"]]
:plugins [[lein-ring "0.8.2"]]
:ring {:handler helloworld.handler/app}
:profiles
{:dev {:dependencies [[ring-mock "0.1.3"]]}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment