Exploring recommendations using AngularJS

I am currently working on replicating the search suggestion feature found at: where certain words are displayed as you type in the search box.

Here is my HTML setup:

<form ng-controller="SearchCtrl">
    <input name="q" ng-model="query" ng-keypress="querySuggest()" type="text">
    <div class="search__enhance">
        <span class="search__offset" ng-bind="suggestion.query"></span>
        <span class="search__suggestion" ng-bind="suggestion.text"></span>
    </div>
</form>

Additionally, inside my controller:

myApp.controller('SearchCtrl', function($rootScope, $scope, $state, $location) {

    $scope.querySuggest = function () {

        var haystack = ["ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Small Talk", "Scheme"];

        $scope.suggestion.query = '';

        $scope.suggestion.text = '';

    }

});

My next step involves displaying the search results within the input element (splitting what has been entered by the user and suggesting alternate query options).

I am currently struggling with the following tasks:

  1. Displaying the search suggestion (excluding the entered query) in the search__suggestion span element.
  2. Showcasing the entered query in the search__offset span element (it appears they do not display the value in the input itself...)
  3. Associating the entered query with the haystack array.

Any thoughts or suggestions on how to tackle these three challenges?

Answer №1

To implement suggestions for an input field, you can create a separate element positioned behind the input. This element will display suggestions fetched through the onchange listener on the input field, addressing points #1 and #2.

For point #3, you can simply match the input against the list of suggestions.


Below is a functional example where pressing the right arrow confirms the suggestion:

angular.module('myApp', [])
  .controller('SearchCtrl', function($rootScope, $scope, $location) {

    $scope.suggestion = {};

    var haystack = ["ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Small Talk", "Scheme"];

    $scope.querySuggest = function($event) {
      if ($event.keyCode == 39) {    // confirm suggestion with right arrow
        $scope.query = $scope.suggestion.text;
        return;
      }
      $scope.suggestion.text = '';
      for (var i = 0; i < haystack.length; i++) {
        if ($scope.query && haystack[i].indexOf($scope.query) === 0) {
          $scope.suggestion.text = haystack[i];
          console.log(haystack[i]);
          break;
        }
      }

    }

  });
form {
  position: relative;
}
.search__suggestion {
  font: normal normal normal 14px/normal Arial;
  position: absolute;
  left: 2px;
  top: 3px;
  color: #aaa;
  z-index: -1;
}
input {
  font: normal normal normal 14px/normal Arial;
  background: transparent;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<form ng-app="myApp" ng-controller="SearchCtrl" autocomplete="off">
  <input name="q" ng-model="query" ng-keyup="querySuggest($event)" type="text">
  <div class="search__enhance">
    <span class="search__suggestion" ng-bind="suggestion.text"></span>
  </div>
</form>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

KnockoutJS is not recognizing containerless if binding functionality

I was recently faced with the task of displaying a specific property only if it is defined. If the property is not defined, I needed to show a DIV element containing some instructions. Despite my efforts using $root and the bind property, I couldn't ...

Generate a series of rotations ranging from -60 to 60 using d3.cloud

I need help replicating the word cloud feature found on for my website. After studying examples and referencing a Stack Overflow answer, I put together the following code: var fill = d3.scale.category20(); var layout = d3.layout.cloud() .size([900, ...

Stop the link action following a delay after the mouse is clicked

I'm currently troubleshooting a function that should prevent users from being redirected when clicking and holding onto a link for more than one second. However, the function I implemented is not functioning as expected. I have spent some time reviewi ...

Preserve the visibility of a text input form while the checkbox is selected

Within my HTML code, there is a form that includes a checkbox labeled "other." When this checkbox is selected, a textbox will appear. If the user types in text and submits the form, the textbox disappears, but the checkbox remains checked (as saved in loca ...

Different ways to enhance max-http-header-size in Vue application

After being redirected from another application, I am unable to open the page and receive an error in the console: Failed to load resource: the server responded with a status of 431 (Request Header Fields Too Large). I came across information about max-h ...

Determining the position coordinates of an element in relation to the viewport using JavaScript, regardless of its relative positioning

I am currently developing a vueJs web application and I'm in need of determining the position of an element within my web app relative to the viewport itself, rather than its parent elements. I'm curious if there exists a function or property tha ...

One-off object property bindings in Angular

Looking to optimize the performance of my app, I encountered a specific issue. Consider having an object with multiple unchangeable keys within it and a view structured as follows: <div ng-if="vm.model"> <span>{{ vm.model.property1 }}</ ...

NodeJS loop issue with variable scoping in the context of express and mongoose

My Tech Stack: NodeJS, express, mongoose var i; for(i = 0; i < results.length; i++){ console.log("out: "+i); RegionData.findOne({'rid': results[i].region_id}, function (err, product) { if (product) { console.log("i ...

Tips for showcasing a table generated from various input types on a separate page after pressing the submit button

After creating two JavaScript functions, I am eager to utilize both of them upon pressing the submit button on my form. The first function is already integrated into the submit button and activates a paragraph display upon submission. Now, I intend to sh ...

Keep track of the toggled state and prevent any flickering when the page is reloaded, all without the

After extensive searching, I couldn't find exactly what I needed. Therefore, I decided to utilize cookies to remember the toggled state of a div whether it's hidden or visible. However, I encountered an issue where there is flicker happening as t ...

404 Error: The requested resource is not available on the web API

I have been attempting to utilize Web Api to send/receive data from the server. In my WebApiConfig.cs file: config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "{controller}/{act ...

How to implement a feature for uploading multiple files through a single form with unique input fields in a web

After searching on Stack Overflow, I couldn't find a suitable solution for my problem. I need help with my code that fetches data and sends it to a PHP file to upload files to specific folders and store their links in a database. However, I am encount ...

Not acknowledging the change quickly enough

Within a controller's logic, there is a function called newGame: function startGame(){ $scope.gameOver = true; $timeout(function(){ //perform game actions $scope.gameOver = false; }, 3000); } Meanwhile, in a dire ...

Angular's innerHTML dilemma

Within my Angular service, I have implemented three methods as shown below: public loadLiveChat() { let url: string; url = this.appConfig.config.liveAgent.liveAgentScriptUrl; this.dynamicallyLoadScript(url); ...

What is the material-ui component that mirrors the functionality of <input type="color"><datalist>?

I'm just starting out with javascript, react, and Material-UI, so my question (along with the code sample) might show my lack of experience. Within a Material-UI TableCell (not a form), I have the following code: <input type="color" name ...

What is the best way to show a message within a specific HTML division with JavaScript?

Here's my attempt at solving the issue: <head> <script> function validateForm() { var username = document.forms["login"]["uname"].value; var password = document.forms["login"]["pwd"].value; if (username == "" || p ...

Issue: ngModel: Unassignable Value

I am currently working on a piece of code that dynamically generates a drop-down list. My goal is to set the selected value using ng-repeat. In order to achieve this, I have implemented a function in ng-model. However, I am encountering an issue with the f ...

Event emitting from a parent Vue.js component

I can't figure out why my code is not functioning properly. I have an event called 'leave' that should be triggered on blur. The components show up correctly, but the event doesn't fire when leaving the inputs. Vue.component('te ...

The combination of CSP 2.0 (unsafe-inline) and Angular offers new possibilities for web

I'm curious to know how implementing CSP 2.0 on my angular app and forbidding unsafe-inline from script-src would affect ng-click and other angular events. Will CSP block them all? ...

StealJS Module Repathing Techniques

There seems to be an issue with my setup, so I welcome all inquiries. I am utilizing an npm package called xrm-mock for a MS CRM mocking framework. Here is how I have configured it: steal.config({ meta: { "dependencyModule": { deps ...