JQuery / AJAX / PHP live search not working as desired - javascript

I have made use of the AJAX live search tutorial as seen on https://codeforgeek.com/2014/09/ajax-search-box-php-mysql/. This is dependent on typeahead.min.js as well as JQuery and Bootstrap.
The problem is, that it is not always getting the href link (it's buggy), as well as the fact that upon clicking on a result, it fills in the input field with the entire href link, which I do not want. I only want to navigate to that page. I feel like my issue may be JQuery / JS related. Please see the screenshot below.
I have modified the PHP to use the PEAR extension for DB calls, and extended it to include links in the returned results.
Below is some of the PHP file for processing the search.
$key=$_GET['key'];
$search_results_array = array();
$sql = "SELECT * FROM `Product_Data` WHERE `Product_Name` LIKE '%{$key}%' OR `Product_Tags` LIKE '%{$key}%' ORDER BY `Product_Sequence` ASC";
$q = $db->query($sql);
if (PEAR::isError($q)) {
showError ($q);
exit;
}
$numRows = $q->numRows();
while ($row = $q->fetchRow()) {
$product_name = $row['Product_Name'];
$product_id = $row['Product_ID'];
$search_results_array[] = "<a href='/index.php?page=purchase&product_id=$product_id' class='livesearch_link'>$product_name</a>";
}
print json_encode($search_results_array);
The HTML:
<div class="col-md-6">
<div class="panel panel-default">
<div class="bs-example">
<input type="text" name="typeahead" class="typeahead tt-query" autocomplete="off" spellcheck="false" placeholder="Search">
</div>
And the JQuery (Which is where I suspect the issue may lie):
<script>
$(document).ready(function(){
$('input.typeahead').typeahead({
name: 'typeahead',
remote: '/manage/process_ajax_search.php?key=%QUERY',
limit : 10,
});
});
$(document).on('click','.tt-suggestion .livesearch_link',function(e){
e.preventDefault();
var href = $(this).attr('href');
window.location.replace(href);
return false;
});
Please help me!

Related

Use AJAX to run PHP script and then return single value

Okay, this question was closed for not being clear enough, so I'm going to completely re-write it in as clear a form as I can...
Project: Room Booking System
Required Function: Check the database for existing bookings matching a criteria, return the result of 'COUNT' SQL query to a textbox which another function then looks to.
The values which need to be inserted into the COUNT criteria are as follows:
<h4>Date:</h4>
<input required type="text" name = "datebox" id = "datebox" ><br/>
<h4>Timeslot:</h4>
<input required type="text" name = "timebox" id = "timebox" ><br/>
<h4>Location:</h4>
<input required type="text" name = "roombox" id = "roombox" ><br/>
<h4>Person:</h4>
<input required type="text" name = "bookerbox" id = "bookerbox" ><br/>
</br>
Problem: I have a functioning php script which counts the number of rows in the database matching a criteria, which will then return the result to a textbox (main function sorted) when set up in a test directory with nothing else on the page. However, when I embed this php into an existing page (the new booking page) it doesn't work when the 'Check Availability' button is clicked. Instead, it reloads the page (as php does) which is not useful when users have already input their data for checking (and would need to re-enter it). I've Googled and have found that I need to use AJAX to run the php function in the background and then return the result to the textbox on the current page. I have never ever used AJAX and are only new to php, js etc. as it is, so I have no idea what I'm doing
How can you help: I need help in converting my existing code into a working solution to the above problem, probably using a combination of AJAX, PHP and JS functions.
Code:
PHP COUNT CODE (works)
<?php
if(isset($_POST['info'])) {
$con = mysqli_connect("x", "x", "x", "x");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql="SELECT COUNT(*) FROM `Existing_Bookings` WHERE Date = '2019-12-30' AND Time = 'Period 6' AND Room = 'C3'";
if ($result=mysqli_query($con,$sql)) {
// Return the number of rows in result set
$rowcount = mysqli_num_rows($result);
// Free result set
mysqli_free_result($result);
}
mysqli_close($con);
echo $rowcount; // echo the data you want to send over ajax
}
?>
Area of php/html in which the result should be returned (id="availresult")
<h2>Check availability</h2>
<h4>Click the button below to check whether your options are available:</h4>
<h4>This will only check against other bookings. It is your responsibility to use the timetable above to check whether the room is actually free.</h4>
<button onclick="soflow()" id="checkAvail" >Check Availability</button>
<input onclick="unhideReview()" type="button" id="continue" value="Continue" disabled />
<input type="text" style="width: 30px;" id="availresult" value="1" />
Test AJAX function, as suggested by an existing reply to my post
<script>
function soflow() {
$.post('checkAvailability.php', {info: 'start'}, function(data) { //if you don't need to send any data to the php file then you can set the value to whatever you want
document.getElementById('availResult').innerHTML = data;
});
}
</script>
I have tried various ways to do this myself, including modifying the suggested AJAX code above, but I'm not sure how to get my values from my various textbox over to the PHP function. Also, I don't know how to tell whether the AJAX function is running, or whether there is an error somewhere. At present, the value shown in my 'availresult' textbox does not change.
I appreciate any help with this, and thank anyone who has tried to help so far. I'm not sure how much clearer I can make this - please don't close the question again.
UPDATE:
(index.php):
<html>
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h4>Date:</h4>
<input required type="text" name = "datebox" id = "datebox" ><br/>
<h4>Timeslot:</h4>
<input required type="text" name = "timebox" id = "timebox" ><br/>
<h4>Location:</h4>
<input required type="text" name = "roombox" id = "roombox" ><br/>
<h4>Person:</h4>
<input required type="text" name = "bookerbox" id = "bookerbox" ><br/>
<br/>
<h2>Check availability</h2>
<h4>Click the button below to check whether your options are available:</h4>
<h4>This will only check against other bookings. It is your responsibility to use the timetable above to check whether the room is actually free.</h4>
<button onclick="soflow()" id="checkAvail" >Check Availability</button>
<input onclick="unhideReview()" type="button" id="continue" value="Continue" disabled />
<input type="text" style="width: 30px;" id="availresult" value="1" />
<script>
function soflow() {
var var_date = $('#datebox').val();
var var_time = $('#timebox').val();
var var_room = $('#roombox').val();
$.post('checkAvailability.php', {info: 'start', date: var_date, time: var_time, room: var_room}, function(data) {
document.getElementById('availResult').innerHTML = data;
});
}
</script>
</body>
</html>
(test.php):
<?php
if(isset($_POST['info'])) {
$con = mysqli_connect("x", "x", "x", "x");
if (mysqli_connect_errno()) { // Check connection
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$date = mysqli_real_escape_string($con, $_POST['date']);
$time = mysqli_real_escape_string($con, $_POST['time']);
$room = mysqli_real_escape_string($con, $_POST['room']);
$sql="SELECT COUNT(*) FROM `Existing_Bookings` WHERE Date = '$date' AND Time = '$time' AND Room = '$room'";
if ($result=mysqli_query($con,$sql)) {
// Return the number of rows in result set
$rowcount = mysqli_num_rows($result);
// Free result set
mysqli_free_result($result);
}
mysqli_close($con);
echo $rowcount; // echo the data you want to send over ajax
}
?>
You could also do ajax with pure JavaScript, but this is simpler.
Also note that this is just an example on how to do an ajax connection in the first place.

How to show an entire select element in a div using only Javascript

I'm writing a code for a project and I want to be able to show an entire select element in a div.
I can't type in the code in the result area because I am calling most of the code from a database. I have tried putting a container around the select element but it still doesn't work. The select element in my work is called from a database and there are many of them which is why I am using '$x' to make each of the select elements unique. I have searched stackoverflow and other forums online but can't find an answer relating to my problem.
//some code above here
$x = 1;
while($row = $result->fetch_assoc()){
$uidcheck = mysqli_num_rows($result);
$catname = $row['name'];
$catrefno = $row['refno'];
echo '
<label class="container"><input type="radio" name="catname[]" id="catname'.$x.'" value="'.$catname.'"> '.$catname.'
<span class="checkmark"></span></label>
<div id="selectdiv'.$x.'"><select class="form-control itnames" name="itname[]" id="itname'.$x.'" required>
<option></option>';
$sql1 = "SELECT * FROM foodarea WHERE status!='deactive' and itcatname='$catname'";
$result1 = $conn->query($sql1);
$uidcheck1 = mysqli_num_rows($result1);
if ($uidcheck1 > 0){
while($row1 = $result1->fetch_assoc()){
$uidcheck1 = mysqli_num_rows($result1);
$itname = $row1['itname'];
echo '<option>'.$itname.'</option>';
}
}
echo '</select></div>
<script>document.getElementById("catname'.$x.'").onchange = function() {
var itnames = document.getElementById("selectdiv'.$x.'").innerHTML;
var selectarea = document.getElementById("selectarea");
selectarea.innerHTML = !this.checked ? "none" : itnames;
};</script>';
$x++;
}
}
echo '<div id="selectarea"></div>'
I expect that when the radio buttons are clicked, the entire select element with id - "itname'.$x.'" is shown in the div with id - "selectarea". But it does not. Instead it shows the value first option or a javascript error. Please I am a beginner and would really appreciate the help.
Mistake is maybe here
<div class="selectdiv'.$x.'">
should be an id
<div id="selectdiv'.$x.'">

How to auto refresh a division with some PHP content within it

I googled abit and found a script, to reload a division.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
setInterval("$('#downshow').load('message.php');", 5000);
</script>
here downshow is my division where contents need to be refreshed. its like chat app, and messages between me and my friend needs to continoulsy reload.
My division downshow is something like below...
$getmessages= mysql_query("SELECT * FROM pvt_messages WHERE (user_from='$active_username' && user_to='$username') || (user_from='$username' && user_to='$active_username') ORDER BY id ASC ") or die(mysql_error());
while ($row = mysql_fetch_assoc($getmessages ))
{
$body = $row['msg_body'];
$date_send = $row['date'];
$opened = $row['opened'];
$whosent= $row['user_from'];
$whoreceived= $row['user_to'];
$seen=$row['opened'];
/////////////////////////////////////////////////////
$get_user_info = mysql_query("SELECT * FROM users WHERE (username='$whosent')");
////////////////////////////////////////////////////
$get_info = mysql_fetch_assoc($get_user_info);
$profilepic_info = $get_info['profile_pic'];
if ($profilepic_info == "") {
$profilepic_info = "./images/default_pic.jpg";
}
else
{
$profilepic_info = "./userdata/profile_pics/".$profilepic_info;
}
echo "
<div style='float: left;padding-top:5px; padding-left:20px;'>
<img src='$profilepic_info' height='50' width='40'>
</div>
<div style='margin-left:50px;padding-top:5px;'>
<a href='$whosent' style='color:black'> $whosent</a> $body
</div></br>
<div style=' margin-left:30px;'>
<font size='2px'>sent on: $date_send</font>
<br />
</div>
<hr />
";
}
I would have kept the content of this division in some other page i.e. message.php and then include it just as
<div id='downshow' style='bottom:0px;'class='see_message'>
<?php include("message.php"); ?>
</div>
But if i do this, there will be lots of problem like, session_start() issues, variable $active_username ll be obtained easily by $active_username=$_SESSION['username'] bt couldnt obtain varibale $username in message.php.
so instead of including the division content as "message.php". i want that code to be in main php file itself.
so want to as instead of
setInterval("$('#downshow').load('message.php');", 5000);
how can i use
setInterval("$('#downshow').load('????????????');", 5000);
load the division itself?????????????
Thankyou in advance :)
Try this..
setInterval(function(){ $('#downshow').load('message.php');
}, 5000);
This is not the best way to do this
You should look at AJAX and create a template for the HTML.
This way you can send information to the server (such as requesting items since a particular time, or from a particular 'room') and only send back the important data (send it back as JSON) and populate your template.
This will reduce traffic and load on your server and will reduce latency in your application as you are only sending back the important data - not the HTML to go with it!
Additionally use classes for each of the items instead of inline styles as it will make your code easier to maintain.

Separating variables for SQL insert using PHP and JavaScript

A grid table is displayed via PHP/MySQL that has a column for a checkbox that the user will check. The name is "checkMr[]", shown here:
echo "<tr><td>
<input type=\"checkbox\" id=\"{$Row[CONTAINER_NUMBER]}\"
data-info=\"{$Row[BOL_NUMBER]}\" data-to=\"{$Row[TO_NUMBER]}\"
name=\"checkMr[]\" />
</td>";
As you will notice, there is are attributes for id, data-info, and data-to that are sent to a modal window. Here is the JavaScript that sends the attributes to the modal window:
<script type="text/javascript">
$(function()
{
$('a').click(function()
{
var selectedID = [];
var selectedBL = [];
var selectedTO = [];
$(':checkbox[name="checkMr[]"]:checked').each(function()
{
selectedID.push($(this).attr('id'))
selectedBL.push($(this).attr('data-info'))
selectedTO.push($(this).attr('data-to'))
});
$(".modal-body .containerNumber").val( selectedID );
$(".modal-body .bolNumber").val( selectedBL );
$(".modal-body .toNumber").val( selectedTO );
});
});
</script>
So far so good. The modal retrieves the attributes via javascript. I can choose to display them or not. Here is how the modal retrieves the attributes:
<div id="myModal">
<div class="modal-body">
<form action="" method="POST" name="modalForm">
<input type="hidden" name="containerNumber" class="containerNumber" id="containerNumber" />
<input type="hidden" name="bolNumber" class="bolNumber" id="bolNumber" />
<input type="hidden" name="toNumber" class="toNumber" id="toNumber" />
</form>
</div>
</div>
There are additional fields within the form that the user will enter data, I just chose not to display the code. But so far, everything works. There is a submit button that then sends the form data to PHP variables. There is a mysql INSERT statement that then updates the necessary table.
Here is the PHP code (within the modal window):
<?php
$bol = $_POST['bolNumber'];
$container = $_POST['containerNumber'];
$to = $_POST['toNumber'];
if(isset($_POST['submit'])){
$bol = mysql_real_escape_string(stripslashes($bol));
$container = mysql_real_escape_string(stripslashes($container));
$to = mysql_real_escape_string(stripslashes($to));
$sql_query_string =
"INSERT INTO myTable (bol, container_num, to_num)
VALUES ('$bol', '$container', '$to')
}
if(mysql_query($sql_query_string)){
echo ("<script language='javascript'>
window.alert('Saved')
</script>");
}
else{
echo ("<script language='javascript'>
window.alert('Not Saved')
</script>");
}
?>
All of this works. The user checks a checkbox, the modal window opens, the user fills out additional form fields, hits save, and as long as there are no issues, the appropriate window will pop and say "Saved."
Here is the issue: when the user checks MULTIPLE checkboxes, the modal does indeed retrieve multiple container numbers and I can display it. They seem to be already separated by a comma.
The problem comes when the PHP variables are holding multiple container numbers (or bol numbers). The container numbers need to be separated, and I guess there has to be a way the PHP can automatically create multiple INSERT statements for each container number.
I know the variables need to be placed in an array somehow. And then there has to be a FOR loop that will read each container and separate them if there is a comma.
I just don't know how to do this.
When you send array values over HTTP as with [], they will already be arrays in PHP, so you can already iterate over them:
foreach ($_POST['bol'] as $bol) {
"INSERT INTO bol VALUES ('$bol')";
}
Your queries are vulnerable to injection. You should be using properly parameterized queries with PDO/mysqli
Assuming the *_NUMBER variables as keys directly below are integers, use:
echo '<tr><td><input type="checkbox" value="'.json_encode(array('CONTAINER_NUMBER' => $Row[CONTAINER_NUMBER], 'BOL_NUMBER' => $Row[BOL_NUMBER], 'TO_NUMBER' => $Row[TO_NUMBER])).'" name="checkMr[]" /></td>';
Then...
$('a#specifyAnchor').click(function() {
var selectedCollection = [];
$(':checkbox[name="checkMr[]"]:checked').each(function() {
selectedCollection.push($(this).val());
});
$(".modal-body #checkboxCollections").val( selectedCollection );
});
Then...
<form action="" method="POST" name="modalForm">
<input type="hidden" name="checkboxCollections" id="checkboxCollections" />
Then...
<?php
$cc = $_POST['checkboxCollections'];
if (isset($_POST['submit'])) {
foreach ($cc as $v) {
$arr = json_decode($v);
$query = sprintf("INSERT INTO myTable (bol, container_num, to_num) VALUES ('%s', '%s', '%s')", $arr['BOL_NUMBER'], $arr['CONTAINER_NUMBER'], $arr['TO_NUMBER']);
// If query fails, do this...
// Else...
}
}
?>
Some caveats:
Notice the selector I used for your previous $('a').click() function. Do this so your form updates only when a specific link is clicked.
I removed your mysql_real_escape_string functions due to laziness. Make sure your data can be inserted into the table correctly.
Make sure you protect yourself against SQL injection vulnerabilities.
Be sure to test my code. You may have to change some things but understand the big picture here.

google style autocomplete with arrow keys

i created a simple search engine that displays mysql database results using the php "LIKE" function (code below). everything works fine. i would just like to make it so that when the user starts typing he/she can use the arrow keys to scroll down and press enter on an item just like google. thanks. my code:
HTML:
<input type="text" name='search' id="searchbooks" onkeyup='getbooks(this.value);' value="search" onblur="setTimeout('removedrop()', 80);">
<div id='drop'></div>
JAVASCRIPT:
function getbooks(value){
if (value!=""){
$.post('getbooks.php', {book: value},
function (data) {
$('#drop').html(data);
doCSS();
});
}
else {
$('#drop').html("");
undoCSS();
}
}
getbooks.php file:
<?php
include 'connect.php';
$book=mysql_real_escape_string(addslashes($_POST['book']));
$result=mysql_query("SELECT * FROM searchengine WHERE title LIKE '$book%'");
while ($row=mysql_fetch_assoc($result)){
$title=$row['title'];
$id=$row['id'];
echo "<div id='link'><a href='index.php?id=$id' id='words'>". $row['title'] ."</a></div>";
}
?>
How about using the jQuery autocomplete plugin? It's made for exactly this use case.

Categories

Resources