I am using jQueryUI autocomplete to search a mySQL database. I have this working for a single column from the database, but I want the autocomplete to search several columns at the same time.
e.g. Tables:
Companies Sectors
---------- ---------
company_id sector_id
company sector
So I want the autocomplete to search both the Companies.company AND Sectors.sector and provide autocomplete suggestions from both tables.
This is the php I have been using so far which does not return an error or data to the autocomplete:
<?php
$con=mysqli_connect(database_details);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$q = strtolower($_GET["term"]);
$return = array();
$query = mysqli_query($con, "SELECT company FROM companies UNION SELECT sector FROM sectors AS data WHERE data LIKE '%$q%'");
if($query === FALSE) {
die(mysql_error());
}
while ($row = mysqli_fetch_array($query)) {
array_push($return,array('label'=>$row['data'],
'value'=>$row['data']
));
}
echo(json_encode($return));
mysqli_close($con);
?>
The JS is really simple:
<script>
$(document).ready(function search() {
$( "#search" ).autocomplete({
source: "php/search.php"
});
});
</script>
I am pretty new to this so please don't shoot me down, although this is likely a very simple error on my behalf :)
I have spent a lot of time (hours) trying to figure this out and not found any example code on stack overflow (or otherwise) that helps me complete this specific task.
Many thanks in anticipation
OK, so I been playing around with this a little more, it was an error with my mysqli_query as I had thought.
I had to change it to this to work:
SELECT company FROM companies WHERE company LIKE '%$q%' UNION SELECT sector FROM sectors WHERE sector LIKE '%$q%'
Most likely a very simple one for you experienced guys out there, but thanks for your help Tularis - testing the JSON return was what led me to this
Related
I'm still learning PHP and MySql and having difficulty with search bar. My problem is that I was able to select two tables from the database but i'm having trouble with the while loop where it is throwing everything at the search bar or sometimes nothing. I'm using typeahead.js plugin for this. I want the countries to show up first and then domains should be suggested and I dont want to join the tables. Please help.
This is my script:
<script>
$(document).ready(function(){
$('input.typeahead').typeahead({
name: 'typeahead',
remote:'search2.php?key=%QUERY',
limit : 30
});
});
</script>
This is my php:
<?php
$key=$_GET['key'];
$array = array();
$con=mysql_connect("localhost","root","");
$db=mysql_select_db("test_db",$con);
$query=mysql_query("select * from tbl_sample where country LIKE '%{$key}%' AND domain LIKE '%{$key}%' ");
while($row=mysql_fetch_assoc($query)){
$array[] = $row['country'];
$array[] = $row['domain'];
}
echo json_encode($array);
?>
What you're asking is a bit vague given you haven't described the second table to us at all, so I assume you just want to do two separate selects from the same table. That's done like this and will place countries first:
$query=mysql_query("select country as 'result' from tbl_sample where country LIKE '%{$key}%' UNION select domain as 'result' from tbl_sample where domain LIKE '%{$key}%' ");
while($row=mysql_fetch_assoc($query)){
$array[] = $row['result'];
}
I'd like to search 3 separate tables I've created from 1 form and return the data in alphabetical order. Currently I can search 3 tables separately with use of a drop-down box (from my form) to select a table but I've fallen short at querying them simultaneously and returning all the data in alphabetical order. I've been trying to solve it but I'm struggling a lot.
Currently what my program searches through separate tables for what the user previously input into my form. Now I would like to be able to search through all my tables in 1 go and return the information in alphabetical order, meaning some values from tables might be spread out.
I have 3 tables: "Insecttable", "birdtable" and "butterflytable"
There are 3 controllers: "ControllerInsectTable", ControllerBirdTable and "ControllerButterflyTable"
I'm trying to make another controller: "ControllerAllTables" that can search through all tables.
HTML:
<form name="searchForm" id="searchForm" method="POST" action="ControllerAllTables.php">
Search for: <input type="text" name="aSearch">
<input type="submit" name="searchButton" value="Search">
</form>
PHP:
// Collect Data
// If an input has been given
if(isset($_POST["aSearch"])) {
$searchq = $_POST["aSearch"];
$searchq = preg_replace("#[^0-9a-z]#i","",$searchq); //Can only search words
// Select statements if keywords match
$sql = "SELECT * FROM insecttable WHERE insectName LIKE '%$searchq%'";
$sql1 = "SELECT * FROM butterflytable WHERE butterflyName LIKE '%$searchq%'";
$sql2 = "SELECT * FROM birdtable WHERE birdName LIKE '%$searchq%'";
}
// Tests if the code been inserted
if ($conn->query($sql && $sql1 &&sql2)=== TRUE){
echo "The rows you have searched for are:";
} else {
echo "Connection failed: ";
echo $conn->error;
}
// Show fields
$result = $conn->query($sql && $sql1 &&sql2);
// Output data of each row
if ($result-> num_rows> 0) {
readfile("ViewReturn.html");
while($row = $result-> fetch_assoc()) {
// echo "ID: ".$row["id"]. "<br>";
echo "Insect: ".$row["insectName"]. "<br><br>";
echo "Bird: ".$row["birdName"]. "<br><br>";
echo "Butterfly: ".$row["butterflyName"]. "<br><br>";
}
} else {
echo "0 results";
}
I cut out some of the bits of my code that didn't affect my question, like making connections and such.
At the moment, I have no idea how to return values in order, and I'm seriously stuck at searching multiple tables from one query. I've looked at "joins" but I really don;'t understand them.
As you can tell I'm not very good at PHP, and I hope I can soon rid it from my life. I've been completely unsuccessful in this section of my program and I'm looking for help and criticism. I know it's a lot to ask but I'm really stuck, thanks.
You'll want to use the UNION operator to combine the query results, being sure to order the data after it has been combined. This can affect performance, but hopefully your result sets aren't too large.
SELECT name -- because we NEVER use select *
FROM
(
SELECT insectName AS name FROM InsectTable WHERE insectName LIKE '$searchq%'
UNION ALL
SELECT butterflyName AS name FROM ButterflyTable WHERE butterflyName LIKE '$searchq%'
UNION ALL
SELECT birdName AS name FROM BirdTable WHERE birdName LIKE '$searchq%'
)
Also, you might want to consider a redesign of the database. If the items in your tables are all related then they are effectively a super class. If you Google "SQL super class design" you should be able to find some good patterns for this.
Also, appending the word "Table" to the end of all of your table names is not something that is usually done. If your table holds data about insects then it's "Insect" or "Insects" (I'll ignore the singular/plural debate for now). The fact that it's a table is already self-evident.
First time posting, first time working with relational databases, so be gentle!
Working on a database of relevant fiction novels, and I'm running into some difficulty with persons of responsibility, such as author or illustrator or preface-writer.
I thought to store the persons in a 'persons' table, with first_name and last_name, but when a user enters a new book to the database, I want the persons of responsibility to act almost like tags, with an autocompleted list appearing as well as allowing them to enter a new author... in a single field, not two.
Further, each person will have a role tied specifically to that book in question. Is there anything terribly wrong with a table 'book-person-role' with 'book_id', 'person_id', and 'role_id'? Or should I separate this into two tables, 'book-person' and 'person-role,' with this 'person-role' table linking to the primary id of the 'book-person' table?
First the second question:
Further, each person will have a role tied specifically to that book in question. Is there anything terribly wrong with a table 'book-person-role' with 'book_id', 'person_id', and 'role_id'?
If you have only one role_id connected to book_id and person_id you can use one table. Joining tables is slow and generally the fewer the tables you have the faster it works (if everything else does not change). In this particular case the number of rows is not increased. So there is nothing wrong with having one table, and you even have a bonus: it works faster.
Concerning the first question. If you have a many to one relationship of books to persons you should use different tables for books and persons. And you can do the user interface whatever you like. You can join tables, make several requests. You did not say what programming languages you are using so I cannot help you write the code for the user interface you want.
EDIT:
The way you proposed to make persons table (first_name and last_name as different fields) is a good way. When you want to lookup a person you make an AJAX call to server the server uses OR and returns the list. For example, you want to find a name in #name_input input tag.
HTML:
<input id="name_input" type='text' />
JavaScript:
$(document).on('keydown','#name_input',function(){
var jqxhr = $.ajax( "name_lookup.php?name="+$("#name_input").val())
.done(function(data, textStatus, jqXHR) {
alert( "add data to your lookup list" );
})
.fail(function() {
alert( "error" );
})
});
PHP:
$name = mysql_real_escape_string($_GET['name']);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
if ($result = $mysqli->query(
"SELECT id, first_name, last_name FROM persons WHERE first_name = $name OR last_name = $name ORDER BY last_name"
)) {
$rows = array();
while($row = $result->fetch_assoc()) {
$rows[] = $row;
}
echo json_encode($rows);
}else{
echo "Error";
}
I am writing a php site using a mysql database for a class of mine and cannot for the life of me figure out what is wrong with it. I have a query that works locally on my machine (on an identical db to the one on the teacher's server) but when I upload it, it doesn't work. The problem is that the query is returning 0 results even though the db has info in it that should be showing.
function bigAssQuery($whereCondition)
{
$queries[] = 'CREATE TEMPORARY TABLE subAssignments (SELECT ua.assignmentid, ua.assignmentnum, ua.description
FROM Course c JOIN UserAssignment ua ON ua.crn = c.CRN AND ua.term = c.term
WHERE c.CRN = "'.$_SESSION["crnum"].'" AND c.term = "'.$_SESSION["mysem"].'")';
$queries[] = 'CREATE TEMPORARY TABLE subStudents (SELECT s.studentid, s.lastname, s.firstname
FROM Course c JOIN Student s ON s.crn = c.CRN AND s.term = c.term
WHERE c.CRN = "'.$_SESSION["crnum"].'" AND c.term = "'.$_SESSION["mysem"].'")';
$queries[] = 'CREATE TEMPORARY TABLE subRubric(SELECT assignmentid, re.rubricelementid, re.learning_goal_char
FROM RubricElement re JOIN RubricAssignmentRelation rar ON re.rubricelementid = rar.rubricelementid)';
$queries[] = 'CREATE TEMPORARY TABLE subAssignRub(SELECT subAssignments.assignmentid, rubricelementid, learning_goal_char, assignmentnum, description
FROM subRubric JOIN subAssignments ON subAssignments.assignmentid = subRubric.assignmentid)';
$queries[] = 'CREATE TEMPORARY TABLE subAssignRubStud (SELECT *
FROM subAssignRub CROSS JOIN subStudents)';
$queries[] = 'CREATE TEMPORARY TABLE subAssignInstRubStud (SELECT sars.assignmentid, ai.ainstanceid, rubricelementid, learning_goal_char, assignmentnum, description, sars.studentid, lastname, firstname
FROM subAssignRubStud sars LEFT JOIN AssignmentInstance ai ON sars.studentid = ai.studentid AND sars.assignmentid = ai.assignmentid)';
$queries[] = 'CREATE TEMPORARY TABLE subTotal (SELECT assignmentid, siars.ainstanceid, s.ainstanceid As scoreAID, siars.rubricelementid, learning_goal_char, assignmentnum, description, studentid, lastname, firstname, score
FROM subAssignInstRubStud siars LEFT JOIN Score s ON siars.ainstanceid = s.ainstanceid AND siars.rubricelementid = s.rubricelementid
ORDER BY lastname, assignmentid)';
$queries[] = 'SELECT *
FROM subTotal
'.$whereCondition.' Order By lastname, assignmentnum, learning_goal_char';
return($queries);
}
Then when the db is queried the code looks like this. . .
$queries = bigAssQuery($whereCondition);
$result = 1;
foreach($queries as $query)
{
$result = $db->query($query);
if(!$result)
{
echo '<script type="text/javascript">
window.onload=function(){ alert("Error: Could not extract course information. Please try again later."); }
</script> ';
exit;
}
}
$num_rows = $result->num_rows;
I assure you that the local and remote databases are identical. I see no reason why no results are coming back. I did test a few simple temp tables to see if the server wasn't reading those tables for some reason, but they weren't an issue in my tests. I would try with nested subqueries, but it gets so convoluted so quickly that I can't organize it. Maybe there is a better way?
Also, just to clarify the queries aren't failing, they just aren't returning anything when I know that they should.
I apologize for the wall of text, but any help is appreciated.
EDIT: I really don't know which of the queries the problem lies. I do know that I'm probably missing some important information. Part of that lies in my web inexperience. I test locally first because I've got the debugger working, but I honestly don't know how to do remote debugging. I'm using netbeans and xdebug. If someone could suggest a how to get remote debugging set up I would probably be able to come up with some better data. Any suggestions would be helpful
EDIT AGAIN: Found the problem. Embarrassingly enough it was an error in data entry; one of my foreign keys was incorrectly entered. Thanks everybody for pointing me in the right direction.
On having a quick look, your code is stoping the execution of the PHP inappropriately. You should at least the let the remainder to continue. Simply exit out of loop using break; instead.
if(!$result)
{
echo '<script type="text/javascript">
window.onload=function(){ alert("Error: Could not extract course information. Please try again later."); }
</script> ';
break; //exit the loop only NOT THE PHP's Execution
}
Furthermore, check every query individually and run them separately on phpMyAdmin to see, if they are executing correctly. Find the break point and fix the error.
I'm having a tough time figuring out how to have a select list drive what is returned in a table. Scenario, there are a list of projects, pending what project your user has access to a subset of items are returned.
Here is some code:
query:
$q = "SELECT DISTINCT projectid, projectname FROM projects where active=1";
select list construction:
//variable for projects list select list name
$dropdown = "Projects Lists \n <select name=\"ProjectsLists\">";
//loop results
while ($row = mysql_fetch_assoc($result)){
$dropdown .= "\r\n<option value='{$row['projectid']}'>{$row['projectname']}</option>";
}//end while
$dropdown .= "\r\n</select>";
echo $dropdown;
Then what i'd like to do is display items returned from a query that needs to be run when the select list is select:
$s_query = "SELECT contentname, contentlocation FROM projectscontent WHERE projectname=<select list value>";
I'm having trouble figuring out if i can capture the selected value. If so, how? I thought i could maybe do $_GET['selectlistname']; but i don't think that is right.
you have to use jquery event .change() this will help you for what you want.
For example:
Add an id in you select options
like $dropdown = "Projects Lists \n <select id=\"mylist\" name=\"ProjectsLists\">";
now with jquery use something like this:
$('#mylist').change(
//provide you selected value
var proName = $(this).val();
//call ajax
$.ajax({
url: 'queryPage.php',
data: 'proName=' + proName,
success: function(data){
$('#result').html(data);
}
});
);
queryPage.php:
//$_REQUEST['proName'] provide you select product name
$productname = mysql_real_escape_string( $_REQUEST['proName'] );
// Now start your query
$s_query = "SELECT contentname, contentlocation FROM projectscontent
WHERE projectname='$productname' ";
now start to run the query and echo the result here on the same page, this will return the data to the page from where you call queryPage.php.
I personally use jQuery DataTables for this type of functionality. I generate a dropdown or group of dropdowns, then on click of a button I update my DataTable element. There are several tutorials on how to do this on the website.
I'm a little concerned, though, that your tables are a bit wonky. This should be very straightforward, and might require more tables than you're telling us about. I'd personally link my two tables on projectid if I was using the structure you're showing above. Then, I'd add an additional table (via inner join on userid) that links users.userid, permissions, and projectid. This would be queried into the second query in your example above to handle permissions.
When I'm generating my dropdown, I'm keeping that simple too. Each <option> would have a value = projectid and the display value would be the project name. On change of the select element listing the projects, I'd run a query (ajax preferrably) to get myself all the project details joined with permissions with where clauses to limit my results to the user, based on permissions. No need to do exotic "merged" values, etc.