Limit Number of Results for Autocomplete Based on Dropdown Selection - php

I'm trying to figure out a couple things here and seem to be pretty close but hit a road block. My issue is, after I select a dropdown option (used to filter a large number of results), the results which should be available when I start typing in the autocomplete box are not available. If I hardcode a value that the dropdown is passing and start typing in the autocomplete box, everything works fine. It's only when I pass in that value that I am having the issue.
I have two PHP pages, one containing the layout which includes a dropdown (SQL for its results) and an autocomplete box and the other which contains the SQL for the autocomplete.
search.php
<select id="loc">
<?php
// sql for dropdown
while ($row = odbc_fetch_array($result)) {
echo "<option value\"".$row['Location']"\">".$row['Description']."</option>";
}
?>
</select>
<label for="search">Search: </label>
<input type="text" id="search" />
<script>
// Send value entered in the autocomplete box to data.php for it to be used in sql statement
$(document).ready(function(){
$('#search').autocomplete({
minLength: 3,
source: function(query, process) {
$.ajax({
url: 'data.php',
type: 'GET',
data: "name=" + $('#search').val(),
dataType: 'JSON',
async: true,
success: function(data) {
process(data);
}
});
}
});
});
// Append selected dropdown value to URL so it can be accessed
$(document).ready(function() {
$('#search').change(function() {
var res = $(this).val();
location.href = "search.php?src="+res;
});
});
</script>
data.php
<?php
if (isset($_GET['src'])) {
$loc = $_GET['src'];
$fullname = explode(" ", $_GET['name']);
$sql = "SELECT p.lastname + ', ' + p.firstname as fullname,
l.city as city
FROM people p
JOIN location l on p.city = l.city
WHERE p.lastname like '".$fullname[1]."%' AND p.firstname like '".$fullname[0]."%'
AND l.city = '$loc'
GROUP BY p.lastname + ', ' + p.firstname, l.city
ORDER BY p.lastname + ', ' + p.firstname";
// DB connection and execute connection here
$array = array();
while ($row = odbc_fetch_array($db)) {
$array[] = $row['fullname'];
}
echo json_encode($array);
}
?>
So when I have my code like this and select an option from the dropdown, it runs through the select statement since the selected value is being passed in. If I echo the results on the search.php page, they are filtered correctly or if I navigate directly to the data.php page and pass in the correct parameters everything is correct. After I make a selection though, and start typing in the autocomplete box, I'm not getting any results. I'm guessing I need to somehow filter the results based on the selection, get those results and run a different query when I start typing?
Thanks in advance for any help and please let me know if I'm not clear on anything.

Well just like it ususally happens, after taking a break from it I've got it working now.
Below is the revised code with comments showing what I changed.
search.php
<select id="loc">
<?php
// sql for dropdown
while ($row = odbc_fetch_array($result)) {
echo "<option value\"".$row['Location']"\">".$row['Description']."</option>";
}
?>
</select>
<label for="search">Search: </label>
<input type="text" id="search" />
<script>
/* Send value entered in the autocomplete box to data.php
* for it to be used in sql statement */
$(document).ready(function(){
$('#search').autocomplete({
minLength: 3,
source: function(query, process) {
// Added the variable below to get the dropdown's selected value
var res = $('#loc').val();
$.ajax({
url: 'data.php',
type: 'GET',
// Edited: included the dropdown value
data: "src="+res + "&name=" + $('#search').val(),
dataType: 'JSON',
async: true,
success: function(data) {
process(data);
}
});
}
});
});
/* This event is not needed since the value is set when a selection
* is made. 'change' passed that value to search.php causing
* the query to run without the search value. This caused a HUGE
* number of results, and usually causing the page to timeout.
* Making sure all variables get passed prior to running the query
* is a must. I knew this but got stuck on how to make it work. */
// Append selected dropdown value to URL so it can be accessed
//$(document).ready(function() {
// $('#search').change(function() {
// var res = $(this).val();
// location.href = "search.php?src="+res;
// });
//});
</script>
data.php
<?php
if (isset($_GET['src'])) {
$loc = $_GET['src'];
}
// Moved the $loc variable into the if statement above
// $loc = $_GET['src'];
$fullname = explode(" ", $_GET['name']);
$sql = "SELECT p.lastname + ', ' + p.firstname as fullname,
l.city as city
FROM people p
JOIN location l on p.city = l.city
WHERE p.lastname like '".$fullname[1]."%'
AND p.firstname like '".$fullname[0]."%'
AND l.city = '$loc'
GROUP BY p.lastname + ', ' + p.firstname, l.city
ORDER BY p.lastname + ', ' + p.firstname";
// DB connection and execute connection here
$array = array();
while ($row = odbc_fetch_array($db)) {
$array[] = $row['fullname'];
}
echo json_encode($array);
?>
I haven't finished a couple pieces on the main page such as disabling/hiding the autocomplete box until a selection is made from the dropdown and adjusting the query for additional filtering but those are next on my list. I'm sure there are a few other things I could clean up as well but my first goal was to get it working correctly and that's accomplished now!
If anyone is using php and has a few hundred thousand + results and would like to use an autocomplete box to filter those without waiting a ridiculous amount of time for the results to display, I hope this may be of some help. Not nearly as complex as I originally made it out to be but over thinking it will do that to you. Also, even though it's working now, feel free to add some suggestions and apologies for any grammatical errors!

Related

Using Select Box to Update Display Query

I am just learning Ajax and am trying to update a mysql select query to filter results. I think the query is working fine, but not sure that I have the event working correctly.
Here is my HTML with the selection;
<div class="volunteers">
<h1>Volunteers</h1>
<div class="volunteerSelection">
<select id="vtSelect" name="volunteerS">
<option value="1">Comittee</option>
<option value="2">Day of Event</option>
</select>
</div>
<div id="volunteers">
</div>
</div>
This is the script that displays the data;
I have updated this to the suggestion and it works fine. Then I started working on my PHP and mysql query. See below;
$(document).ready(function(){
$('#vtSelect').change(function (e) {
e.preventDefault();
var selectedOption = $(this).find('option:selected');
$('#vtSelect option').removeAttr('selected');
$(selectedOption).attr('selected', 'selected');
var selectedOptionValue = $(selectedOption).val();
$.ajax({
type: "POST",
url: "includes/backDataProcess.php",
data: {
data: selectedOptionValue
},
success: function (data) {
$("#volunteers").html(data);
}
});
});
});
This is the PHP with the select query; I have update this and am getting data. I updated the name in the select tag, but I am not getting the select tag value in the query. When I comment out the post data and just fill in a value it posts fine. I am not getting any errors, it is just displaying 0 results.
<?php
include('readerConnect.php');
$sql = "SELECT * FROM contacts prc
JOIN states as st
ON (prc.stateId = st.idStates)
INNER JOIN volunteers as v
ON (prc.idContacts = v.contactId)
INNER JOIN volunteerType as vt
ON (v.volunteerTypeId = vt.idVolunteerType)
WHERE (volunteerTypeId = 1 /*`mysql_real_escape_string('$_POST[volunteerS]')`*/)";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo
"<div class='contacts'>
<div class='contactName'>" . $row["firstName"] ." " . $row["lastName"] ."</div>"
."<div class='contactAddress'>" .$row["address1"] ." " .$row["address2"] ."<br>"
.$row["city"] ." " .$row["state"] ." " .$row["zip"] ."</div>"
."<div class='contactVolunteer'>" .$row["volunteerTypeId"]
."</div>";
}
} else {
echo "0 results";
}
$conn->close();
?>
I am not sure exactly where the issue is, I have tried both change and onchange to update, do I need an update button? I thought jquery would be able to do this with no update. Any help is greatly appreciated.
There are several obvious problems in your jQuery code. If you open your browser console you should see error onChange is not a function since there is no such jQuery method. You want change() or on()
Also you create a function showVolunteers() but it never gets called.
try:
$('#vtSelect').change(function (e) {
e.preventDefault();
var selectedOption = $(this).find('option:selected');
$('#vtSelect option').removeAttr('selected');
$(selectedOption).attr('selected', 'selected');
var selectedOptionValue = $(selectedOption).val();
$.ajax({
type: "POST",
url: "includes/backDataProcess.php",
data: {
data: selectedOptionValue
},
success: function (data) {
$("#volunteers").html(data);
}
});
});
Should you encounter more problems, use browser console network tab to inspect ajax request, and always use console to check for errors

How do i populate a php dropdown with data relating to a previous dropdown selection [duplicate]

I am trying to create a dynamic set of dropdown boxes, using jQuery/AJAX and PHP/MySQL. The first dropdown box will be populated when the page loads based on values from a database. The second dropdown box should display a set of values based on the selection from the first dropdown box. I know there have been similar questions asked on here before, but I haven't found a solution that matches my scenario.
My query to generate a JSON encoded list of values for the second drop down is functioning, but I am having issues populating it into the actual dropdown form element. Any ideas on where I'm going wrong.
Javascript:
<script>
$().ready(function() {
$("#item_1").change(function () {
var group_id = $(this).val();
$.ajax({
type: "POST",
url: "../../db/groups.php?item_1_id=" + group_id,
dataType: "json",
success: function(data){
//Clear options corresponding to earlier option of first dropdown
$('select#item_2').empty();
$('select#item_2').append('<option value="0">Select Option</option>');
//Populate options of the second dropdown
$.each( data.subjects, function(){
$('select#item_2').append('<option value="'+$(this).attr('group_id')+'">'+$(this).attr('name')+'</option>');
});
$('select#item_2').focus();
},
beforeSend: function(){
$('select#item_2').empty();
$('select#item_2').append('<option value="0">Loading...</option>');
},
error: function(){
$('select#item_2').attr('disabled', true);
$('select#item_2').empty();
$('select#item_2').append('<option value="0">No Options</option>');
}
})
});
});
</script>
HTML:
<label id="item_1_label" for="item_1" class="label">#1:</label>
<select id="item_1" name="item_1" />
<option value="">Select</option>
<?php
$sth = $dbh->query ("SELECT id, name, level
FROM groups
WHERE level = '1'
GROUP by name
ORDER BY name");
while ($row = $sth->fetch ()) {
echo '<option value="'.$row['id'].'">'.$row['name'].'</option>'."\n";
}
?>
</select>
<label id="item_2_label" for="item_2" class="label">#2:</label>
<select id="item_2" name="item_2" />
</select>
PHP:
<?php
require_once('../includes/connect.php');
$item_1_id = $_GET['item_1_id'];
$dbh = get_org_dbh($org_id);
$return_arr = array();
$sth = $dbh->query ("SELECT id, name, level
FROM groups
WHERE level = '2'
AND parent = $item_1_id
GROUP by name
ORDER BY name");
while ($row = $sth->fetch ()) {
$row_array = array("name" => $row['name'],
"id" => $row['id']);
array_push($return_arr,$row_array);
}
echo json_encode($return_arr);
?>
Sample JSON Output:
[{"name":"A","id":"0"},{"name":"B","id":"1"},{"name":"C","id":"2"}]
First, your document-ready looks a bit off, it should either be $(document).ready(function(){}); or it could be just $(function(){});.
Second, you looping over the JSON result looks a bit odd as well. Try something like this instead:
$.each(data.subjects, function(i, val){
$('select#item_2').append('<option value="' + val.id + '">' + val.name + '</option>');
});

Cascading jQuery Dropdowns with JSON and Multiple MySQL Tables using PHP

I'm fairly new to PHP and MySQL, have a little experience with jQuery and almost no experience with JSON, just to give you some background. I am trying to implement cascading dropdowns in my form.
I have two tables:
|city|
|city_id INT| - PK
|city VARCHAR (45)|
|state_state_id INT | - FK
|state|
|state_id INT| - PK
|state VARCHAR (25)|
Here's my form:
State:<br />
<select name="state" id="stateName">
<?php foreach($rows as $row): ?>
<option value="<?php echo htmlentities($row['state'],ENT_QUOTES,'UTF-8');?>"><?php echo htmlentities($row['state'],ENT_QUOTES,'UTF-8');?>
</option>
<?php endforeach; ?>
</select>
<br /><br />
City:<br />
<select name="city" id="cityName"></select>
<input type="submit" name="work_order_submit" id="" value="Add Work Order" />
I populate the State dropdown with this query:
$query = "SELECT * FROM state WHERE 1 ORDER BY state";
try{
$stmt = $db->prepare($query);
$stmt->execute();
}catch(PDOException $ex){
//On production remove getMessage.
die("Failed to run query: " . $ex->getMessage());
}
$rows = $stmt->fetchAll();
Here's the jQuery I've created to run the JSON and populate the City dropdown with the cascaded values from the state dropdown when a state is selected:
<script>
function populateCityName(){
$.getJSON('state-names.php', {stateName:$('#stateName').val()},
function(data){
var select = $('#cityName');
var options = select.prop('options');
$('option', select).remove();
$.each(data, function(index, array){
options[options.length] = new Option(array['city']);
});
});
}
$(document).ready(function(){
populateCityName();
$('#stateName').on('change', function(){
populateCityName();
});
});
</script>
And here's the code in the state-names.php file (I connect to the database before this code):
$rows = array();
if(isset($_GET['stateName'])){
$query = "SELECT city FROM city INNER JOIN state ON city.state_state_id = state.state_id WHERE state = :state ORDER BY city";
$query_params = array(":state" => $_GET['stateName']);
try{
$stmt = $pdo->prepare($query);
$stmt->execute($query_params);
}catch(PDOException $ex){
//On production remove .getMessage.
die("Failed to run query: " . $ex->getMessage());
}
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
echo json_encode($rows);
Nothing happens when I select the state in the form. I don't even get an error. I've tested the SQL and it runs fine and retrieves the values that I want, but for some reason that I can't figure out, the values aren't being cascaded into the City dropdown.
Any help is very much appreciated.
EDIT: As I'm doing more debugging and realizing a few things, this is what I've found so far. The JSON comes in like this:
[{"city":"Salt Lake City"},{"city":"Toole"},{"city":"Provo"},{"city":"St. George"}]
I now know the JSON is working correctly. When I changed the dropdown selection in the state dropdown to a state that I know had entries for the cities, the city dropdown showed blank 'option' fields for the number of entries that there actually were. So, using the answer below and MANY different tutorials on cascading dropdowns and chained dropdowns, I finally figured it out. I've submitted an answer with the working code.
Can you try:
$.each(data, function(index, array){
// new Option(text [, value, defaultSelected, selected]);
select.add(new Option(array['city'], index), null);
});
??
All of the code above worked except the jQuery function. Well, the jQuery worked for what I told it to do, not for what I really wanted the code TO DO... Big difference.
Here's the working jQuery that populates the city dropdown based on a selection made in the state dropdown:
<script>
function populateCityName(){
$.getJSON('state-names.php', {stateName: $('#stateName').val()},
function(data){
var html = '<option value="';
var htmlEnd = '</option>';
var options = '';
var select = $('#cityName');
$('option', select).remove();
$.each(data, function(index, array){
options += html + array['city'] + '">' + array['city'] + htmlEnd;
});
$('#cityName').append(options);
});
}
$(document).ready(function(){
populateCityName();
$('#stateName').on('change', function(){
populateCityName();
});
});
</script>
Before, the code would find the number of entries and the select box would show this number, but the selections were blank. With this code, the number of entries is found, but the values for those entries also show. Hope this helps someone else later.

Saving sortable to mysql with ajax jquery and php

I have a page with multiple drag&drop boxes, that works great, the thing that does not work are the links in the boxes. I would appreciate if someone could help me :). So I have a page where people can drag&drop boxes (it works fine, as I said before), the links inside the boxes are sortable aswell, but I can't seem to get them to save the values to mysql. I think there is a conflict between the two drag&drops, maybe I am doing it wrong, 'cause I haven't used ajax and jquery before.
//here is the jquery where I need to add some ajax
$(function() {
$('.dragbox-content').sortable({
connectWith: '.dragbox-content',
update: function(event, ui) {
var order=$(this).attr('id');
alert(order); // I get the order alert and it has one value that I need, but I need the sort order aswell
}
});
});
//this is the <div> that has the links in them and mysql query that gets the values
//from two different databases, one is for the boxes and the other for links.
//boxes db id = links title_id
echo '<div class="dragbox-content" id="order'.$widget['id'].'"';'>''</div>';
$sql10 = "SELECT u.*, w.id, w.link_address, w.link_name FROM db_boxes u LEFT
JOIN db_links w ON u.link_id = w.id WHERE
(u.username = '$username' AND u.link_id !='0' AND w.title_id = '".$widget['id']."'
AND w.link_name !='pilt' AND w.rights = '0') OR
(u.username = '$username' AND u.link_id !='0' AND w.title_id = '".$widget['id']."'
AND w.link_name !='pilt' AND w.rights LIKE '%26%') ORDER BY w.id ASC";
$result10 = mysql_query($sql10) or die (mysql_error());
while ($row = mysql_fetch_array($result10)) {
$link_id = $row['id'];
$link_address = $row['link_address'];
$link_name = $row['link_name'];
$title_id = $row['title_id'];
?>
<div class="move" id="<?php echo $link_id;?>">
<span class="link_style">
<div><?php echo $link_name;?> </div</span></div>
I just need somebody to tell me how can I save tile_id and sort_order to boxes database with ajax on every click a user makes on that page
See my example below:
http://jsfiddle.net/gRoberts/vMy7r/
$(function () {
$('ul').sortable({
update : function(e, ui) {
var ul = $(ui.item).closest('ul');
var index = 0;
var toPost = {};
ul.find('> li').each(function() {
index++;
$(this).find('input').val(index);
toPost[$(this).find('input').attr('name')] = index;
});
$.ajax({
url : '/echo/json/',
data : toPost,
type : 'POST',
dataType : 'json',
success : function(resp) {
alert(resp);
},
error : function() {
alert('There was a problem');
}
});
}
});
});
​
The above example can be used in two ways, if you remove the $.ajax it will update hidden form fields which you can then post normally.

How to populate second dropdown based on selection of first dropdown using jQuery/AJAX and PHP/MySQL?

I am trying to create a dynamic set of dropdown boxes, using jQuery/AJAX and PHP/MySQL. The first dropdown box will be populated when the page loads based on values from a database. The second dropdown box should display a set of values based on the selection from the first dropdown box. I know there have been similar questions asked on here before, but I haven't found a solution that matches my scenario.
My query to generate a JSON encoded list of values for the second drop down is functioning, but I am having issues populating it into the actual dropdown form element. Any ideas on where I'm going wrong.
Javascript:
<script>
$().ready(function() {
$("#item_1").change(function () {
var group_id = $(this).val();
$.ajax({
type: "POST",
url: "../../db/groups.php?item_1_id=" + group_id,
dataType: "json",
success: function(data){
//Clear options corresponding to earlier option of first dropdown
$('select#item_2').empty();
$('select#item_2').append('<option value="0">Select Option</option>');
//Populate options of the second dropdown
$.each( data.subjects, function(){
$('select#item_2').append('<option value="'+$(this).attr('group_id')+'">'+$(this).attr('name')+'</option>');
});
$('select#item_2').focus();
},
beforeSend: function(){
$('select#item_2').empty();
$('select#item_2').append('<option value="0">Loading...</option>');
},
error: function(){
$('select#item_2').attr('disabled', true);
$('select#item_2').empty();
$('select#item_2').append('<option value="0">No Options</option>');
}
})
});
});
</script>
HTML:
<label id="item_1_label" for="item_1" class="label">#1:</label>
<select id="item_1" name="item_1" />
<option value="">Select</option>
<?php
$sth = $dbh->query ("SELECT id, name, level
FROM groups
WHERE level = '1'
GROUP by name
ORDER BY name");
while ($row = $sth->fetch ()) {
echo '<option value="'.$row['id'].'">'.$row['name'].'</option>'."\n";
}
?>
</select>
<label id="item_2_label" for="item_2" class="label">#2:</label>
<select id="item_2" name="item_2" />
</select>
PHP:
<?php
require_once('../includes/connect.php');
$item_1_id = $_GET['item_1_id'];
$dbh = get_org_dbh($org_id);
$return_arr = array();
$sth = $dbh->query ("SELECT id, name, level
FROM groups
WHERE level = '2'
AND parent = $item_1_id
GROUP by name
ORDER BY name");
while ($row = $sth->fetch ()) {
$row_array = array("name" => $row['name'],
"id" => $row['id']);
array_push($return_arr,$row_array);
}
echo json_encode($return_arr);
?>
Sample JSON Output:
[{"name":"A","id":"0"},{"name":"B","id":"1"},{"name":"C","id":"2"}]
First, your document-ready looks a bit off, it should either be $(document).ready(function(){}); or it could be just $(function(){});.
Second, you looping over the JSON result looks a bit odd as well. Try something like this instead:
$.each(data.subjects, function(i, val){
$('select#item_2').append('<option value="' + val.id + '">' + val.name + '</option>');
});

Categories