I am working on an e-commerce website.
The home page has 2 inputs: Looking for and Location. The user would enter their desired product and location and click on Search as shown below:
The first input (i.e. Looking for) has autocomplete functionality and when the user clicks on it, it opens a list of suggestions. I am using the jQuery UI Autocomplete tool to build the suggestions. The suggestions come from Elasticsearch (in this example I am using a static array to demonstrate the behavior).
The problem I'm solving is that on a mobile device, the autocomplete's suggestions opens under the input and the keyboard pops up and hides the suggestions as shown below:
What I want to do is to highlight the autocomplete input when it is focussed in mobile devices. That is to bring it to the top of the screen and hide everything else. This is what ebay does on mobile devices.
The code
I have placed my autocomplete input inside a sticky-container
and when the container is focused I add active
class to the sticky-container
which would make its position static
.
Note: I am using media queries to do this for mobile devices only, however I could not get the media query working in the snippet below, so I kept them commented.
var elasticSearchSuggestions = [
"Armchair", "Apple", "Ball", "Bed", "Book", "Car", "Cooking", "Desk", "Earaser", "Football", "Games",
"Hammer", "Headphone", "iPhone", "Iron", "Job", "King size bed", "Lamp", "Mobile", "Nail", "Orange",
"Paper", "Pencil", "Pool", "Rail", "Running Shoes", "Queen size bed", "Saw", "Shoes", "Table",
"Tools", "Toyota", "Umbrella", "Window", "Xerox", "Yarn", "Zoo"
];
function bringStickyInputToTopOfThePageOnMobile() {
$("#autocompleteInput").on("click", function() {
$(this).closest('.sticky-container').addClass('active');
});
$("#autocompleteInput").on("blur", function() {
$(this).closest('.sticky-container').removeClass('active');
});
}
function isMobileDevice() {
if (Modernizr.mq('(max-width: 767px)')) {
return true;
}
return false;
}
$(document).ready(function() {
$("#autocompleteInput").autocomplete({
source: elasticSearchSuggestions,
position: {
collision: "flip"
}
});
// if (isMobileDevice()) {
bringStickyInputToTopOfThePageOnMobile();
// }
});
/* All the CSS is inside this media query
* @media (max-width:767px)
*/
.sticky-container.active {
top: 0px;
left: 0px;
position: fixed;
width: 100%;
height: 100%;
padding: 65px 15px;
z-index: 1;
background-color: #fff;
display: block !important;
}
.sticky-container.active:before {
display: block !important;
content: 'x';
font-size: 25px;
position: absolute;
top: 25px;
right: 75px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Products</a>
</li>
</ul>
</nav>
<br>
<div class="container">
<h3>Search Products</h3>
<hr/>
<form>
<div class="form-group sticky-container">
<label>Looking for</label>
<input id="autocompleteInput" type="text" class="form-control" placeholder="Looking for">
</div>
<div class="form-group sticky-container">
<label>Location</label>
<input type="text" class="form-control" id="locationInput" placeholder="Location">
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
</body>
</html>
Note: I am using position: { collision: "flip" }
for jQuery UI's autocomplete which means it should open the suggestion box on the top, if the input is at the bottom of the page... however I think using this method, there is still more room for the autocomplete suggestions box.