Forum Moderators: coopster

Message Too Old, No Replies

Query results in different tabs?

         

kristo5747

4:47 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Greetings!

I have a form that's meant to be a rudimentary search engine.

The forms calls the piece of code below and outputs successfully the results in a new tab.

<?php
//Includes the db config file
$dbconf = include '.../config/dbConfig.php';

//checks if fields are set.
if(isset($_POST['submit'])) {
if(
!empty($_POST['search_string'])
) {
searchWebcases();
searchResolutions();
} else {
echo "<html><body>
<script type=\"text/javascript\" language=\"javascript\">alert(
'Nothing to do.'
+ '\\n\\n' + ' You must type a letter, word or phrase before you can hit \"Run Search\"'
+ '.');</script> </body></html>";
}
}


function searchWebcases() {

/*
* Grabs $dbconf and declares variables.
*/
global $dbconf;
/*
* Grabs POST value.
*/
$q = $_POST['search_string'];

/*
* Connect to db.
*/
$con = mysql_connect($dbconf["host"], $dbconf["user"],$dbconf["password"]) ;
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db($dbconf["db"], $con) or die ("Couldn't select the database.");

/*
* Search webcases.
*/
$result = mysql_query("
select
wc.caseid,
wc.request_title,
wc.request_description,
wc.requestor,
wc.created_on,
wc.status,
wc.assigned_to from webcases wc where
lower(wc.request_title) like '%".$q."%'
or
lower(wc.request_description) like '%".$q."%' order by wc.caseid asc");

/*
* build output page.
*/
$headerpage = '<html><head><title>WEBCASES matching your search criteria</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
#mytable, #mytd
{
border-color: #600;
border-style: solid;
}
#mytable
{
border-width: 1px 1px 1px 1px;
border-spacing: 0;
border-collapse: collapse;
}
#mytd
{
margin: 0;
padding: 4px;
border-width: 1px 1px 0 0;
background-color: #FFC;
}
</style></head><body>';

echo $footerpage = '</body></html>';

echo $headerpage . '<table id="mytable"><thead>
<tr>
<th>ID</font></th>
<th>Title</font></th>
<th>Description</font></th>
<th>Requester</font></th>
<th>Created</font></th>
<th>Status</font></th>
<th>Developer</font></th>
</tr></font></thead><tbody>';

while($row = mysql_fetch_array($result)) {

echo("<a target='_blank'>".
'<tr><td id="mytd">'
. $row['caseid'] . '</td><td id="mytd">'
. $row['request_title'] . '</td><td id="mytd">'
. $row['request_description'] . '</td><td id="mytd">'
. $row['requestor'] . '</td><td id="mytd">'
. $row['created_on'] . '</td><td id="mytd">'
. $row['status'] . '</td><td id="mytd">'
. $row['assigned_to'] . '</td><td id="mytd">'
. '</tr>'
."</a> \n");

}

echo '</tbody></table>' . $footerpage;

mysql_close($con);
}

function searchResolutions() {


/*
* Grabs $dbconf and declares variables.
*/
global $dbconf;
/*
* Grabs POST value.
*/
$q = $_POST['search_string'];

/*
* Connect to db.
*/
$con = mysql_connect($dbconf["host"], $dbconf["user"],$dbconf["password"]) ;
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db($dbconf["db"], $con) or die ("Couldn't select the database.");

/*
* Search webcases.
*/
$result = mysql_query("
select
wc.caseid,
wc.resolution,
wc.resolved_on from resolution wc where lower(wc.resolution) like '%".$q."%' order by wc.caseid asc");

/*
* build output page.
*/
$headerpage = '<html><head><title>RESOLUTIONS matching your search criteria</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
#mytable, #mytd
{
border-color: #600;
border-style: solid;
}
#mytable
{
border-width: 1px 1px 1px 1px;
border-spacing: 0;
border-collapse: collapse;
}
#mytd
{
margin: 0;
padding: 4px;
border-width: 1px 1px 0 0;
background-color: #FFC;
}
</style></head><body>';

echo $footerpage = '</body></html>';

echo $headerpage . '<table id="mytable"><thead>
<tr>
<th>ID</font></th>
<th>Resolution</font></th>
<th>Resolved On</font></th>
</tr></font></thead><tbody>';

while($row = mysql_fetch_array($result)) {

echo("<a target='_blank'>".
'<tr><td id="mytd">'
. $row['caseid'] . '</td><td id="mytd">'
. $row['resolution'] . '</td><td id="mytd">'
. $row['resolved_on'] . '</td><td id="mytd">'
. '</tr>'
."</a> \n");

}

echo '</tbody></table>' . $footerpage;

mysql_close($con);
}
?>


Problem is that both query results display in the *same* tab i.e that of my searchWebcases() function.

Is there a way to output the results of searchResolutions() function in its own tab?

CyBerAliEn

5:02 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



First...

Clarification... When you say "tabs", do you mean loading one function's output into one browser tab, and the other function's output to another (separate) browser tab?

If this is the case, your solution lies more within Javascript than with PHP (because PHP does not dictate or control where [window/tab/etc] content is loaded into)... while you can control this with JS.

It seems you have one page that gets the user's search term/phrase... this is then passed into your script which runs it through 2 different functions. To use JS to load results into 2 different tabs, you ought to...

(1) Have your "search page" get the phrase (form). Have it use JS to check if a value is entered. If a value is entered, have JS load "script 1" into the current tab. Then have JS load "script 2" into a new tab.

(2) "script 1" should be a separate PHP script that contains your first function/code. "script 2" should contain your second function/code.

Then, when someone submits a phrase... it will load both of your functions, but one in one tab, one in another tab. It will just require some changes to your "setup" to accomplish this.


Secondly...

You get your "query" from a user in the form through:
$q = $_POST['search_string']; 


You then use this inside your actual mySQL query in PHP as:
$result = mysql_query("
select
wc.caseid,
wc.resolution,
wc.resolved_on from resolution wc where lower(wc.resolution) like '%".$q."%' order by wc.caseid asc");


One big issue I see with this is that you are opening your database/server/website to mySQL injection with this code.

Huh? By just grabbing the user input and throwing it into your database... a "smart" user can send in a value that will allow them to inject their own code into your query. This includes modifying your own tables, data, removing data, etc... even a potential for uploading malicious files onto your server.

To plug this hole, you are strongly encouraged to change your query to the following (at minimum); which will give you reasonable protection against injection:
$result = mysql_query("
select
wc.caseid,
wc.resolution,
wc.resolved_on from resolution wc where lower(wc.resolution) like '%".mysql_real_escape_string($q)."%' order by wc.caseid asc");

CyBerAliEn

5:11 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Some after thoughts...

Thirdly...

Your query is casting "wc.resolution" to lower case, then comparing it to "q". This is a very basic "search". Suppose your "wc.resolution" had a value like:
Why do frogs cross the road at night?

And "q" was: frog

Your query basically turns the sentence to lowercase, and then looks for "%frog%" where "%" indicates it is a wildcard... anything can be before "frog" and/or after "frog" and it will be returned as a result. This works great for a basic search.

But if "q" was Frogs... nothing would be returned (I'm pretty sure on this, I do believe it is case sensitive). You ought to modify your query line to account for this to:
$result = mysql_query("
select
wc.caseid,
wc.resolution,
wc.resolved_on from resolution wc where lower(wc.resolution) like '%".mysql_real_escape_string(strtolower($q))."%' order by wc.caseid asc");


If this is your intent.


If you want to empower your "search" capability... mySQL has a more advanced searching algorithm built in. Using "like" is more of a "matching" game than a "search". Do some research on fulltext searches with mySQL. It will provide a more indepth search (ie: phrases do not have to be exact, they can be close; results are returned in an order according to "best match"; it essentially mimics what you would regularly call a "search").

kristo5747

5:50 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



Thanks for taking the time to deconstruct my code.

I am self-taught and (obviously) make mistakes.

First) Yes, I mean loading one function's output into one browser tab, and the other function's output to another (separate) browser tab. since Javascript is the way, I'll work on it...

Secondly & Thirdly) Though I was aware of SQL injection (at a high level), I honestly never bothered with it since I was on an intranet (I know, I know). I thank you for you suggestions to improve my code.

Readie

6:17 pm on Apr 13, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I honestly never bothered with it since I was on an intranet

Tom in accounting, who has some small knowledge of MySQL, just got upbraided. He goes to the intranet for revenge :)

Seriously though, sometimes when people percieve any offense to themselves at all, they will try and cause damage wherever they can. I strongly suggest you start guarding against SQL injection at all levels, it doesn't take long to type mysql_real_escape_string() around your variable.

kristo5747

6:58 pm on Apr 13, 2010 (gmt 0)

10+ Year Member



It's done: added mysql_real_escape_string().

kristo5747

3:46 pm on Apr 14, 2010 (gmt 0)

10+ Year Member



jQuery did the trick.

I found an example of tabs implementation via jQuery. I simply hacked the code to support my needs. Here it is:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Knowledge Base</title>
<style type="text/css">
body {
background: #f0f0f0;
margin: 0;
padding: 0;
font: 10px normal Verdana, Arial, Helvetica, sans-serif;
color: #444;
}
h1 {
font-size: 3em; margin: 20px 0;
}
.container {
width: 1000px; margin: 50px ;height: 1000px;
}
ul.tabs {
margin: 0;
padding: 0;
float: left;
list-style: none;
height: 32px;
border-bottom: 1px solid #999;
border-left: 1px solid #999;
width: 100%;
}
ul.tabs li {
float: left;
margin: 0;
padding: 0;
height: 31px;
line-height: 31px;
border: 1px solid #999;
border-left: none;
margin-bottom: -1px;
background: #e0e0e0;
overflow: hidden;
position: relative;
}
ul.tabs li a {
text-decoration: none;
color: #000;
display: block;
font-size: 1.2em;
padding: 0 20px;
border: 1px solid #fff;
outline: none;
}
ul.tabs li a:hover {
background: #ccc;
}
html ul.tabs li.active, html ul.tabs li.active a:hover {
background: #fff;
border-bottom: 1px solid #fff;
}
.tab_container {
border: 1px solid #999;
border-top: none;
clear: both;
float: left;
width: 100%;
height: 100%;
background: #fff;
-moz-border-radius-bottomright: 5px;
-khtml-border-radius-bottomright: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomleft: 5px;
-khtml-border-radius-bottomleft: 5px;
-webkit-border-bottom-left-radius: 5px;
}
.tab_content {
padding: 20px;
font-size: 1.2em;
}
.tab_content h2 {
font-weight: normal;
padding-bottom: 10px;
border-bottom: 1px dashed #ddd;
font-size: 1.8em;
}
.tab_content h3 a{
color: #254588;
}
.tab_content img {
float: left;
margin: 0 20px 20px 0;
border: 1px solid #ddd;
padding: 5px;
}
</style>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {

//Default Action
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content

//On Click Event
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the rel attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active content
return false;
});

});
</script>
</head>
<body>
<div class="container">
<h1>Knowledge Base</h1>
<h3>This search engine crawls the online ticketing system for data on resolutions.<p></p>
For a search, enter a word (faster) or letter (slow) to see a list of corresponding ticket titles, design notes or resolutions.</h3>
<form method="post"
id="f1" name="myform" action="<?php echo $_SERVER['PHP_SELF'];?>" >
<input type="text" id="qry" name="search_string" size="60"></input>
<input type="submit" id="rs" name="submit" value="Run Search"></input>
<input type="reset" id="reset" name="reset" value="Clear Search"
></input><p></p>
</form>
<ul class="tabs">
<li><a href="#tab1">Webcases</a></li>
<li><a href="#tab2">Design Notes</a></li>
<li><a href="#tab3">Resolutions</a></li>
</ul>
<div class="tab_container">
<div id="tab1" class="tab_content">
<h2>Search Results</h2>
<p>
<?php
//Includes the db config file
$dbconf = include '/var/www/html/ServiceAndRepair/config/dbConfig.php';

//checks if fields are set.
if(isset($_POST['submit'])) {
if(
!empty($_POST['search_string'])
) {
searchWebcases();
}
}


function searchWebcases() {

/*
* Grabs $dbconf and declares variables.
*/
global $dbconf;
/*
* Grabs POST value.
*/
$q = $_POST['search_string'];

/*
* Connect to db.
*/
$con = mysql_connect($dbconf["host"], $dbconf["user"],$dbconf["password"]) ;
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db($dbconf["db"], $con) or die ("Couldn't select the database.");

/*
* Search webcases.
*
* Uses `mysql_real_escape_string()` as safeguard against SQL injection.
* Function `mysql_real_escape_string()` escapes special characters in a string for use in a SQL statement.
*
*/
$result = mysql_query("
select
wc.caseid,
wc.request_title,
wc.request_description,
wc.requestor,
wc.created_on,
wc.status,
wc.assigned_to from webcases wc where
lower(wc.request_title) like '%".mysql_real_escape_string($q)."%'
or
lower(wc.request_description) like '%".mysql_real_escape_string($q)."%' order by wc.caseid asc");


/*
* build output page.
*/
$headerpage = '<html><head><title>WEBCASES matching your search criteria</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
#mytable, #mytd
{
border-color: #600;
border-style: solid;
}
#mytable
{
border-width: 1px 1px 1px 1px;
border-spacing: 0;
border-collapse: collapse;
}
#mytd
{
margin: 0;
padding: 4px;
border-width: 1px 1px 0 0;
background-color: #FFC;
}
</style></head><body>';

echo $footerpage = '</body></html>';

echo $headerpage . '<table id="mytable"><thead>
<tr>
<th>ID</font></th>
<th>Title</font></th>
<th>Description</font></th>
<th>Requester</font></th>
<th>Created</font></th>
<th>Status</font></th>
<th>Developer</font></th>
</tr></font></thead><tbody>';

while($row = mysql_fetch_array($result)) {

echo("<a target='_new'>".
'<tr><td id="mytd">'
. $row['caseid'] . '</td><td id="mytd">'
. $row['request_title'] . '</td><td id="mytd">'
. $row['request_description'] . '</td><td id="mytd">'
. $row['requestor'] . '</td><td id="mytd">'
. $row['created_on'] . '</td><td id="mytd">'
. $row['status'] . '</td><td id="mytd">'
. $row['assigned_to'] . '</td><td id="mytd">'
. '</tr>'
."</a> \n");

}

echo '</tbody></table>' . $footerpage;

mysql_close($con);
}?>
</p>
</div>
<div id="tab2" class="tab_content">
<h2>Search Results</h2>
<p>
<?php
//Includes the db config file
$dbconf = include '/var/www/html/ServiceAndRepair/config/dbConfig.php';

//checks if fields are set.
if(isset($_POST['submit'])) {
if(
!empty($_POST['search_string'])
) {
searchWip();
}
}

function searchWip() {
/*
* Grabs $dbconf and declares variables.
*/
global $dbconf;
/*
* Grabs POST value.
*/
$q = $_POST['search_string'];

/*
* Connect to db.
*/
$con = mysql_connect($dbconf["host"], $dbconf["user"],$dbconf["password"]) ;
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db($dbconf["db"], $con) or die ("Couldn't select the database.");

/*
* Search resolutions. Uses `mysql_real_escape_string()` as safeguard against SQL injection.
* Function `mysql_real_escape_string()` escapes special characters in a string for use in a SQL statement.
*/
$result = mysql_query("
select
wc.caseid,
wc.design_notes,
date(wc.as_of) as_of from wip wc where lower(wc.design_notes) like '%".mysql_real_escape_string(strtolower($q))."%' order by wc.caseid asc");

/*
* build output page.
*/
$headerpage = '<html><head><title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
#mytable, #mytd
{
border-color: #600;
border-style: solid;
}
#mytable
{
border-width: 1px 1px 1px 1px;
border-spacing: 0;
border-collapse: collapse;
}
#mytd
{
margin: 0;
padding: 4px;
border-width: 1px 1px 0 0;
background-color: #FFC;
}
</style></head><body>';

echo $footerpage = '</body></html>';

echo $headerpage . '<table id="mytable"><thead>
<tr>
<th>ID</font></th>
<th>Design Notes</font></th>
<th>As Of</font></th>
</tr></font></thead><tbody>';

while($row = mysql_fetch_array($result)) {

echo("<a target='_new'>".
'<tr><td id="mytd">'
. $row['caseid'] . '</td><td id="mytd">'
. $row['design_notes'] . '</td><td id="mytd">'
. $row['as_of'] . '</td><td id="mytd">'
. '</tr>'
."</a> \n");

}

echo '</tbody></table>' . $footerpage;

mysql_close($con);
}?>
</p>
</div>
<div id="tab3" class="tab_content">
<h2>Search Results</h2>
<p>
<?php
//Includes the db config file
$dbconf = include '/var/www/html/ServiceAndRepair/config/dbConfig.php';

//checks if fields are set.
if(isset($_POST['submit'])) {
if(
!empty($_POST['search_string'])
) {
searchResolutions();
}
}

function searchResolutions() {
/*
* Grabs $dbconf and declares variables.
*/
global $dbconf;
/*
* Grabs POST value.
*/
$q = $_POST['search_string'];

/*
* Connect to db.
*/
$con = mysql_connect($dbconf["host"], $dbconf["user"],$dbconf["password"]) ;
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db($dbconf["db"], $con) or die ("Couldn't select the database.");

/*
* Search resolutions. Uses `mysql_real_escape_string()` as safeguard against SQL injection.
* Function `mysql_real_escape_string()` escapes special characters in a string for use in a SQL statement.
*/
$result = mysql_query("
select
wc.caseid,
wc.resolution,
date(wc.resolved_on) resolved_on from resolution wc where lower(wc.resolution) like '%".mysql_real_escape_string(strtolower($q))."%' order by wc.caseid asc");

/*
* build output page.
*/
$headerpage = '<html><head><title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
#mytable, #mytd
{
border-color: #600;
border-style: solid;
}
#mytable
{
border-width: 1px 1px 1px 1px;
border-spacing: 0;
border-collapse: collapse;
}
#mytd
{
margin: 0;
padding: 4px;
border-width: 1px 1px 0 0;
background-color: #FFC;
}
</style></head><body>';

echo $footerpage = '</body></html>';

echo $headerpage . '<table id="mytable"><thead>
<tr>
<th>ID</font></th>
<th>Resolution</font></th>
<th>Resolved On</font></th>
</tr></font></thead><tbody>';

while($row = mysql_fetch_array($result)) {

echo("<a target='_new'>".
'<tr><td id="mytd">'
. $row['caseid'] . '</td><td id="mytd">'
. $row['resolution'] . '</td><td id="mytd">'
. $row['resolved_on'] . '</td><td id="mytd">'
. '</tr>'
."</a> \n");

}

echo '</tbody></table>' . $footerpage;

mysql_close($con);
}?>
</p>
</div>
</div>
</div>
</body>
</html>


It is not 100% production ready but it is working like I want. :D

CyBerAliEn

4:02 pm on Apr 14, 2010 (gmt 0)

10+ Year Member



Good to see you found a solution!

Your original post indicated you wanted to do "browser tabs"... this is obviously "harder" to implement.

Building your own HTML "tabs" within your page, and manipulating with JS is considerably easier/better. :)

kristo5747

5:03 pm on Apr 14, 2010 (gmt 0)

10+ Year Member



I am beginning to realize how easy it is to build anything I want in an HTML page as opposed to the browser itself.

Live and learn.

[edited by: kristo5747 at 5:04 pm (utc) on Apr 14, 2010]

kristo5747

5:03 pm on Apr 14, 2010 (gmt 0)

10+ Year Member



By the way...jQuery kicks a**!

CyBerAliEn

8:11 pm on Apr 14, 2010 (gmt 0)

10+ Year Member



^It does very much!

Aside from its great ability to manipulate the DOM (ie: add a class, remove a class; select specific items; get attributes; etc)... it also lots of great abilities that easily enhance functionality... I really like the visual effects: hiding/showing, fading in/out, sliding up/down, etc. It also has AJAX functionality built in. All in all, a great framework! :)

I'm sure you've checked it out, but look through this:
[docs.jquery.com ]

Lots of great abilities/functions/methods!