Last active
January 20, 2017 12:46
-
-
Save hlolli/8d4c080edb803e4f1ff4f27782a0a8d1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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