Jquery auto complete results appear as individual letters, not words - php

I'm using jquery to capture a users input in a text field and then display a dropdown of possible options.
The script calls a php page which searches and returns the results to the ajax request.
Where there are multiple values returned by PHP they appear like
["Site 4,"Site 2","Site 1","Site 6","Site 7","Site 0"]
A single value would appear like
["Site 4"]
What I get in my drop down is as follows (based on the single entry)
[
LINE
"
S
i
t
e
LINE
4
"
]
Where LINE is a separator between Site & 4 and the quotes and brackets are shown.
My Jquery is:
$('#site').autocomplete({
source: function( request, response ) {
$.ajax({
url : 'siteCheck.php?name=' + request.term,
success: function( data ) {
console.log (data)
response( $.map( data, function( item ) {
return {
label: item,
value: item,
data : item
}
}));
}
});
},
autoFocus: true,
minLength: 1,
select: function( event, ui ) {
$('#site').val(ui);
}
});
How do I get this to return the dropdown list as
Site 4
Site 2
Site 1
Site 6
Site 7
Site 0
and not individual letters !
Thanks

First of all: Is it a typo, that your json array has no closing " for the first element?
Second: according to the doc for autocomplete, source, would be sufficient to just pass the array as simple array, as you have it already. No need to transform it to something with label/value.
In the example of remote datasource, they just adding source: 'remoteScript.php'
So you could just use
$( '#site' ).autocomplete({
source: 'siteCheck.php?name=' + request.term,
autoFocus: true,
minLength: 1,
select: function( event, ui ) {
$('#site').val(ui);
}
});
EDIT:
Try to modify you server side script to accept term as GET parameter, then your URL can drop the part, with term added, as the autocomplete does it for you:
source: 'siteCheck.php', //should accept term as parameter

Related

JqueryUI autocomplete barcode scanner with delay on enter key press

I'm looking to use the skill_input field for accomplishing field to read from barcode scanner or to be used also keyboard incase the item doesn't have barcode to be scanned,
I have an issue, the barcode scanner usually scan code and do enter key(automatically configured)
So when i read code fast and click enter , already the list of items isn't been loaded yet,
It needs like 1 second to load the list , so im thinking in a way of delaying the enter key press
$(function() {
$("#skill_input").autocomplete({
source: "fetchData.php",
minLength: 3,
autoFocus: true,
select: function( event, ui ) {
//copy id and desc of the array (item)to another field
$("#code").val(ui.item.id);
$("#item_description").val(ui.item.value);
$("#skill_input").val("");
},
response: function( event, ui ) {
$("#skill_input").keydown(function(e) {
if(e.which == 13) {
setTimeout( function() {
if($("#skill_input").val().length>0) { // if not empty
insert_row();
}
}, 2000);
e.preventDefault();
}
}); // alert(event);
}
});
});

How to set Jquery Autocomplete to a specific value and display It's Label using a datasource of JSON objects

Background
So I have a table that is populated by a form. Each row can be edited by hitting a edit button. The Edit button opens the form that is populated. I need to auto fill the autocomplete so that the user can see one of His selected course.
How I Cheated
I'm using PHP and Codeigniter server side and am dynamically creating my form based on database. The labels and values are all produced from the Database and populate my JQuery Auto complete (a.k.a datasource variable below). From my controller I'm passing my value to the model and getting the Label from the DB. From there I'm passing it to my view and to my AutoComplete and setting the input value equal to the found label.
I feel dirty having done it this way. The inefficiency of this burns my eyes.
My Goal
I want to use the value that I've gotten and have the autocomplete select it and display it's label client side.
OR
I need to just display the label in the box so the user knows it's not a blank field.
Both options need to allow the user to modify the autocomplete box.
Existing Code
My code for the input looks like this:
<div class="row-start span-2">
<label for="course_code">Course Code </label>
</div>
<div class="row-end span-2">
<input id="course_code">
</div>
My script for the autocomplete looks like this:
<script>
function search_course_code(){
var datasource = [{"value":"1","label":"AAF100 - DL"},{"value":"2","label":"AAF101 - DL+web"},.....];
var searchboxid = "#course_code";
var searchresultid = "#CRSEINVID";
$(searchboxid).autocomplete({
source:datasource,
focus: function( event, ui ) {
$( searchboxid ).val( ui.item.label );
return false;
},
select: function(event,ui){
var UIvalue = ui.item.value;
var UIlabel = ui.item.label;
console.log(UIvalue);
console.log(UIlabel);
$( searchboxid ).val( ui.item.label );
use_search("#search1","#CRSEINVID",UIvalue,UIlabel ); return false;
}
});
};
function use_search(show_select,result_id,uivalue,uilabel){
//loads value to field that takes it's value
$(result_id).val(uivalue);
//Display course below search box
course = "<span>"+uilabel+"</span>";
$(show_select).html(course );
//stops the value from being shown in the search box
return false;
};
$( document ).ready(function() {
search_course_code();
});
</script>
I draw the value from a hidden input with a unique ID simply using JQUERY val() function.
What I've tried
Try 1
Setting value using:
$(searchboxid).val(hiddenInputValue);
Result: Value displayed not the label
Try 2
Using the autocomplete on create method I tried to overwrite the UI object and send it to the select.
ui.item={"value":"","label":""};
ui.item.value=$(hiddenInputValue).val;
this.select(ui);
Result: No observable change, no errors.
Try 3
$(searchboxid).autocomplete("select", hiddenInputValue);
Result:
Uncaught Error: cannot call methods on autocomplete prior to
initialization; attempted to call method 'select'
Try 4
Tried changing value using
$(searchboxid).val(hiddenInputValue);
and having change function detect it and set label with
$( searchboxid ).val( ui.item.label );
Result: Value loaded into input not label
Try 5
Tried Triggering the change function with this:
$("#<?php echo $id;?>").autocomplete("option","change").call(searchBox);
and then setting label. Based on the answer to:
jQuery AutoComplete Trigger Change Event
Result: empty UI object for change function,
Try 6
Tried Triggering the select function with this:
$("#<?php echo $id;?>").autocomplete("option","select",{value:hiddenInputValue}).call(searchBox);
and then using my current select function.
Result: Uncaught Error: undefined is not a function,
Ideas
Ideas 1:
I thought of using the value then searching through the datasource object to find associating label and then using:
$(searchboxid).val(label);
would this work? How would I do it?
Idea 2:
If the value of the input field is set to a value using:
$(searchboxid).val(label);
Would the change function detect it? Not detected used console.log function in change function to give feedback,
So after much research and trying to get this to work I discovered two problems:
that I was using Select2 version 3.5.3 and needed to use text instead of label and :
$myselect.select2("val","somevalue");
The MAJOR source of my problem though was because I was using Web Experience Toolkit tabs and I needed to load the Select 2 after tabs where initialized.
assign the value to the auto complete input element by using
$('#YourAutoCompletBox').val(yourValuefromHiddenControl);
html:
Topic: <input type="text" id="topics" /><input type="hidden" id="topicID" />
<br/><br/><br/><br/>
<p>You selected <span id="results"></span></p>
jQuery:
var topics= [
{
value: "cooking",
label: "Cooking",
id: "1"
},
{
value: "C++",
label: "C++",
id: "2"
},
{
value: "craftsmanship",
label: "Software Craftsmanship",
id: "3"
}
];
$(document).ready(function() {
$( "#topics" ).autocomplete({
minLength: 0,
source: topics,
focus: function( event, ui ) {
$( "#topics" ).val( ui.item.label );
return false;
},
select: function( event, ui ) {
$( "#topics" ).val( ui.item.label );
$("#topicID").val(ui.item.id);
$( "#results").text($("#topicID").val());
return false;
}
})
});
Playground : jsfiddle

Avoid multiple server calls, "self-filtering" JqueryUI autocomplete

Consider "Method A: no ajax":
$(function() {
var emails = [
"john#beatles.com",
"george#beatles.com",
"paul#beatles.com",
"ringo#beatles.com"
];
$( "#invitees" ).autocomplete({
source:emails
});
});
This is given a relatively small, "unfiltered" array. The autocomplete function filters it for you as you type. I want to fetch this data once, thereby only requiring one call to the database.
Consider "Method B: 'internal' URL:
$( "#invitees" ).autocomplete({
source:"/api/get/users"
});
This does not work as I expect it to. No matter what I type, the entire list is always there. Now, after research reading the docs, other S/O questions, and every example I can find- they usually conclude with something like this:
"Data should be filtered server side. The autocomplete widget adds the term parameter to the url, so the resulting url is something like: /search.php?term=whatityped
I can handle that, but that's not totally happening in "Method A", is it? For larger data sets, I get it: no need to pre-load 100,000 results. But in this case, I want the ability to run one query and be done with it. That way if a mobile user is standing in the desert with "one bar" of service, his phone won't lock up while the server repeatedly requests new data every time he types a letter, right?
When the request goes to the internal URL:'/api/get/users'... here's the relevant part of the PHP code:
function get($className,$param1="all",$param2=""){
//above parameters will be refactored...
$stmt=$this->db->prepare('SELECT username FROM users');
$stmt->execute();
$this->data=$stmt->fetchAll(PDO::FETCH_COLUMN);
echo json_encode($this->data);
}
That function returns:
["john#beatles.com","george#beatles.com","paul#beatles.com","ringo#beatles.com"]
So again, If I explicitly do this, the filtering works:
var emails = [
"john#beatles.com",
"george#beatles.com",
"paul#beatles.com",
"ringo#beatles.com"
];
$( "#invitees" ).autocomplete({
source:emails
});
but this does not:
$( "#invitees" ).autocomplete({
source:"/api/get/users"
});
What am I missing here?
PS: Here is an unpolished attempt at method C, by the way- "ajax callback":
(Note: it's meant to accept an associative array from PHP, but the point is that it also does not "self-filter")
$( "#invitees" ).autocomplete({
source: function(request,response){
$.ajax({
url:"/api/get/users",
dataType:"json",
data:{
maxRows:5, // ? does not work
//name_startsWith: request.term // ? does not work
},
error: function(xhr,status){
alert(status);
},
success: function (data){
// alert(data);
response($.map(data,function (item){
return{
label: item.username,
};
}));
}
});
}
});
//ensures autocomplete is not set to "off"
$('input[name=invitees]').attr('autocomplete','on');
For completeness, here's My HTML:
<label for="invitees">Invite by email: </label>
<input id="invitees" name="invitees"/>
You can put the autocomplete function inside a callback function and pass the return data into that.
An example:
$.getJSON('/myJSONdata', function(data) {
$( "#input_field" ).autocomplete({
source: data
});
});
This will assign the autocomplete function to the desired fields after the callback is complete and the data would be assigned just as if it were plain text written into the function.
The autocomplete function obviously won't work until the callback completes successfully so that is something that you might want to keep in mind.

jQuery full calendar $.ajax call issue ( using static events on page open )

So I am using Yii and full calendar as a widget which is called in a view of CalendarController. Uppon call for a widget, the widget retrives existing events from the DB and puts them inside the full calendar to display. Now I have also made a simple filter for filtering out events by category they are in ( dropdown with a submit ), so I want to send request to a calendarController method called actionEvents() which then takes what is passed to it ( the category of events for which we want to retrieve events ), gets them back to the jQuery which then calls the calendar again passing it a json_encode(d) array of needed properties to correctly render events under the selected category in the dropdown. The problem I have is that it seems fullcalendar is doing my wanted call ( POST ) as well as one another GET call along with it for some reason so it does return properly formatted json to the jQuery from the method of controller, but just shows an empty calendar without events in it on return. This is how the console looks like after the returned data.
This is the code that calls ajax call
$(document).ready(function() {
var date = new Date(),
d = date.getDate(),
m = date.getMonth(),
y = date.getFullYear();
$('form.eventFilter').submit(function() {
var selectedOption = $('form.eventFilter select').val(),
eventContainer = $('.fc-event-container');
var objectToSend = { "categories" : [selectedOption],"datefrom" : "september2013"/*month + "" + year*/ , "dateto" : "september2013"/*month + "" + year*/};
$.ajax({
url: '<?php echo Yii::app()->createUrl('calendar/events'); ?>',
type: "POST",
async:false,
data: {data : JSON.stringify(objectToSend)},
success: function(data) {
$('#fc_calendar').html('');
$('#fc_calendar').fullCalendar({
events: data
});
console.log(data);
},
error: function() {
console.log(data);
}
});
return false;
})
})
The code that renders initial calendar events on first page load ( open ) is this
<div id="fc_calendar"></div>
<script class="fc_calendar_script">
// gets calendar and its events working and shown
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#fc_calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
editable: true,
events: [
<?php foreach ($eventItems as $event): ?>
{
title: '<?php echo htmlentities($event['eventItems']['title']); ?>',
start: new Date(y,m,d + <?php echo $event['eventItems']['startdate_day_difference']; ?>),
end: new Date(y,m,d + <?php echo $event['eventItems']['enddate_day_difference']; ?>),
url: '<?php echo $event['eventItems']['url']; ?>',
className: [
<?php foreach($event['eventCategories'] as $category) { echo ''.json_encode($category['slug']).','; }?> // and categories slugs as classnames, same purpose
]
},
<?php endforeach; ?>
]
});
</script>
The code in controller is not that important since you can see what it returns in the screenshot :) If someone has an idea of how to get around this I would really be grateful :) Tried everything I know
Ok so bounty goes to whoever answers this question :)
I am having problems with full calendar month rendering when ajax data is returned and events populated. Since I have checkboxes for each category ( events have MANY_MANY relation with categories ) and each time a checkbox is checked or unchecked, JSON array of chosen categories of events is passed on to PHP method which queries DB for all events that go under chose categories and returns all events in a jquery encoded array to the view which then takes that events array and rerenders the calendar like shown in the upper code.
Problem is that when a checkbox is checked or unchecked and ajax returned the calendar always renders on the current month ( so right now it would always rerender itself to show events for september, untill the end of the month, then always for Ocbober and so on ), but what if a user was on lets say November 2013 when he checked event category for which he wanted to filter the events? The calendar would rerender on September still. How could I make it rerender on the month the user was on when he checked / unchecked a checkbox ?
The code that I have which keeps track ( or at least it should ) of the current month when prev or next month buttons are clicked is this
$('.fc-button-next span').click(function(){
start = $('#fc_calendar').fullCalendar('getView').visEnd;
console.log(start);
});
$('.fc-button-prev span').click(function(){
start = $('#fc_calendar').fullCalendar('getView').visStart;
console.log(start);
});
However this code is not tracking properly, sometimes it skips a month, sometimes it stays on the month without change and sometimes it returns propper month, which is bugging me so I cant call this function of the calendar properly which should set calendar to propper month on rerender.
$('#fc_calendar').fullCalendar('gotoDate', start);
I think what you might be looking for is something like
jQuery(function($){
$('form.eventFilter').submit(function() {
$('#fc_calendar').fullCalendar( 'refetchEvents' );
return false;
});
$('#fc_calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
editable: true,
events: function(start, end, callback) {
var selectedOption = $('form.eventFilter select').val(),
eventContainer = $('.fc-event-container');
//create the data to be sent
var objectToSend = {
"categories": [selectedOption],
"datefrom": start.getDate() + '-' + start.getMonth() + '-' + start.getYear(),
"dateto": end.getDate() + '-' + end.getMonth() + '-' + end.getYear()
};
//use jsonp based jQuery request
$.ajax({
url: 'events.json',
data: objectToSend,
cache: false
}).done(function(data){
//on success call `callback` with the data
callback(data)
})
}
});
});
Demo: Plunker
Note: The date param formatting and jsonp is not used here, you will have to change it to match your requirements
I see that you use JSON.stringify(data); this is what i tought your error was
maybe you need a jsonp, and below you have my example
$.ajax({
'url': 'http://domain.com/index.php/api/news?callback=?',
'data': {'data': JSON.stringify(data), callback: 'jsonPCallback'},
'success': function(data) {
// console.log(data);
},
jsonpCallback: jsonPCallback,
dataType: 'jsonp'
});
function jsonPCallback(cbdata){
console.log('callback2')
// console.log(cbdata);
return false;
}
now, do you also use something like
echo $_GET['callback'].'('.CJSON::encode(array('status_live' => 1, 'data' => $data_decoded)).')';
in the controller to return the results ?
also, createUrl might be wrong, because you need a absolute path
Actualy the problem solution is as weird as the problem itself and it is the following. You must use designated way of doing an ajax call to fetch json that is in the plugin documentation, any other way you send your own call ( GET or POST ) and the calendar after that makes yet another call ( hence the another GET call ) if you are using just a "regular" $.ajax, $.post or $.get call using jQueries native functionality
This should really be posted somewhere on the website in some section so that people do not get confused why their calendar is not making ajax calls and I wonder how noone else had similar problem before . So this is the "correct" documentation way of calling it with full calendar which you can find HERE
$('#fc_calendar').html('');
$('#fc_calendar').fullCalendar({
eventSources: [
// your event source
{
url: '?r=calendar/events',
type: 'POST',
data: { data : JSON.stringify(objectToSend)},
error: function(data) {
alert(data);
},
}
// any other sources...
]
});
So it will automaticly fetch any returned ( properly formatted data ) and use it to rerender new calendar with those events. It is very weird way of doing it, but the only way that will work.
I can't comment so, you have an assignment to variable:"nothing" in your last query parameter
double check if you have looked for ajax request in your controller(important!),
and also if this is this a 404 by the apache, you have url rewriting problems,
and it looks like index.php is missing from url?!

kendoAutoComplete for multiple dataTextField

The code below works for autocomplete for FileNo (field) only. i want this function to work for other attributes of employee too. i.e FirstName, LastName
dataTextField: "FileNo" <---------------- here dataTextField gets sing field. how could it be for multiple fields?
Since you are the one that knows on which columns want to search, my recommendation is:
Implement index.php/hr_management/manage_hr/search_employee/ in such way that is able to do the search for any of the columns that you want (FileNo, FirstName, LastName...).
This service will return three columns (at least) providing an id, column name on which you found the match and match value.
match value is used for displaying values in the autocomplete.
Once selected value on autocomplete use the column name and match value for filtering on the grid.
You should use template to change what is displayed in the dropdownlist of the autocomplete. Then the dataTextField will only be used inside the input element.
Here is how it goes to create template.
Kendo Autocomplete has dataTextField that accepts a field name(e.g. employeeID, employeeName etc. of a datasource ) to use for filtering items.
To use multiple fields, you have to set one of the fields to hold concatenated fields during parsing of datasource in your schema as given below.
Then set your filter of AutoComplete to "contains"
I did it as follows.
var myDataSrc = new kendo.data.DataSource({
transport: {
read: {
type:"GET",
url:clientDataURL,
dataType: "jsonp",
contentType: "application/json",
}
},
schema: {
parse: function(clntDB) {
$.each(clntDB, function(ky, clnt) {
clnt.firstName = clnt.clientUID + " | " + clnt.firstName+ " " + clnt.lastName;
});
return clntDB;
}
},
pageSize: 4 // Number of Items to show during input
});
/// See the firstName above it's reconstructed to hold concatenated lastname , ID and firstname string.
Next step is to use parsed firstName as a value of dataTextField of kendo Autocomplete.
Then
var selectedClntID; //// Actually, this aims at getting the ID for future use
$("#YOURSEARCHINPUTID").kendoAutoComplete({
dataSource: myDataSrc ,
template: tmplSrchdClnt, // YOUR TEMPLATE like "<div>firstName</div>"
dataTextField:"firstName",
filter:"contains", /// DON'T FORGET TO ADD THIS
minLength : 1 ,
select: function(e) {
var selectedClnt = this.dataItem(e.item.index()),
x = kendo.stringify(selectedClnt);
selectedClntID = JSON.parse(x);
}
// headerTemplate: '<div><h2>ID - LastName</h2></div>'
});
However, tough to find resource indicating like this, it's awesome when you see it working.This is engine of my project when it comes to autocompletion. I did it this way.
Alternatively, you can convert to
data = new Employee(firstname, lastname, ID); // on client side
function Employee( firstname, lastname, ID ){
this.filterStr = firstname + ""+lastname+" "+ID;
}
give data to kendo AutoComplete dataSource and use filterStr as dataTextField.
Another code example adding a new field to the datacourse to use as dataTextField.
// Build our data source object.
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: readUrl,
}
},
group: {field: "region"},
schema: {
data: function(response) {
$.each(response, function(k, v) {
response[k].searchString = v.airport + " " + v.iataCode;
});
return response;
}
}
});
$(selector).kendoAutoComplete({
dataTextField: "searchString",
filter: "contains",
template: '<span class="k-state-default">#: data.airport # (#: data.iataCode #)</span>',
height: 400,
dataSource: dataSource,
});

Categories