I work on a rails project and I have a problem with a plugin of jquery : autocomplete.
I try to implemete a search engine with multiple word, I include in my webpage 1.8.0.min.js and the plugin autocomplete (jquery-ui-1.8.23.custom.min.js) and the code below in another .js include too:
$(document).ready(function(){
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Scheme"
];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#search" ).bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
availableTags, extractLast( request.term ) ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
});
In my app this code don't work and firebug give me this warning:
TypeError: $("#search").bind("keydown", function (event) {if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) {event.preventDefault();}}).autocomplete is not a function
TypeError: $("#search").bind("keydown", function (e) {e.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active && e.preventDefault();}).autocomplete is not a function
When I test this outside of my app it's work.
I'm on Mandriva 12.04 TLS, and a use firefox 15.0.
Related
I'm a newbie to ajax, I got this code from google and now I want to get the data for the input field from database instead of the variable defined availableTags. I'm confused that where all I want to change the url to the particular function to run.
This is the url I want to add in order to get the value from database:
http://localhost:8888/auto/index.php/birds/get_birds
$( 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"
];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
function log( message ) {
$( "<input name='skill'>" ).text( message ).prependTo( "#log" );
$( "#log" ).scrollTop( 0 );
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.on( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
availableTags, extractLast( request.term ) ) );
},
focus: function(event, ui) {
$(event).val(ui.item.value);
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
if(terms.length <= 3) {
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
log(ui.item.value);
if (jQuery.inArray(ui.item.value, availableTags) > -1) {
availableTags.splice($.inArray(ui.item.value, availableTags), 1);
//availableTags[jQuery.inArray(ui.item.value, availableTags)] = '';
terms.push( "" );
// add placeholder to get the comma-and-space at the end
this.value = terms.join( ", " );
}
return false;
}else{
var last = terms.pop();
$(this).val(this.value.substr(0, this.value.length - last.length - 2)); // removes text from input
$(this).effect("highlight", {}, 1000);
$(this).attr("style","border: solid 1px red;");
return false;
}
},
change: function (event, ui) {
if (!ui.item) {
$(this).val('');
}
}
});
} );
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete - Multiple values</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<!-- <link rel="stylesheet" href="/resources/demos/style.css"> -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tag programming languages: </label>
<input id="tags" size="50">
</div>
</body>
</html>
Contoller:
<?Php
class Birds extends CI_Controller{
function index(){
$this->load->view('birds_view');
}
function get_birds(){
$this->load->model('bird_model');
if (isset($_GET['term'])){
$q = strtolower($_GET['term']);
$data['s']=$this->bird_model->get_bird($q);
}
}
}
Model:
<?php
class Bird_model extends CI_Model{
function get_bird($q){
$this->db->select('*');
$this->db->like('bird', $q);
$this->db->order_by('bird','desc');
$query = $this->db->get('birds');
if($query->num_rows() > 0){
foreach ($query->result_array() as $row){
$new_row['label']=htmlentities(stripslashes($row['bird']));
$new_row['value']=htmlentities(stripslashes($row['id']));
$row_set[] = $new_row; //build an array
}
echo json_encode($row_set); //format the array into json data
}
}
}
Try to replace below code of source
source: function( request, response ) {
$.ajax({
url: "http://gd.geobytes.com/AutoCompleteCity",
dataType: "jsonp",
data: {
q: request.term
},
success: function( data ) {
response( data );
}
});
},
Here URL is the path of your json response. Produce a json response in your controller file
$( 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"
];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
function log( message ) {
$( "<input name='skill'>" ).text( message ).prependTo( "#log" );
$( "#log" ).scrollTop( 0 );
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.on( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function( request, response ) {
$.ajax({
url: "http://gd.geobytes.com/AutoCompleteCity",
dataType: "jsonp",
data: {
q: request.term
},
success: function( data ) {
response( data );
}
});
},
focus: function(event, ui) {
$(event).val(ui.item.value);
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
if(terms.length <= 3) {
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
log(ui.item.value);
if (jQuery.inArray(ui.item.value, availableTags) > -1) {
availableTags.splice($.inArray(ui.item.value, availableTags), 1);
//availableTags[jQuery.inArray(ui.item.value, availableTags)] = '';
terms.push( "" );
// add placeholder to get the comma-and-space at the end
this.value = terms.join( ", " );
}
return false;
}else{
var last = terms.pop();
$(this).val(this.value.substr(0, this.value.length - last.length - 2)); // removes text from input
$(this).effect("highlight", {}, 1000);
$(this).attr("style","border: solid 1px red;");
return false;
}
},
change: function (event, ui) {
if (!ui.item) {
$(this).val('');
}
}
});
} );
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete - Multiple values</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<!-- <link rel="stylesheet" href="/resources/demos/style.css"> -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tag programming languages: </label>
<input id="tags" size="50">
</div>
</body>
</html>
I am using JQuery autocomplete to send a json request to my cakephp application, the javascript code is from http://jqueryui.com/autocomplete/
$(function() {
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tag-string" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
source:function(request, response){
$.getJSON("/articles/getTags/" + request.term + ".json", {
term : extractLast(request.term)
}, response);
},
search: function() {
// custom minLength
var term = extractLast( this.value );
if ( term.length < 1 ) {
return false;
}
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
});(jQuery);
if i run the XMLHttpRequests on the chrome js console (where "c" is the term to search for)
$.getJSON("/articles/getTags/c.json")
i get this response text:
responseText: "{↵ "tags": [↵ {↵ "tag": "Calles"↵ },↵ {↵ "tag": "Circulacion"↵ },↵ {↵ "tag": "cognicion"↵ },↵ {↵ "tag": "Creatividad"↵ }↵ ]↵}"
but the input field does not populate with this values.
This is what i get (i've uploaded an image because is the easiest way to explaint it) on the "Tag String" input field
finally solved.
the json response send to jquery autocomplete must be formated with "value" and "label".
var ac = [
{
label: "One Thing",
value: "One-Thing"
},
{
label: "Two Thing",
value: "Two-Thing"
},
]
Using jQuery autocomplete multiple values option, how can I prevent autosuggestion for every new word.
The problem is that it shows the entire array when you press "space" which slow down (hang) some browsers when using a large array.
Increasing the .minLength value works for the first word, but once you press space it shows the entire array.
How do I stop it from doing that.
http://plnkr.co/edit/ru7i5kuOWzZ7CYu5KNxr?p=preview
<script>
$(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"
];
function split( val ) {
return val.split( / \s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "ui-autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 3,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
availableTags, extractLast( request.term ) ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
});
</script>
You can check for empty string in request parameter in autocomplete source method like below
if(request.term===' ')
{
response([{value: "Enter Some text to search"}]);
return false;
}
Take a look at this jqfaq working sample which may helps you
add this litte if-statement to your source-function
if (extractLast( request.term ).replace(/ /g, "") == "") {
return false;
}
here is a plunker as well.
Hi i'm programming a Chrome offline extension. I know i can't include JS inline. This code is from a jquery widget, it works on the browser perfectly... but not in the app. I guess it's related with $.widget("custom.combobox", {_create: function() {},_createAutocomplete: function() {}, ... );
I had a similar trouble in other file of a widget that didn't work. After checking for an hour i deleted this line of code $( "#tags" ).autocomplete({ minLength: 0, source: availableTagsForFiles }); (that worked perfectly on the browser) and worked again.
I'm using google chrome for everything.
I think it will correct if i write this $.widget("custom.combobox", {_create: function() {},_createAutocomplete: function() {}, ... ); in a different way. But i don't know jquery enought to do it. (it's just a supposition). Can someone help me?
Script that is not working:
$(document).ready(function( $ ) {
console.log("Adios mundo cruel!");
$.widget( "custom.combobox", {
_create: function() {
this.wrapper = $( "" )
.addClass( "custom-combobox" )
.insertAfter( this.element );
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function() {
var selected = this.element.children( ":selected" ),
value = selected.val() ? selected.text() : "";
this.input = $( "<input>" )
.appendTo( this.wrapper )
.val( value )
.attr( "title", "" )
.attr( "id", "EscribeCssTextbox" )
.addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
.focus(cargaTodosLosIdsClasesYElementos)
.keyup(ocupaCambio)
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy( this, "_source" )
})
.tooltip({
tooltipClass: "ui-state-highlight"
});
this._on( this.input, {
autocompleteselect: function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function() {
var input = this.input,
wasOpen = false;
$( "<a>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.tooltip()
.appendTo( this.wrapper )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "custom-combobox-toggle ui-corner-right" )
.mousedown(function() {
wasOpen = input.autocomplete( "widget" ).is( ":visible" );
})
.click(function() {
input.focus();
// Close if already visible
if ( wasOpen ) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete( "search", "" );
});
},
_source: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
response( this.element.children( "option" ).map(function() {
var text = $( this ).text();
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
label: text,
value: text,
option: this
};
}) );
},
_removeIfInvalid: function( event, ui ) {
// Selected an item, nothing to do
if ( ui.item ) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children( "option" ).each(function() {
if ( $( this ).text().toLowerCase() === valueLowerCase ) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if ( valid ) {
return;
}
// Remove invalid value
this.input
.val( "" )
.attr( "title", value + " didn't match any item" )
.tooltip( "open" );
this.element.val( "" );
this._delay(function() {
this.input.tooltip( "close" ).attr( "title", "" );
}, 2500 );
this.input.data( "ui-autocomplete" ).term = "";
},
_destroy: function() {
this.wrapper.remove();
this.element.show();
}
});
});
$(document).ready(function() {
console.log("BUAAAAAAAAAAA I'LL cry !!");
$( "#combobox" ).combobox();
$( "#toggle" ).click(function() {
$( "#combobox" ).toggle();
});
});
My team in the proyect got this solution for the bug, jut use this "" when using widgets in Chrome apps:
$.widget("custom.combobox", {"_create": function() {},"_createAutocomplete": function() {}, ... );
With that Jquery widget displays right. Well just an exception that is not working:
.autocomplete({
"delay": 0,
"minLength": 0,
"source": $.proxy( this, "_source" )
})
I am using jquery-ui's autocomplete in my project. It works great. Now I want to add autocomplete that is dependant on a previous select option.
I have one select and a text input with autocomplete.
<select id='type'>
<option value='languages'>Languages</option>
<option value='OS'>Operating Systems</option>
</select>
<input type='text' id='tags' />
I use a similar function for the autocomplete and it works.
$(function() {
var languages = [
"ActionScript",
"AppleScript",
"Asp",
"Scheme"
];
var os = [
"Windows",
"Mac OS X",
"Chrome",
];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
languages, extractLast( request.term ) ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
});
How can I link it to my onchange event of the previous select. So when I select operating systems. The autocomplete changes the array from languages to os.
I appreciate any help.
Try something along the following. You'll also need to restructure how your suggestion array is formatted slightly so it's more workable!
$("#type").change(function() {
var source = $(this).val().toLowerCase();
$("#tags").source(function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
sources[source], extractLast( request.term ) ) );
});
});
var sources = {
"languages": [
"ActionScript",
"AppleScript",
"Asp",
"Scheme"
],
"os": [
"Windows",
"Mac OS X",
"Chrome",
]
};