(page "index.html" (:require [datascript.core :as d] [clojure.string :as cstr])) (def db (let [schema {:aka {:db/cardinality :db.cardinality/many}} conn (d/create-conn schema)] (d/transact! conn [ {:db/id -1 :name "Maksim" :age 45 :aka ["." "Max Otto von Stierlitz", "Jack Ryan"]} ]) (d/transact! conn [ {:db/id -1 :name "Foom" :age 45 :aka ["."]} ]) conn)) (def search-query '[:find ?n (distinct ?k) :in $ ?startsWith % :where (dothings ?startsWith ?e) [?e :name ?n] [?e :aka ?k]]) (def search-rules '[[(dothings ?startsWith ?e) [?e :name ?n] [(?startsWith ?n)]] [(dothings ?startsWith ?e) [?e :aka ?n] [(?startsWith ?n)]]]) (defn do-query [prefix] (d/q search-query @db (fn [e] (cstr/starts-with? (cstr/lower-case e) (cstr/lower-case prefix))) search-rules)) (def initial-state {}) (defn init-search-panel [state] (let [initial-search "" initial-results (do-query initial-search)] (assoc state :search-panel {:current-search initial-search :search-results initial-results}))) (defn init-add-contact [state] (assoc state :add-contact {})) (defc state ((comp init-search-panel init-add-contact) initial-state)) (defc= search-panel (get state :search-panel) #(dosync (swap! state assoc :search-panel %))) (defc= search (get search-panel :current-search) #(dosync (reset! search-panel {:current-search % :search-results (do-query %)}))) (d/listen! db :datascript->hoplon #(swap! search-panel assoc :search-results (do-query (:current-search @search-panel)))) (defc= search-results (get search-panel :search-results)) (defc= add-contact-data (:add-contact state) #(swap! state assoc :add-contact %)) (defc= new-contact-name (:name add-contact-data) #(swap! add-contact-data assoc :name %)) (defc= new-contact-age (:age add-contact-data) #(swap! add-contact-data assoc :age %)) (defc= new-contact-aka (:aka add-contact-data) #(swap! add-contact-data assoc :aka ["." %])) (defn starts-with? [s ss] (cstr/starts-with? s ss)) (def event-value #(.-value (.-target %))) (html (head (link :href "app.css" :rel "stylesheet" :type "text/css")) (body (h1 "My Contacts") (section :id "add-contact" (form (input :type "text" :placeholder "name" :value new-contact-name :keyup #(reset! new-contact-name (event-value %))) (input :type "text" :placeholder "age" :value new-contact-age :keyup #(reset! new-contact-age (event-value %))) (input :type "text" :placeholder "aka" :value (cell= (and new-contact-aka (second new-contact-aka))) :keyup #(reset! new-contact-aka (event-value %))) (button :click #(do (.preventDefault %) (d/transact! db [{:db/id -1 :name @new-contact-name :age @new-contact-age :aka @new-contact-aka}])) "Add Contact"))) (section :id "do-search" (div search) (input :type "text" :value search :keyup #(reset! search (event-value %)) :placeholder "query ยป") (div :id "results" (for-tpl [[name aka] search-results] (div (h2 name) (ul (for-tpl [alias (cell= (rest aka))] (li alias))))))) ))