{"id":884,"date":"2010-08-12T08:21:55","date_gmt":"2010-08-12T07:21:55","guid":{"rendered":"http:\/\/www.simonbattersby.com\/blog\/?page_id=884"},"modified":"2013-11-26T17:08:18","modified_gmt":"2013-11-26T17:08:18","slug":"vertical-scrollbar-with-integrated-autocomplete-jquery-ui","status":"publish","type":"page","link":"https:\/\/www.simonbattersby.com\/blog\/vertical-scrollbar-with-integrated-autocomplete-jquery-ui\/","title":{"rendered":"Vertical slider with integrated autocomplete &#8211; jQuery UI"},"content":{"rendered":"<p>In response to a comment on my <a href=\"\/blog\/vertical-scrollbar-using-jquery-ui-slider\/\" title=\"Vertical slider demo\">vertical slider with jquery ui<\/a> demo page, here I&#8217;ve extended this further to integrate an autocomplete function.<\/p>\r\n\r\n<p>I&#8217;ve envisaged a scenario where the slider is used to display a number of products (probably retrieved from a database), displayed within the slider as a photograph and a text description. With a large number of products it would be useful to add a &#8220;quickfind&#8221; option to allow the user to type in a search term, and then use autocomplete to match the entered term against values in the database. If the user selects a match, then the slider scrolls to that entry.<\/p>\r\n\r\n<p>This is built on the standard code <a href=\"\/blog\/vertical-scrollbar-using-jquery-ui-slider\/\" title=\"Vertical slider demo\">here<\/a>, and can be used with or without the mousewheel extension. Here&#8217;s the javascript:<\/p>\r\n\r\n<pre>$(\"#quickfind\").autocomplete({\r\n    source: \"get_descriptions.php\",\r\n    minLength: 2,<span class=\"code_comment\">\/\/search after two characters\r\n<\/span>    select: function(event,ui){\r\n        position = $(\".scroll-content-item:contains(\"+ui.item.value+\")\").position();<span class=\"code_comment\">\/\/search for a div containing the selected description and read its position\r\n<\/span>\t\t\r\n        var topValue = -(position.top);<span class=\"code_comment\">\/\/content top is just the negative of the top position\r\n<\/span>\t\t\r\n\tif (topValue&gt;0) topValue = 0;<span class=\"code_comment\">\/\/stop the content scrolling down too much\r\n<\/span>\tif (Math.abs(topValue)&gt;difference) topValue = (-1)*difference;<span class=\"code_comment\">\/\/stop the content scrolling up too much\r\n<\/span>\r\n\tsliderVal = (100+(topValue*100\/difference));<span class=\"code_comment\">\/\/calculate the slider position from the content position\r\n<\/span>\t$(\"#slider-vertical\").slider(\"value\", sliderVal);<span class=\"code_comment\">\/\/set the slider position\r\n<\/span>\t}\r\n});\r\n<\/pre>\r\n\r\n<p>You&#8217;ll see this is quite similar to the code used for the mousewheel, except in this case we&#8217;re initially calculating the position of the scroll pane and then the position of the slider. I&#8217;m using the jQuery contains() selector to find the div within the scroll pane which contains the selected text, and then the jQuery position() method to find how far down I need to scroll.<\/p>\r\n\r\n<p>That&#8217;s the javascript, now let&#8217;s have a look at the php code:<\/p>\r\n\r\n<pre><span class=\"code_comment\">\/\/assumimg a $mysqli connection exists...\r\n<\/span>\r\n$term = trim(strip_tags($_GET['term']));<span class=\"code_comment\">\/\/retrieve the search term that autocomplete sends\r\n<\/span>\r\n$qstring = \"SELECT description as value,id FROM test WHERE description LIKE '%\".$term.\"%'\";\r\n$result = $mysqli-&gt;query($qstring);<span class=\"code_comment\">\/\/query the database for entries containing the term\r\n<\/span>\r\nif ($result-&gt;num_rows&gt;0)\r\n\t{\r\n\twhile($row = $result-&gt;fetch_array())<span class=\"code_comment\">\/\/loop through the retrieved values\r\n<\/span>\t\t{\r\n\t\t\t\t$row['value']=htmlentities(stripslashes($row['value']));\r\n\t\t\t\t$row['id']=(int)$row['id'];\r\n\t\t\t\t$row_set[] = $row;<span class=\"code_comment\">\/\/build an array\r\n<\/span>\t\t}\r\n\techo json_encode($row_set);<span class=\"code_comment\">\/\/format the array into json data\r\n<\/span>\t}\r\nelse echo \"error\";\r\n<\/pre>\r\n\r\n<p>This is fairly straightforward &#8211; a couple of points worth mentioning. jQuery autocomplete sends the entered search term as a GET (<code>get_descriptions.php?term=[searchterm]<\/code>) so that&#8217;s what we need to retrieve to use. Autocomplete expects &#8220;value&#8221; for the text, so I&#8217;m retrieving the description field in my database as this.<\/p>\r\n\r\n<p>And that&#8217;s about it. There&#8217;s a separate <a href=\"\/demos\/vertical_scrollbar_autocomplete_demo.php\" title=\"Vertical scrollbar with autocomplete demo page\">demo page<\/a> here. Possible enhancement might be to provide a visual highlight &#8211; change the background colour or border colour &#8211; on the scroll just to make it more obvious.<\/p>\r\n\r\n<h3>Changelog<\/h3>\r\n<h4>5 March 2012 &#8211; simplified javascript<\/h4>\r\n<p>Removed directly changing the top value of .scroll-content since this is done automatically by the slider<\/p>\r\n<h4>11 November 2010 &#8211; change to php code<\/h4>\r\n<p>Added error handling to the php code in the event that no match is found on search. This error did not affect users but caused a javascript error.<\/p>\r\n<h4>4 September 2010 &#8211; styling<\/h4>\r\n<p>added styling to the autocomplete\/dropdown values and to the mouse, in order to make it more obvious that the autocomplete values are clickable.<\/p>","protected":false},"excerpt":{"rendered":"<p>In response to a comment on my vertical slider with jquery ui demo page, here I&#8217;ve extended this further to integrate an autocomplete function. I&#8217;ve envisaged a scenario where the slider is used to display a number of products (probably retrieved from a database), displayed within the slider as a photograph and a text description. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-884","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages\/884","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/comments?post=884"}],"version-history":[{"count":1,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages\/884\/revisions"}],"predecessor-version":[{"id":2894,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages\/884\/revisions\/2894"}],"wp:attachment":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/media?parent=884"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}