Skip to content

Instantly share code, notes, and snippets.

@Joseph-N
Last active August 28, 2021 10:33
Show Gist options
  • Save Joseph-N/ae4d50164755edd7ce33 to your computer and use it in GitHub Desktop.
Save Joseph-N/ae4d50164755edd7ce33 to your computer and use it in GitHub Desktop.
Gists for autocomplete tutorial - foxycomplete rails. Tutorial link http://josephndungu.com/tutorials/autocomplete-search-with-images-in-rails
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require bootstrap.min
*= require foxycomplete
*= require_tree .
*/
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require jquery-migrate
//= require bootstrap.min
//= require foxycomplete
//= require turbolinks
//= require_tree .
@charset "utf-8";
html{
margin-top:0;
}
body{
font: 13px/23px Tahoma, Arial, Helvetica, sans-serif;
background-color:#e1e1e1;
color:#2c2c2c;
}
h1{
margin-bottom:35px;
}
h1, h2{
font-weight:normal;
}
/* Styling for Autocomplete */
/* CSS Document */
.ac_results{overflow:hidden;z-index:99999;margin:0;padding:0;}
.ac_results ul{list-style-position:outside;list-style:none;background:#f5f5f5;margin:0;padding:5px 10px 10px}
.ac_results li{cursor:pointer;display:block;overflow:auto;margin:0;padding:0;border-top:1px solid #e1e1e1;}
.ac_results li:first-child{border:0;}
.ac_loading{background-image:url('<%= asset_path('ajax-loader.gif') %>');background-position:97% center;background-repeat:no-repeat;}
.ac_over{background-color:#FFFFF0;color:#fb0}
.ac_over a:hover{color:#000}
.ac_results li a{display:block; overflow:auto; padding:10px; color:#2c2c2c;}
.ac_results li a img{width:80px; height:auto; max-height:80px;float:left; margin-right:15px;}
<div class="starter-template">
<h1>Search Youtube Vidoes</h1>
<form class="form-inline" role="form">
<div class="form-group">
<input type="text" class="form-control input-lg" id="search" placeholder="Search Youtube Video">
</div>
<button type="submit" class="btn btn-default input-lg">Search</button>
</form>
</div>
AutComplete::Application.routes.draw do
root "searches#index"
get "search" => "searches#search"
end
(function ($) {
// when document is ready for manipulation
$(document).ready(function () {
// our search box with id of search
$('#search').each(function () {
$(this).attr('title', $(this).val())
.focus(function () {
if ($(this).val() == $(this).attr('title')) {
$(this).val('');
}
}).blur(function () {
if ($(this).val() == '' || $(this).val() == ' ') {
$(this).val($(this).attr('title'));
}
});
});
$('input#search').result(function (event, data, formatted) {
$('#result').html(!data ? "No match!" : "Selected: " + formatted);
}).blur(function () {});
$(function () {
// returns the image in the autocomplete results and also a link pointing to the results
// and also the results title. Note we must pass (permalink, image, and title) in our json results
function format(mail) {
return "<a href='" + mail.permalink + "'><img src='" + mail.image + "' /><span class='title'>" + mail.title + "</span></a>";
}
// returns the url of the result
function link(mail) {
return mail.permalink
}
// returns the title of the results
function title(mail) {
return mail.title
}
// Invoke our autocomplete plugin and give it a url where it should fetch for results. In our case is /search
// we defined this custom action in our roots.rb file. Change this to suite yours
$("#search").autocomplete('/search', {
width: $("#search").outerWidth() - 2, //match width of input box (search box)
max: 5, // maximum of five results
scroll: false, // disable scroll in results
dataType: "json", // expect json data
matchContains: "word",
parse: function (data) {
return $.map(data, function (row) {
return {
data: row,
value: row.title,
result: $("#search").val()
}
});
},
formatItem: function (item) {
return format(item);
}
}).result(function (e, item) {
// add the clicked result title in the search box
$("#search").val(title(item));
// redirect to the result's url
location.href = link(item);
});
});
});
})(jQuery);
class SearchesController < ApplicationController
def index
end
def search
# call custom json function with query and limit params
results = custom_json(params[:q], params[:limit])
# return json format
render json: results
end
private
def custom_json(query, max)
# invoke the youtube api and pass in query and limit the maxResults returned
results = RestClient.get "https://www.googleapis.com/youtube/v3/search", {
:params => {
:q => query,
:maxResults => max,
:part => "snippet",
:type => "video",
:key => ENV["YOUTUBE_KEY"]
}
}
# parse the results into json and assign them to data
data = JSON.parse(results)
# parse only data we need and format it so that foxycomplete is able to inteprete it correctly
#in JSON format. (FoxyComplete needs a title, image and permalink)
data["items"].collect do |info|
{
:title => info["snippet"]["title"],
:image => info["snippet"]["thumbnails"]["default"]["url"],
:permalink => "https://www.youtube.com/watch?v=" + info["id"]["videoId"]
}
end.to_json
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment