Skip to content

Instantly share code, notes, and snippets.

@hlolli
Last active January 20, 2017 12:46
Show Gist options
  • Save hlolli/8d4c080edb803e4f1ff4f27782a0a8d1 to your computer and use it in GitHub Desktop.
Save hlolli/8d4c080edb803e4f1ff4f27782a0a8d1 to your computer and use it in GitHub Desktop.
(ns input-masker-test
(:require
[goog.dom :as gdom]
[om.next :as om :refer-macros [defui]]
[goog.events :as events]
[goog.events.EventType :as EventType]
[om.dom :as dom]))
(defn input-masker
"mask: a string of number/char with seperator
ex: \"99-99999999\"
\"AA/AAA/AAAA\""
[mask in-str backspace?]
(when-not (nil? in-str)
(loop [mask (seq mask)
;;Remove whitespace if found.
char (re-seq #"[a-zA-Z0-9]" in-str)
out-str ""]
(if (empty? char)
(if (and backspace?
(> (count out-str) 0)
(not (re-matches #"[a-zA-Z0-9]" (last out-str))))
(subs out-str 0 (- (count out-str) 2))
out-str)
(let [fmask (first mask)
ffmask (first (rest mask))
mask-match (cond
(re-matches #"[a-z]" fmask) :lowercase
(re-matches #"[A-Z]" fmask) :uppercase
(re-matches #"[0-9]" fmask) :number
(= "*" fmask) :wildcard
:else :seperator)
next-mask-match (if-not (string? ffmask)
false
(cond
(re-matches #"[a-z]" ffmask) :lowercase
(re-matches #"[A-Z]" ffmask) :uppercase
(re-matches #"[0-9]" ffmask) :number
(= "*" ffmask) :wildcard
:else :seperator))
fchar (first char)
char-match (cond
(re-matches #"[a-z]" fchar) :lowercase
(re-matches #"[A-Z]" fchar) :uppercase
(re-matches #"[0-9]" fchar) :number
:else :seperator)
next-is-seperator? (= next-mask-match :seperator)]
(cond
(= :seperator char-match) (recur (rest mask)
(rest char)
(str out-str fchar))
(= :wildcard mask-match) (if next-is-seperator?
(recur (rest (rest mask))
(rest char)
(str out-str fchar ffmask))
(recur (rest mask)
(rest char)
(str out-str fchar)))
(= mask-match char-match) (if next-is-seperator?
(recur (rest (rest mask))
(rest char)
(str out-str fchar ffmask))
(recur (rest mask)
(rest char)
(str out-str fchar)))
(and (= mask-match :lowercase)
(= char-match :uppercase)) (if next-is-seperator?
(recur (rest (rest mask))
(rest char)
(str out-str
(string/lower-case fchar)
ffmask))
(recur (rest mask)
(rest char)
(str out-str
(string/lower-case fchar))))
(and (= mask-match :uppercase)
(= char-match :lowercase)) (if next-is-seperator?
(recur (rest (rest mask))
(rest char)
(str out-str
(string/upper-case fchar)
ffmask))
(recur (rest mask)
(rest char)
(str out-str
(string/upper-case fchar))))
:else (recur (rest mask)
(rest char)
out-str)))))))
(defui InputMasker
Object
(componentDidMount [this]
(events/listen js/document
EventType/KEYDOWN #(if (= 8 (.-keyCode %)) (om/update-state! this assoc :backspace? true)
(when (:backspace? (om/get-state this))
(om/update-state! this assoc :backspace? false)))))
(componentWillUnmount [this] (events/removeAll js/document EventType/KEYDOWN))
(render [this]
(dom/div nil
(dom/h3 nil "Phone number" (dom/code nil " mask: 999-999-9999"))
(dom/input #js {:id "input-example-1"
:value (:input-example-1 (om/get-state this))
:onChange (fn [e]
(om/update-state! this assoc :input-example-1
(input-masker "999-999-9999"
(str (-> e .-target .-value))
(:backspace? (om/get-state this)))))}))))
(def inputMasker (om/factory InputMasker))
(js/ReactDOM.render (inputMasker) js/klipse-container)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment