How do autocomplete suggestions work? - autocomplete

For example, if you type something in upper-right google/yahoo search box in firefox there will be some kind 'suggested auto complete' sort of thing.
Another example is in youtube search box and Stackoverflow tags edit box just below this question preview. How do they work? What technology behind 'em?

What technology behind 'em?
In case you are wondering which data structure is being used underneath then its called "trie" and for using less space compared to tries you can use "DAFSA"
How do they work?
both are implemented as a tree, where each node of tree corresponds to one character in a string and the character which appears before is parent of character which appears later e.g. The strings "tap", "taps", "top", and "tops" stored in a Trie (left) and a DAFSA (right),so as you begin to type tap..the tree is traversed based on the characters typed and shows the suggestions based on some weight assigned to each word, weight may be assigned based on usage frequency of the word.
Looking up string in worst case is O(m) time where m is the length of string.
Image is being referenced from the wikipedia articel : DAFSA,trie

That's done with the use of AJAX, this site has a nice tutorial on it:
AJAX Suggest Tutorial, and the WaybackMachine version, as website seems down.
A database with keywords and a bit of code is all there is to it as far as I know.
I'm learning how to use it right now actually, for work. :)
Another resource is w3schools. They have covered it as well.

They use JavaScript to normally:
Look at a local array of all possible values
Request another page (i.e. /autocomplete.php?q=partialText) in the background.
Call a webservice.
When the JavaScript has the list of entries to show it modifies the page to show the autocomplete box.
If you want to put an autocomplete box on your website I have used and found the following to be very good. It is also based on the popular jQuery framework.
jQuery autocomplete plugin

It's quite simple.
Client side:
Grab keystrokes in form field
On keystroke make an AJAX request to server
If another keystroke is entered immediately, cancel current AJAX request as it is obsolete now
Make a new AJAX requested with updated characters in form field
Show server response to client
Server side:
All words are already bucketed alphabetically
If client request comes in for "ove" find all words starting with ove, ordered by popularity
Return top matches to client

There's an excellent open-source Country selector in the Smashing Magazine article (link below) which includes a discussion of the usability challenges with plain autocomplete solutions, and fixes them.
While I'm UX, not Dev, I'm certain a clever developer could adapt this open-source code to handle other kinds of selections—not just the names of countries. :)
The article that describes the usability issues that this selector resolves.
The demo and open-source download. Try it!
Disclaimer: I have no connection to the folks who made this Country selector. I just happen to know about it, and I like to share information about Usability with developers, FWIW.

There's as many answers to this as there are different implementations of them. Our AutoCompleter which you can see a sample of in Stacked works by raising an event which then is handled in the codebehind of the .ASPX page from which you populate a ControlCollection with whatever controls you wish. We're however in Stacked only using Literal controls with Text content being anchor links. But we could add up checkboxes or images if we wanted to...
If you're on ASP.NET our AutoCompleter is a great place to start. If you're on "something else" then probably ScriptAculous AutoCompleter is another nice place to start...

i also have been recently working on autocomplete feature and we used lucene to index the text to be shown in autocomplete. Searching is fast with lucene. Somethings to look at when working with autocomplete data:
Freshness of suggestions,
Dependency on the long term data,
Regional dependency,
Language dependency

Update 2022
The marked answer is a little outdated. Suggestions autocomplete seems like magic on the surface but really what it is under the hood is
fast asynch communication and
searching through a list of keywords
Send a string to your database then return response in JSON to loop/iterate through. Then repeat as user types.
One good example is done with YELP Fusion.
Below is example with small library autocomplete.js
$(function () {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$(".sbx-custom__input").autocomplete({
source: availableTags
});
});
<!--jqueryui-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<!--autocompletejs-->
<script src="https://cdn.jsdelivr.net/npm/#tarekraafat/autocomplete.js#10.2.6/dist/autoComplete.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/#tarekraafat/autocomplete.js#10.2.6/dist/css/autoComplete.min.css">
<!--input-->
<input class="sbx-custom__input" autocomplete="on" required="required" placeholder="autocomplete...">

here is the simple example from my code(using jquery + jquery ui). first i requested all data with ajax that i prefixed to inbox then i clicked one of them and so it redirects to another action succesfully.
$("#Name").autocomplete({
source: function (request, response) {
var prefix = { Name: request.term};
$.ajax({
url: '#Url.Action("FilterMastersByName", "JsonResult")',
data: JSON.stringify(prefix),
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return item;
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
select: function (e, i) {
var abc=i.item.val;
let a = document.createElement('a');
a.href = `/Home/GetMasterById?masterId=${abc}`;
a.click();
},
minLength: 1
});
});
Dont forget setFilterMastersByName action to httppost and GetMasterById to httpget

Here is one for MooTools.

Related

Capturing DOM Value using GTM

Total noob here so please bear with me:
I am trying to setup dynamic FB remarketing on a client ecommerce site.The problem is that the site doesn't have a data layer setup for this process so I'm trying to scrape some ecommerce values from the DOM (specifically the product name).
Essentially I am trying to capture the product name from this code string from the order confirmation page:
<h3> <p> **Icebreaker® Pocket Hat - Black/Cargo** </p> </h3>
The "Icebreaker® Pocket Hat - Black Cargo" is what I'm trying to feed into a custom FB pixel as a DOM variable in GTM. I've been experimenting all sorts of things but nothing has really worked so far. I've already captured order value this way so I'm fairly confident this is at least possible.
On the same order confirmation page, there is also this bit of JavaScript with the product name in it should that be of use as well:
<script type="text/javascript"> var gbTracker = new GbTracker('cabelasca', 'Production'); gbTracker.autoSetVisitor(); var visitorId = gbTracker.getVisitorId(); var sessionId = gbTracker.getSessionId(); gbTracker.sendOrderEvent({ cart: { items: [ { productId: '79530', title: '**Icebreaker® Pocket Hat - Black/Cargo**', price: 24.97, quantity: 1 }, ] } }); </script>
I am hoping someone knows how to pass this value using some kind of custom GTM variable. Any nudge towards an answer would be greatly appreciated. Thanks guys.
What I would normally do if I need to get some data from DOM is:
Create DOM element variable
This variable will find all necessary data from DOM. For example in your case variable should be like that:
CSS selector: h3 > p > a
Use this variable in your tags
Then in your tags just use this variable like that: {{Product Title}}

LimeSurvey auto-complete feature

Imagine the question: "Please write down five titles of TV Series".
We want the answer to be spontaneous thus the users freely recall and write their answers such as "Game of Thrones", "The Big Bang Theory" or "Friends".
Our problem is that some of them will write "big bang theory", others "The Big Bang Show" or even "big ban teory" but we know that these answers are the same.
Therefore, we would like LimeSurvey to dynamically offer an auto-completed answer like "The Big Bang Theory" to all of them so that we minimize the manual work of rewriting and grouping the answers.
Is this feature available? If not, do you have any clue about how to implement it?
LimeSurvey (and don't think any other system) don't have core system to do this. But LimeSurvey include jquery-ui, and jquery-ui have autocomplete.
Something like this (if you have a csv file).
download jquery.csv-0.71.js at https://code.google.com/p/jquery-csv/ and put it in your template directory.
put your csv file in your template directory (name series.csv : one serie by line)
Update the HTML sourve of your question with:
<script type="text/javascript" src="{TEMPLATEURL}jquery.csv-0.71.js"></script>
<script>
var url = "{TEMPLATEURL}series.csv";
$(function() {
var seriesTitle = new Array();
$.get(url,function(data){
fullArray = $.csv.toArrays(data);
$(fullArray).each(function(i, item){
seriesTitle.push(item[0]);
});
$("#question{QID} input[type=text]").autocomplete({
source: seriesTitle
});
});
});
</script>
It work for multi text and short text.
If needed you can use an API (and if available).
Look at autocomplete exemple to see using JSON : http://jqueryui.com/autocomplete/#remote

FilteredTextBox in Lift?

I'm looking for a filteredTextBox in lift to block users from inserting wrong input types.
Something like this Ajax example: http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/FilteredTextBox/FilteredTextBox.aspx
Someone knows something similar in lift or knows if SHtml.ajaxText has some Attribute to do that?
If you are targeting HTML5 capable browsers, SHtml has outputs for specific types - like SHtml.number(...) and SHtml.range(...). You can accomplish the same thing using SHtml.ajaxText(label, func, "type" -> "number") (or "type" -> "range", etc...).
To target other browsers (or for more robust functionality), JQuery might be your best bet. You could write your own validation function to get called, or googling quickly found this library which looks like it would work (though there must be others too). Based on their documentation, to use it, it looks like you'd just need to do this:
Snippet:
//add a class for the type (in this case to validate lowercase)
".lc-input" #> SHtml.ajaxText(label, func, "class" -> "validate-this-lowercase")
Template:
//Add this into a processed template - head_merge should add to the head of the document
<head_merge>
<script type="text/javascript">
$(document).ready(function(){
$(".validate-this-lowercase").filter_input({regex:'[a-z]'});
});
</script>
</head_merge>
<span class="lc-input"></span>

I search a tutorial on how play and customize with collection form

I need to create some forms non-linked to entities.
I pretty understood how create my builders, but when I try to use them, I am pretty confuse, and I don't really find examples in the online doc of Symfony 2.0
To go into the details: I create a "Multiple choice question" form. So I created:
a "class ResponseType extends AbstractType"
a "class MCQType extends AbstractType", which uses my class ResponseType
a file "forms.html.twig", which includes templates for my "responsetype_widget" and for my "mcqtype_widget"
My aim is to be able to customize the labels and play with them in this template (like add div with uniqueID, etc), specially the itemization when I add a new item: I would know how to change the "0", "1", "2", etc in "Bad answer 1", "Bad answer 2", etc.
Currently, I do it with JQuery, in the client-side. But when I submit my form, and an error appears, my created items appear with the "0", "1" ; generated by the server-side.
Here are screenshot to have a better view of the situation:
Modified by JQuery (sorry not enought reputation to post images)
Generated by Symfony 2
I really would customize these labels on the server-side, or in my "class MCQType extends AbstractType", or from the mcqtype_widget in forms.html.twig
I tried a lot of stuff that I found in the doc, but nothing works and I feel desesperate to mofify that from the JS instead of the server-side.
Is somebody have a good example?
Thank you by advance. And if any good tutorial is realeased about manipulate collections, I would really help me!
What you need to do for customizing those labels is to redefine the template block to include your modification.
To do so, you'll need this part of the documentation :
http://symfony.com/doc/2.0/cookbook/form/form_customization.html
I would also advise you to play with that in order to get familiar with the form collection :
http://bootstrap.mohrenweiserpartner.de/mopa/bootstrap/forms/collections
Don't hesitate to go deep inside to see how they are doing.
PS: if you need to hide those labels, you need to pass 'show_legend' => false, inside the field options

Lazy load github gist files to display source code on the website

I have a couple of gists which I need to include in a website post to showcase the source code. Currently, I'm inlining each of the multiple gists at various places in the HTML with script tags, however, this would be a blocking call. So, is there a way to dynamically load the gists and paste it specific points in time.
I tried something like below :-
<html>
<body>
<div id="bookmarklet_1.js"></div>
<div id="bookmarklet_2.js"></div>
<div id="bookmarklet_3.js"></div>
var scriptMap = {'bookmarklet_1.js' : 'https://gist.github.com/892232.js?file=bookmarklet_1.js',
'bookmarklet_2.js' : 'https://gist.github.com/892234.js?file=bookmarklet_2.js',
'bookmarklet_3.js' : 'https://gist.github.com/892236.js?file=bookmarklet_3.js'};
var s, scr, holder;
for(s in scriptMap){
holder = document.getElementById(s);
scr= document.createElement('script');
scr.type= 'text/javascript';
scr.src= scriptMap[s];
holder.appendChild(scr);
}
</script>
</body>
</html>
The above didn't work for me, it seems that each script is doing a document.write internally to write the CSS and soure code. Has anyone tried this before or got it working ?
I started a project exactly for this purpose. Dynamically-embedded Gists
Try it now: http://urlspoiler.herokuapp.com/gists?id=992729
Use the above url as the src of a dynamically-created iframe, or add &format=html to get the Gist html snippet via ajax, then put it anywhere you want. (The gist in the above url also happens to be the documentation for how to use this project.)
I myself wanted to do exactly the same thing (with the addition of even removing the default gist style link) - ended up building a "generic" script loader that handles document.write calls :
https://github.com/kares/script.js
Here's how one can use it for embedding gists (and pasties) :
https://github.com/kares/script.js/blob/master/examples/gistsAndPasties.html
You can now get the HTML + CSS directly using JSONP.
I wrote a fuller answer in response to this question, but the key is that you can get the HTML + CSS using JSONP.
For example: https://gist.github.com/anonymous/5446989.json?callback=callback12345
callback12345({
"description": "Function to load a Gist without an iframe",
"public": true,
...
"div": <HTML code>,
"stylesheet": <URL of CSS file>
})