autocomplete suggest from multiple columns and prevent duplicate - php

I want autocomplete value from two columns of MySql database table, One column have multiple similar values, In autocomplete window in case of similarity it should only display one of the similar values. And after select it should not be suggested in autocomplete window in next row.
HTML
<tr>
<td><input type="text" data-type="aTeam" id="team_1" class="team"></td>
<td><input type="text" id="score_1" ></td>
</tr>
<button type="button" id="addRow">Add Row</button>
JS
$(document).on('focus','.team',function(){
var type = $(this).data('type');
if(type ==='aTeam' )autoTypeNo= 0;
$(this).autocomplete({
source: function( request, response ) {
$.ajax({
url : 'fetch.php',
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: type
},
success: function( data ) {
response( $.map( data, function( item ) {
return {
label: item.aTeam,
value: item.aTeam,
data : item
};
}));
}
});
},
autoFocus: true,
minLength: 1,
select: function( event, ui ) {
id_arr = $(this).attr('id');
id = id_arr.split("_");
$('#team_'+id[1]).val(ui.item.data.aTeam);
$('#score_'+id[1]).val(ui.item.data.score);
}
});
});
//add row
var i=$('table tr').length;
$("#addRow").on('click',function(){
html = '<tr>';
html += '<td><input type="text" data-type="aTeam" id="team_'+i+'" class="team"></td>';
html += '<td><input type="text" id="score_'+i+'"></td>';
html += '</tr>';
$('table').append(html);
i++;
});
PHP
<?php
require_once("config.php");
if(!empty($_POST['type'])){
$type = $_POST['type'];
$name = $_POST['name_startsWith'];
$query = $db->prepare("SELECT aTeam, bTeam FROM teams where UPPER($type) LIKE '".strtoupper($name)."%' limit 10 ");
$query->execute();
$data= array();
$i = 0;
while ($row = $query->fetch(PDO:: FETCH_ASSOC)) {
$data[$i]['aTeam'] = $row['aTeam'];
$data[$i]['bTeam'] = $row['bTeam'];
$data[$i]['score'] = $row['score'];
++$i;
}
echo json_encode($data);
}

Try this: (read the // {comment here} and just compare the code with yours to see what changed)
$(document).on('focus','.team',function(){
let type = $(this).data('type');
// `autoTypeNo` isn't used anywhere, so I commented out this.
//if(type ==='aTeam' )autoTypeNo= 0;
$(this).autocomplete({
source: function( request, response ) {
$.ajax({
url : 'fetch.php',
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: type
},
success: function( data ) {
let selected = [],
uniques = [],
choices = [];
$('tr .team[id^="team_"]').each(function(){
let value = this.value.trim().toLowerCase();
if (value && selected.indexOf(value) < 0) {
selected.push(value);
}
});
data.forEach(item => {
let value = item.aTeam.trim().toLowerCase(),
value2 = item.bTeam.trim().toLowerCase();
if (uniques.indexOf(value) < 0 && selected.indexOf(value) < 0) {
choices.push({
label: item.aTeam,
value: item.aTeam,
data: item,
type: 'aTeam'
});
uniques.push(value);
}
if (uniques.indexOf(value2) < 0 && selected.indexOf(value2) < 0) {
choices.push({
label: item.bTeam,
value: item.bTeam,
data: item,
type: 'bTeam'
});
uniques.push(value2);
}
});
response(choices);
}
});
},
autoFocus: true,
minLength: 1,
select: function( event, ui ) {
// Strips the 'team_' part, leaving just the number.
let id_num = $(this).attr('id').substring(5);
$(this).val(ui.item.value);
$('#score_' + id_num).val(ui.item.data.score);
$(this).attr('data-type', ui.item.type); // Change to the correct type?
// Cancels default action, so that the above `jQuery.val()` call works.
return false;
}
});
});
//add row
// 'i' is too generic, so I renamed it to 'row_num'.
var row_num=$('table tr').length;
$("#addRow").on('click',function(){
// Increment before used.
row_num++;
let html = '<tr>';
html += '<td><input type="text" data-type="aTeam" id="team_' + row_num + '" class="team"></td>';
html += '<td><input type="text" id="score_' + row_num + '"></td>';
html += '</tr>';
$('table').append(html);
// Optional, but I like to focus on the `input` in the row that was just added.
$('#team_' + row_num).select();
});
UPDATE
I updated the JS code (above).
And note that for the PHP part, I changed the $query from:
$query = $db->prepare("SELECT aTeam, bTeam FROM teams where UPPER($type) LIKE '".strtoupper($name)."%' limit 10 ");
to:
$query = $db->prepare("SELECT aTeam, bTeam, score FROM teams where ( aTeam LIKE '".$name."%' OR bTeam LIKE '".$name."%' ) limit 10 ");
because without the OR bTeam LIKE '".$name."%', for example if you typed "d" and there were no aTeam starting with "d", then you know what would happen..

Related

jQuery Ajax Request fails to bring all data with SQL Query to fields

i have a form that works by filling the next select fields with data based on the previous ones, it works perfect on Localhost / Xampp with PHP8 but now when i try to get it on my server it only works "once" per category.
My problem simplified.
I select category1 and get two results based on that to the next select
Only one of these results works with returning data to the 3rd Select and the other one doesn't return anything with json_encode and only throws an error
More info:
Request that works.
{
"request": "2",
"subcategoryid": "11",
"alakategoriaID": "15"
}
[
Response which is correct.
{
"ID": "23",
"name": "Puu 25"
},
{
"ID": "24",
"name": "Puu 50"
}
Request that doesn't return anything
{
"request": "2",
"subcategoryid": "10",
"alakategoriaID": "15"
}
Main function that contains the select fields etc..
´´´<script>
$(function () {
// Country
$('#sel_country').change(function () {
var categoryID = $(this).val();
// Empty state and city dropdown
$('#sel_state').find('option').not(':first').remove();
$('#sel_city').find('option').not(':first').remove();
$('#varichanger').find('option').not(':first').remove();
// AJAX request
$.ajax({
url: 'helper.php',
type: 'post',
data: {
request: 1,
categoryID: categoryID
},
dataType: 'json',
success: function (response) {
var len = response.length;
for (var i = 0; i < len; i++) {
var id = response[i]['id'];
var name = response[i]['name'];
$("#sel_state").append("<option value='" + id + "'>" + name + "</option>");
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("some error");
}
});
$.ajax({
url: 'helper.php',
type: 'post',
data: {
request: 3,
categoryID: categoryID
},
dataType: 'json',
success: function (response) {
var len = response.length;
for (var i = 0; i < len; i++) {
var id = response[i]['id'];
var name = response[i]['name'];
$("#varichanger").append("<option value='" + id + "'>" + name + "</option>");
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("some error");
}
});
});
// State
$('#sel_state').change(function () {
var subcategoryid = $(this).val();
var alakategoriaID = $('#sel_country').val();
// Empty city dropdown
$('#sel_city').find('option').not(':first').remove();
// AJAX request
$.ajax({
url: 'helper.php',
type: 'post',
data: {
request: 2,
subcategoryid: subcategoryid,
alakategoriaID: alakategoriaID
},
dataType: 'json',
success: function (response) {
console.log(response);
var len = response.length;
for (var i = 0; i < len; i++) {
var id = response[i]['ID'];
var name = response[i]['name'];
$("#sel_city").append("<option value='" + id + "'>" + name + "</option>");
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("some error");
}
});
});
});
</script>´´´
Helper.php
include "pdoconfig.php";
error_reporting(0);
$request = 0;$request = 0;
if(isset($_POST['request'])){
$request = $_POST['request'];
}
// Fetch subcategory list by categoryID
if(trim($request) == 1){
$categoryID = $_POST['categoryID'];
$stmt = $conn->prepare("SELECT * FROM alakategoriat WHERE kategoriaID=:kategoriaID ORDER BY subcategoryname");
$stmt->bindValue(':kategoriaID', (int)$categoryID, PDO::PARAM_INT);
$stmt->execute();
$subcategorysList = $stmt->fetchAll();
$response = array();
foreach($subcategorysList as $subcategory){
$response[] = array(
"id" => $subcategory['id'],
"name" => $subcategory['subcategoryname']
);
}
echo json_encode($response);
exit;
}
// Fetch city list by subcategoryid
if(trim($request) == 2){
$kategoriaID = $_POST['alakategoriaID'];
$alakategoriaID = $_POST['subcategoryid'];
$stmt = $conn->prepare("SELECT * FROM tuotteet
WHERE kategoriaID=$kategoriaID
AND alakategoriaID=$alakategoriaID
ORDER BY productname");
$stmt->execute();
$productslist = $stmt->fetchAll();
$response = array();
foreach($productslist as $product){
$response[] = array(
"ID" => $product['ID'],
"name" => $product['productname']
);
}
echo json_encode($response);
exit;
}
if(trim($request) == 3){
$categoryID = $_POST['categoryID'];
$stmt = $conn->prepare("SELECT *
FROM kategoriavarit
INNER JOIN varit ON kategoriavarit.variID = varit.variID
WHERE kategoriaID=:kategoriaID");
$stmt->bindValue(':kategoriaID', (int)$categoryID, PDO::PARAM_INT);
$stmt->execute();
$varilist = $stmt->fetchAll();
$response = array();
foreach($varilist as $vari){
$response[] = array(
"id" => $vari['variID'],
"name" => $vari['varinimi']
);
}
echo json_encode($response);
exit;
}
you have to save your first category value to session and use it for second time ajax call. As per your code you always get
trim($request) == 1
because each time ajax call it consider as new request. So use session or cookie for store and use parent category.
Solved the problem by clearing and reinserting my database values and following #Foramkumar Patel's answer
EDIT: Cancel that, problem was with scandinavian letters in the response from JSON causing many different problems, solved the problem by utf_8 encoding the response.

delete records from store with checkbox selection

I have this ajax request that iterates through a store and deletes all selected records.
code
Ext.Ajax.request({
url: 'system/index.php',
method: 'POST',
params: {
class: 'LicenseFeatures',
method: 'delete',
data: Ext.encode({
feature_id: ( function(){
var e = "";
var sel = Ext.getCmp('featureGrid').getSelection();
var c = 0;
for( var i in sel ) {
var x = ( c == 0 ) ? e = sel[i].data.feature_id : e += "," + sel[i].data.feature_id;
c++;
}
return e;
})()
})
},
success: function( response ){
Ext.MessageBox.alert( 'Status', 'Record(s) has been deleted.' );
Ext.getStore('LicenseFeaturesStore').reload();
},
failure: function(){
Ext.MessageBox.alert( 'Status', 'Failed to delete records.' );
}
});
Currently the code retrieves 1 id from the grid and deletes it. What I need to do is get two Id's from the grid as I need to run a specific sql to the database. The sql needs two inputs, here is the sql
public function delete( $vars ){
$sql = "DELETE FROM `LicenseFeatures` WHERE feature_id in({$vars->data->feature_id}) AND license_id in({$vars->data->license_id})";
if( $result = $vars->db->query( $sql ) ) {
echo json_encode( array( "success" => true,"sql"=>$sql ) );
} else {
echo json_encode( array( "success" => false ) );
}
}
Try and change the data property to this.
data: Ext.encode(( function(){
var feature_id,
licence_id;
var sel = Ext.getCmp('featureGrid').getSelection();
var c = 0;
for( var i in sel ) {
if (c == 0) {
feature_id = sel[i].data.feature_id;
licence_id = sel[i].data.licence_id;
} else {
feature_id += "," + sel[i].data.feature_id;
licence_id += "," + sel[i].data.licence_id;
}
c++;
}
return {
feature_id: feature_id,
licence_id: licence_id
};
})())

Error when JSON array is echoed back to AJAX script

I have a text box where I search database for a specific information.
The PHP code when I just type and click on search is the following:
try
{
$date_emp = $_POST['date_emp'];
$val = $_POST['data1'];
$gender = $_POST['gen'];
if($date_emp == "choose" && $gender == "specify")
{
$search = "SELECT * FROM employee
WHERE emp_name = :val OR position = :val
OR salary = :val OR date_employed = :val
OR gender = :val";
$searchStmt = $conn->prepare($search);
$searchStmt->bindValue(":val", $val);
$searchStmt->execute();
$res = $searchStmt->fetchAll();
echo json_encode($res);
}
catch(PDOException $ex)
{
echo $ex->getMessage();
}
And here the AJAX script for it:
$("#search").click(function()
{
var txt = $("#txtSearch").val();
var drop = $("#date_employed").val();
var gender = $("#sex").val();
//console.log(txt);
if(txt == '' && drop == "choose" && gender == "specify")
{
$("#txtSearch").css('border-color', 'red');
}
else
{
if(drop == "choose" && gender == "specify")
{
$.ajax
({
url: 'search.php',
type: 'POST',
data: {data1: txt, date_emp: drop, gen: gender},
dataType: 'JSON',
success:function(res)
{
$("#myTable tr").remove();
$("#myTable").append("<tr><th>Name</th><th>Position</th><th>Salary</th><th>Date</th><th>Gender</th></tr>");
$.each( res, function(key, row){
$("#myTable").append("<tr><td>"+row['emp_name']+"</td><td>"+row['position']+"</td><td>"+row['salary']+"</td><td>"+row['date_employed']+"</td><td>"+row['gender']+"</td></tr>");
});
},
error:function(res)
{
alert("Something Wrong");
}
});
}
$("#date_employed, #sex").change(function()
{
var txt = $("#txtSearch").val();
var drop = $("#date_employed").val();
var gender = $("#sex").val();
$.ajax({
url: 'search.php',
type: 'post',
data: {data1: txt, date_emp: drop, gen: gender},
datatype: 'json',
success:function(res)
{
$("#myTable tr").remove();
$("#myTable").append("<tr><th>Name</th><th>Position</th><th>Salary</th><th>Date</th><th>Gender</th></tr>");
$.each( res, function(key, row){
$("#myTable").append("<tr><td>"+row['emp_name']+"</td><td>"+row['position']+"</td><td>"+row['salary']+"</td><td>"+row['date_employed']+"</td><td>"+row['gender']+"</td></tr>");
});
},
error:function(res)
{
alert("Couldn't find any data!");
}
});
});
}
});
WHERE gender and drop are 2 drop lists that forming a search filters
When I change one of the drop lists, per example, when I choose the date equal to: this week I should see in table 2 rows.
But I can only see them in the network (in devTool), and at console tab I see the following error:
Uncaught TypeError: Cannot use 'in' operator to search for 'length' in
[{"id":"48","0":"48","emp_name":"Alexa","1":"Alexa","position":"Secretary","2":"Secretary","salary":"8000","3":"8000","date_employed":"2016-02-23","4":"2016-02-23","gender":"female","5":"female"}]
The PHP code when I change drop lists is:
if($date_emp == "week" && $gender == "specify")
{
$search = "SELECT * FROM employee WHERE (emp_name = :val OR position = :val
OR salary = :val OR date_employed = :val
OR gender = :val) AND date_employed > DATE_SUB(NOW(), INTERVAL 1 WEEK)";
$searchStmt = $conn->prepare($search);
$searchStmt->bindValue(":val", $val);
$searchStmt->execute();
$res = $searchStmt->fetchAll();
echo json_encode($res);
}
When you make an ajax call and expect the response to be a json you need to send a json header from the PHP
header('Content-Type: application/json');
echo json_encode($data);
Sending the json header from the PHP will turn the "res" param in your ajax to a json object and not a json string.
If you don't send the the header you need to parse the json string into a json object
var json = JSON.parse(res);

Select multiple rows into array and send them via AJAX

I am trying to run a SELECT query in PHP and then multiple rows are selected, but I need to fetch them into an array and then use: echo json_encode($array). After That I need to get this array into AJAX.
Here is the PHP code:
$val = $_POST['data1'];
$search = "SELECT * FROM employee WHERE emp_name = :val OR salary = :val OR date_employed = :val";
$insertStmt = $conn->prepare($search);
$insertStmt->bindValue(":val", $val);
$insertStmt->execute();
$insertStmt->fetchAll();
//echo "success";
//$lastid = $conn->lastInsertId();
$i = 0;
foreach($insertStmt as $row)
{
$arr[$i] = $row;
$i++;
}
echo json_encode($arr);
The problem is that I can't get all the lines of this array into AJAX so I can append them into some table. Here is the script:
var txt = $("#txtSearch").val();
$.ajax({
url: 'search.php', // Sending variable emp, pos, and sal, into this url
type: 'POST', // I will get variable and use them inside my PHP code using $_POST['emp']
data: {
data1: txt
}, //Now we can use $_POST[data1];
dataType: "json", // text or html or json or script
success: function(arr) {
for() {
// Here I don't know how to get the rows and display them in a table
}
},
error:function(arr) {
alert("data not added");
}
});
You need to loop over your "arr" data in the success callback. Something along the lines of:
var txt = $("#txtSearch").val();
$.ajax
({
url: 'search.php', //Sending variable emp, pos, and sal, into this url
type: 'POST', //I will get variable and use them inside my PHP code using $_POST['emp']
data: {data1: txt},//Now we can use $_POST[data1];
dataType: "json", //text or html or json or script
success:function(arr)
{
var my_table = "";
$.each( arr, function( key, row ) {
my_table += "<tr>";
my_table += "<td>"+row['employee_first_name']+"</td>";
my_table += "<td>"+row['employee_last_name']+"</td>";
my_table += "</tr>";
});
my_table = "<table>" + my_table + "</table>";
$(document).append(my_table);
},
error:function(arr)
{
alert("data not added");
}
});
You could just return
json_encode($insertStmt->fetchAll());
Also, be sure to retrieve only characters in UTF-8 or JSON_encode will "crash".
Your success function should be like this :
success:function(arr)
{
$.each(arr,function (i,item) {
alert(item.YOUR_KEY);
});
}

How to get the JSON working with PHP

I have the following code which pass data formatted as JSON to PHP through Ajax, but the PHP code doesn't print out the result.
var array_str_idnum = [];
for (var i=0;i<2;i++) {
array_str_idnum[i] = [];
}
$('#movetoset').click(function() {
if ($('#selectsett').val() === 'General') {
}
for(j=0;j< (array_str_idnum[0]).length;j++) {
if((document.getElementById('check' + array_str_idnum[0][j]).checked) && (array_str_idnum[1][j] != "moved")) {
document.getElementById('imagediv' + array_str_idnum[0][j]).style.display = 'none';
array_str_idnum[1][j] = "moved";
index = ((array_str_idnum[0]).length - 1 - j) + '';
var str = $("#complicated").serialize() + "&myindex=" + encodeURIComponent(index) ;
var desc_str = document.getElementById('textarea' + array_str_idnum[0][j]).value;
str = str + "&mydescription=" + encodeURIComponent(desc_str);
$.ajax({
type: "POST",
url: "addtoset.php",
data: str,
cache: false,
success: function(msg) {
$("#formstatus").ajaxComplete(function(){$(this).fadeIn("slow").html(msg + '<br /><br />')});
$("#formstatus").append(msg);
}
});
}
}
mydata = JSON.stringify(array_str_idnum);
$.ajax({
type: 'post',
cache: false,
url: 'parser.php',
data: {myJson: mydata},
success: function(msg) {
$("#formstatus").ajaxComplete(function() { $(this).fadeIn("slow").html(msg) });
}
});
});
Here is my PHP code:
$decoded = json_decode($_POST['myJson'],true);
// do something with data here
echo "decoded = $decoded[1][0]";
What's wrong with the code?
I think you want to fix your PHP code like others suggested, like so:
<?php
if ( !empty($_POST['myJson']) && strlen($_POST['myJson']) > 0 )
{
$decoded = json_decode( $_POST['myJson'], true );
// Echo out the JSON onject as a JavaScript variable.
echo "decoded = {$decoded[1][0]};";
}
else
{
// Echo out the JSON onject as a JavaScript variable.
echo "decoded = null;";
}
?>
Here is your JavaScript code with some minor suggestions:
<script type="text/javascript">
$( document ).ready(function()
{
var array_str_idnum = [];
// Init the array with two elemsnts that contain empty literal arrays.
for ( var i = 0; i < 2; i++ )
{
array_str_idnum[ i ] = [];
}
$( "#movetoset" ).click(function()
{
var $checkbox, str, desc_str, elementSuffix;
// I believe the code in here was removed for privacy reasons.
// I also believe it populats 'array_str_idnum' with some values of some kind.
if ( $("#selectsett").val() === "General" )
{
// ...
}
for ( var i = 0; i < (array_str_idnum[0]).length; i++ )
{
elementSuffix = array_str_idnum[ 0 ][ i ];
// Grab the checkbox.
$checkbox = $( "#check" + elementSuffix );
if ( $checkbox.checked && (array_str_idnum[1][i] != "moved") )
{
// Hide the image.
$( "#imagediv" + elementSuffix ).css({ "display": "none" });
// Indicate that this one is now moved, so do NOT process it again.
array_str_idnum[ 1 ][ i ] = "moved";
index = ( (array_str_idnum[0]).length - 1 - i ) + '';
// Setting str here will reinitialize it
str = $( "#complicated" ).serialize() + "&myindex=" + encodeURIComponent( index );
desc_str = $( "#textarea" + elementSuffix ).value;
str = str + "&mydescription=" + encodeURIComponent( desc_str );
// Bad idea to put ajax call in a loop.
$.ajax({
"type": "POST",
"url": "addtoset.php",
"data": str,
"cache": false,
"success": function( msg )
{
$( "#formstatus" ).ajaxComplete(function()
{
$( this ).fadeIn( "slow" ).html( msg + "<br /><br />" );
});
$( "#formstatus" ).append( msg );
}
});
}
}
mydata = JSON.stringify( array_str_idnum );
$.ajax({
"type": "POST",
"cache": false,
"url": "parser.php",
"data": { myJson: mydata },
"success": function( msg )
{
$( "#formstatus" ).ajaxComplete(function()
{
$( this ).fadeIn( "slow" ).html( msg )
});
}
});
});
});
</script>
Maybe your only problem is the echo statement. You'll have to change that to
echo "decoded = ".$decoded[1][0];
or
echo "decoded = {$decoded[1][0]}"; //
This is because PHP only notices "normal" variables in double-quoted strings. For array elements (or object properties) you'll have to use curly braces around the variable or use string concatenation.

Categories