I have been battling with how to create a search suggestion box or auto complete box in compojure using jquery and this is what i have but still not working
In my routes.home i have below, i can see my list
as output from get-client-list
output is like {:id 2, :name "foobar"}
(defn get-list! [{:keys [params]}]
(log/infof "Pulling client list from db" params)
(let [list (into {} (db/get-client-list params))]
;;list is like hugsql
(log/infof "List of names -> [%s]" list)
(if (empty? list)
(log/errorf "No record found [%s]" list)
(do
(log/infof "The list is ->[%s]" list)
;; seems am missing something here, dont know
;;code for readlist.html is still far below
(layout/render "readlist.html" (:records list))))))
(defn about-page [{:keys [flash]}]
(layout/render "home.html"
(merge nil (select-keys flash [:name :amount :value :er :errors]))))
(defroutes home-routes
(GET "/getinfo" {:keys [headers params body] :as request}
(do
(if (empty? (:user (:session request)))
(do
(log/info "Unauthorised attempt to /getinfo URL:" request)
(response/found "/"))
(about-page request))))
(POST "/getinfo" request
(if (empty? (:user (:session request)))
(do
(log/info "Unauthorised attempt to /getinfo URL:" request)
(response/found "/"))
(msg! request)))
(GET "/clientlist" request (get-list! request)))
My home.html
<div class="col-sm-6">
<p>
Name:
<input class="form-control"
id="search-box"
type="text"
name="clientname"
value="{{name}}" />
</p>
<div id="suggestion-box"></div>
{% if errors.name %}
<div class="alert alert-danger">{{errors.name|join}}</div>
{% endif %}
</div>
<div class="col-sm-6">
<p>
Amount(in figures):
<input class="form-control"
type="number"
name="amount"
value="{{amount}}" />
</p>
{% if errors.amount %}
<div class="alert alert-danger">{{errors.amount|join}}</div>
{% endif %}
</div>
Then in my base.html,
i placed this script within the <head>
there
<script src="https://code.jquery.com/jquery-2.1.1.min.js" type="text/javascript"></script>
<script>
$(document).ready(function(){
$("#search-box").keyup(function(){
$.ajax({
type: "GET",
//calling this URL in route.home
// why are you not working?
url: "/clientlist",
data:'keyword='+$(this).val(),
beforeSend: function(){
$("#search-box").css("background","#FFF url(LoaderIcon.gif) no-repeat 165px");
},
success: function(data){
$("#suggestion-box").show();
$("#suggestion-box").html(data);
$("#search-box").css("background","#FFF");
}
});
});
});
function selectList(val) {
$("#search-box").val(val);
$("#suggestion-box").hide();
}
</script>
readlist.html code is below
{% for item in records %}
<li onClick="selectList('{{item.name|join}}');">
{{item.name|join}}
</li>
{% endfor %}
Please assist, spent hours trying to figure it out. Thanks
From your code, i guess the problem is that the suggestion is not coming up, which means /clientlist
is not doing what its supposed to.
Your .js script seems fine so it seems the problem is with /clientlist
Try this, its crude but will work, you can make it simpler by building on it
(defn process-url-encoded
"parses the url sent from the .js function"
[req]
(let [input (or (:query-string req) (:input-string req))]
(let [input-vec (apply hash-map (str/split input #"[&=]"))]
(walk/keywordize-keys input-vec))))
(defn get-list! [req]
(log/infof "Request sent from .js function")
(try
(let [{keyword :keyword} (process-url-encoded req)
keywd (str "%" keyword "%")
param (hash-map :name-like keywd)
list (into {} (db/get-client-list param))]
(log/infof "The list is -> %s" list)
(layout/render "readlist.html" {:record list}))
(catch Exception e
(log/errorf "No value supplied -> %s" (.getMessage e))
(layout/render "readlist.html" {:record {}}))))
Then your readlist.html should have this
<ul id="need-to-style-this-section">
<li onClick="selectList('{{record.name}}');">
<!-- name should be your database column name-->
{{record.name}}
</li>
</ul>
Also, since you are using clojure template, its likely its based on hugsql syntax, so this should be appropiate
-- :name get-client-list :? :*
-- :doc GETS client list
SELECT name FROM table-name
WHERE name LIKE :name-like
ORDER BY name ASC
Have fun!