I trying to create a multifunctional search bar, where one can not only look for cities (using Geonames) but also using the same input field for finding signed up users (using my MYSQL table.
I managed to achieve both seperately, however I couldn't manage to merge the code together.
The JQuery code for the geoname autocomplete:
$(function() {
$( "#top_search_field" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://api.geonames.org/searchJSON?username=dummie",
dataType: "jsonp",
data: {
featureClass: "P",
style: "full",
country: "AT",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) {
response( $.map( data.geonames, function( item ) {
return {
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
value: item.name
}
}));
}
});
},
minLength: 2,
select: function (event, ui) {
var selectedObj = ui.item;
jQuery("#top_search_field").val(selectedObj.value);
return false;
},
open: function () {
jQuery(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
jQuery(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
});
The code for grabbing the users from the table:
$(function() {
$( "#top_search_field" ).autocomplete({
source:'php_includes/search.php',
minLength: 2,
open: function () {
jQuery(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
jQuery(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
})
});
search.php
include_once("db_connect.php");
$stmt = $db_connect->query("SELECT user_auth, first_name, last_name, avatar FROM users WHERE (first_name LIKE '%".$_REQUEST['term']."%' OR last_name LIKE '%".$_REQUEST['term']."%') ");
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = array('label' => utf8_encode($row['first_name'].' '. $row['last_name'] ) );
}
echo json_encode($results);
What is the best way to merge the codes together and make it possible to look for both cities and users?
You need to do a service for getting information from multiple service, combine them and respond to your autocomplete result. Let say you have a service called advanced_search.php. In this file;
<?php
$keyword = $_GET["keyword"];
$result = array();
$usersReturnedFromService = getUsersFromService($keyword); // Get users from service by using curl
foreach ($usersReturnedFrom as $user) {
array_push(array("type" => "user", "value" => $user));
}
$geoNamesReturnedFromService = getGeoNamesFromService($keyword); // Get geonames from service by using curl
foreach ($geoNamesReturnedFromService as $geoname) {
array_push(array("type" => "geoname", "value" => $geoname));
}
// When you sort, result will mixed
function compareArr($a, $b){
$ad = strtotime($a['value']);
$bd = strtotime($b['value']);
return ($ad-$bd);
}
usort($result, 'compareArr');
echo json_encode($result);
And in js side;
$(function() {
$( "#top_search_field" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "advanced_search.php?keyword=" + request.term, // put other variables here. I have only put term
success: function( data ) {
response( $.map( data, function( item ) {
return {
label: item.value, // john
value: item.type + "|" + item.value // user|john
}
}));
}
});
},
minLength: 2,
select: function (event, ui) {
var selectedObj = ui.item;
jQuery("#top_search_field").val(selectedObj.value);
return false;
},
open: function () {
jQuery(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
jQuery(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
});
Related
I have a problem with my code. I receive data via ajax and it works, but the problem is that when I try to search for an element and all the elements appear so the search does not work properly.
JS code :
let marque_id =$("#marque_id").val();
$( "#grp_name" ).autocomplete({
source: function( request, response ) {
$.ajax({
url:"abonne/ajax_get_grp_autorisation",
method:"POST",
dataType: "json",
data: {
marque_id : id_marque
},
success: function( data ) {
response( data );
console.log(data);
}
});
},
select: function (event, ui) {
// Set selection
$('#grp_name').val(ui.item.label); // display the selected text
$('#id_grp_selected').val(ui.item.id); // save selected id to input
return false;
}
});
PHP code :
$data = array();
while($line = mysqli_fetch_object($liste_grp) ){
$data[] = array("label"=>$line->grp_nom,"value"=>$line->grp_nom ,"id"=>$line->groupement_id);
}
echo json_encode($data);
result
you should send the text you are searching for to ajax request so your autocomplete function should be
let marque_id =$("#marque_id").val();
$( "#grp_name" ).autocomplete({
source: function( request, response ) {
$.ajax({
url:"abonne/ajax_get_grp_autorisation",
method:"POST",
dataType: "json",
data: {
marque_id : id_marque ,
term: request.term
},
success: function( data ) {
response( data );
console.log(data);
}
});
},
select: function (event, ui) {
// Set selection
$('#grp_name').val(ui.item.label); // display the selected text
$('#id_grp_selected').val(ui.item.id); // save selected id to input
return false;
}
});
request.term is your search text and in your example it is group text
and also you need to modify your mysql query and add condition (like)
for example
$rs = mysql_query("SELECT * FROM table WHERE colum LIKE '%" . $_POST['term'] . "%'");
and finally you can check https://jqueryui.com/autocomplete/#remote-jsonp
I would advise the following jQuery:
$( "#grp_name" ).autocomplete({
source: function(request, response) {
$.ajax({
url:"abonne/ajax_get_grp_autorisation",
method:"POST",
dataType: "json",
data: {
marque_id: request.term
},
success: function( data ) {
console.log(data);
response(data);
}
});
},
select: function (event, ui) {
// Set selection
$('#grp_name').val(ui.item.label); // display the selected text
$('#id_grp_selected').val(ui.item.id); // save selected id to input
return false;
}
});
This is a small change. This will send the request.term to your PHP Script. For example, if the user types "gro", this will be sent to your script and would be accessed via:
$_POST['marque_id']
This would assume your SQL Query is something like:
$stmt = $mysqli->prepare("SELECT * FROM table WHERE column LIKE '?%'");
$stmt->bind_param("s", $_POST['marque_id']);
$stmt->execute();
$liste_grp = $stmt->get_result();
$data = array();
while($line = $liste_grp->fetch_assoc()) {
$data[] = array(
"label" => $line['grp_nom'],
"value" => $line['grp_nom'],
"id" => $line['groupement_id']
);
}
$stmt->close();
header('Content-Type: application/json');
echo json_encode($data);
This uses the MySQLi Prepared Statement, and will help prevent SQL Injection. I also included the JSON Header as good practice. The result of search "gro" would be something like:
[
{
"label": "GROUPE DATAPNEU TEST",
"value": "GROUPE DATAPNEU TEST",
"id": 1
}
];
Thanks guys i found a solution it works better
i used tokeninput with many options
http://loopj.com/jquery-tokeni
$.ajax({
url:"ajax_get_societe_authorisation",
method:"POST",
scriptCharset: "iso-8859-1",
cache: false,
dataType: "json",
data: {
marque_id : id_marque
},
success: function( data ) {
console.log(data);
$("#soc_name").tokenInput(data
,{
tokenLimit: 1,
hintText: "Recherche une société par son nom",
noResultsText: "Aucune société trouvé",
searchingText: "Recherche en cours ...",
onAdd: function (data) {
$("#soc_id").val(data.id);
},
onDelete: function (item) {
$("#soc_id").val("");
}
}
);
}
});
I am trying to populate multiple fields with jQuery from user input in one form but I'm not getting any result in JSON. Can anyone spot what the problem is?
$('#countryname_1').autocomplete({
source: function( request, response ) {
$.ajax({
url : 'search.php',
dataType: "json",
data: {
name_startsWith: request.term,
type: 'country_table',
row_num : 1
},
success: function( data ) {
response( $.map( data, function( item ) {
var code = item.split("|");
return {
label: code[0],
value: code[0],
data : item
}
}));
}
});
},
autoFocus: true,
minLength: 0,
select: function( event, ui ) {
var names = ui.item.data.split("|");
$('#country_no_1').val(names[1]);
$('#phone_code_1').val(names[2]);
$('#country_code_1').val(names[3]);
}
});
The PHP I'm using to query the database
require ($_SERVER['DOCUMENT_ROOT'].'/config/dbconnect.php');
if(isset($_POST['type']) == 'country_table'){
$result = $db->prepare("SELECT firstname, department FROM users where firstname LIKE '".strtoupper($_POST['name_startsWith'])."%'");
$data = array();
while ($row->fetch(PDO::FETCH_ASSOC)){{
$name = $row['firstname'].'|'.$row['department'].'|'.$row_num;
array_push($data, $name);
}
echo json_encode($data);
}
}
Nothing appears in the form and Chrome shows that no data is being passed back
I have this live search and it works perfectly. What i want to do is I want to get another field. Aside of fetching indcator name i also want to get its ID by assigning it to another input type once I clicked the indicatorname using live search.
Heres the Script :
<script type="text/javascript">
$(document).ready(function() {
$('#indicatorname').autocomplete({
source: function( request, response ) {
$.ajax({
url : 'ajax.php',
dataType: "json",
data: {
name_startsWith: request.term,
type: 'indicatorname'
},
success: function( data ) {
response( $.map( data, function( item ) {
return {
label: item,
value: item
}
}));
}
});
},
autoFocus: true,
selectFirst: true,
minLength: 0,
focus : function( event, ui ) {
$('#indicatorname').html(ui.item.value);
},
select: function( event, ui ) {
$('#indicatorname').html(ui.item.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top");
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
$('#slider').rhinoslider({
effect: 'transfer'
});
});
</script>
Heres the ajax.php :
<?php
$connection = pg_connect("host=localhost dbname=brgy_profiler
user=postgres password=password");
if (!$connection)
{
echo "Couldn't make a connection!";
}
?>
<?php
if($_GET['type'] == 'indicatorname'){
$result = pg_query("SELECT cindicatordesc,nindicatorid from
tbl_indicators where cindicatordesc LIKE
'%".$_GET['name_startsWith']."%'");
$data = array();
while ($row = pg_fetch_array($result))
{
array_push($data, $row['cindicatordesc']);
}
echo json_encode($data);
}
?>
Here's my tbl_indicator :
How can i get also the nindicatorid field and get it together with cindicatordesc using ajax live search?
Note: Only cindicatordesc will be displayed and nindicatorid will be save in an input type.
Not a problem. You can add additional data attributes in your Auto-complete select return as,
$('#indicatorname').autocomplete({
source: function( request, response ) {
...........
success: function( data ) {
response( $.map( data, function( itemList ) {
return {
label: itemList.label,
value: itemList.value,
extraField : itemList.extraField
}
}));
So, Only change you need to accommodate is the Server side where you need to send the extra values to the Auto-complete AJAX.
And , On select event you can fetch the value as ui.item.extraField.
Here is a Sample Demo of using multiple attributes. Although it is not same as you have done, the inner logic is the same.
I'm using this jquery plugin : JQuery Autocomplete. Problem I'm getting json data but it's not appearing on the autocomplete list.
The JQuery code:
$( "#student-id" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "ajax/ajax_admin.php?auto_student=" + $( "#student-id" ).val(),
dataType:"json",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) {
response( $.map( data.students, function( item ) {
return {
label: item.id +" , "+ item.name,
value: item.id
}
}));
}
});
},
minLength: 2,
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
The PHP Script is :
public function load_ajax_student_list($val)
{
$val = "%".$val."%";
$stmt = $this->conn->prepare("select * from student where studentAiubId like :value limit 0,5");
$stmt->bindValue(':value', $val);
$stmt->execute();
if($stmt->rowCount() < 1)
echo "";
else
{
$result = $stmt->fetchAll();
$output = array();
foreach($result as $row)
{
if($row['mname']=="")
$name = $row['fname']." ".$row['lname'];
else
$name = $row['fname']." ".$row['mname']." ".$row['lname'];
$data["name"] = $name;
$data["id"] = $row['studentAiubId'];
$output["students"][] = $data;
}
echo json_encode($output);
}
}
If the call goes like this: ajax/ajax_admin.php?auto_student=10
The produced data from PHP script is :
{
"students": [
{"name":"Moh Mamun Sardar","id":"10-15987-1"},
{"name":"Rehan Ahmed","id":"10-12451-2"},
{"name":"Abid Hassan","id":"10-15412-1"},
{"name":"Abir Islam","id":"10-11245-1"}
]
}
But Nothing showing on autocomplete. What I'm doing wrong?
try something like this
$.map( data.students, function(item ) {
return {
label: item.name,
value: item.id
});
it is minlength not minLength see casing
You have forgotten the "appendTo" property. In this propery you have to specify the selector of the element you wish the information to be appended to like this
appendTo: '.class' or appendTo: '#id'
You have to add this property to the initialization of the autocomplete as a sibling of source and etc ...
I need an example of how to code a jQuery autocomplete to populate product_id while showing the product_name calling an ajax page "remote.php"
<input name="product_name" id="product_name" type="text" value="" />
<input name="product_id" id="product_id" type="hidden" value="" />
remote.php:
$partial = addslashes($_POST['partial_search']);
$myDataRows = array();
$result = mysql_query ("SELECT product_id, product_name FROM products
WHERE product_name like "%$partial%");
while ($row = mysql_fetch_row($result)) {
array_push($myDataRows, $row);
}
$ret = json_encode ($myDataRows);
echo $ret;
I'm not sure how to code the jQuery autocomplete and if I need to change remote.php
thanks
ADDED LATER:
I worked out another solution:
<script type="text/javascript">
function nqi_search (type, id_name, text_name)
{
$( "#"+text_name ).autocomplete({
source: "remote.php?&t="+type,
minLength: 1,
select: function( event, ui ) {
$( "#"+id_name ).val(ui.item.id );
}
});
}
</script>
<script type="text/javascript">
jQuery(document).ready(function() {
nqi_search ("product_search", "product_id", "product_name");
// also you can have many on one page with:
nqi_search ("vendor_search", "vendor_id", "vendor_name");
});
</script>
There's one problem. it doesn't seem to work if the nqi_search function is put into a .js file. I have no idea why?
This is how I do it:
Note, I've coded a special feature where the json can flag an item as a message instead and in this way you can put messages in the list (eg I put a "Addition X items not shown" for long lists). To use the message feature, but the text in the label field and a true boolean for the message field.
To use this on the page I just have
setupAutocomplete(<id of textbox>,<path to service>);
$.ajaxSetup({
type: "POST",
contentType: "application/json; charset=utf-8",
data: "{}",
dataFilter: function(data) {
var msg;
if (typeof (JSON) !== 'undefined' && typeof (JSON.parse) === 'function')
msg = JSON.parse(data);
else
msg = eval('(' + data + ')');
if (msg.hasOwnProperty('d'))
return msg.d;
else
return msg;
},
error: function(msg) {
$('#error').html(msg.responseText)
}
});
// remove this to get rid of custom message handling
$.widget("custom.redcomplete", $.ui.autocomplete, {
_renderMenu: function(ul, items) {
var self = this;
$.each(items, function(index, item) {
if (item.message)
ul.append("<li class='ui-menu-item special-red'> " + item.label + "</li>");
else
self._renderItem(ul, item)
});
}
function setupAutocomplete(inID, inURL) {
var myTB = $("[id$='_" + inID + "']");
// change redcomplete to autocomplete to get rid of message handling
myTB.redcomplete({
source: function(request, response) {
$.ajax({
url: inURL,
data: "{'filter': '" + request.term + "'}",
success: function(data) {
response($.map(data, function(item) {
return {
label: item.text,
value: item.id,
// remove this line and the , above to get rid of message handling
message: item.message
};
}));
}
})
},
delay: 500,
minLength: 3,
focus: function(event, ui) {
myTB.val(ui.item.label);
return false;
},
select: function(event, ui) {
// action for the select here.
return false;
},
open: function() {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function() {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});