Using a Variable from a Javascript Function - javascript

OK, I'm fairly new to javascript and am trying to make this script work. I don't know the terms of javascript enough to search for this I guess because it seems like a fairly easy thing to do, but it is not working. The links are supposed to open a side menu that slides across the screen and displays different data depending on which link is clicked.
My Script:
/* Open the sidenav */
function openNav(boxid) {
document.getElementById(boxid).style.width = "100%";
}
/* Close/hide the sidenav */
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
My Body:
include('dbconn.php');
$sql = 'SELECT * FROM joblist';
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
echo '<span onclick="openNav(mySidenav- '.$row['jobname'].')">'.$row['jobname'].'</span><br>';
echo '<div id="mySidenav-'.$row['jobname'].'" class="sidenav">';
echo '×';
$eachrow = explode("," , $row["itemlist"]);
$arrlength = count($eachrow);
for($x = 0; $x < $arrlength; $x++) {
echo $eachrow[$x];
echo "<br>";
}
echo "</div>";
}
I'm not sure why boxid isn't sending the variable I place in each onclick

Look at what you're doing:
echo '<span onclick="openNav(mySidenav- '.$row['jobname'].')">'.$row['jobname'].'</span><br>';
That'll generate some html that looks like
<span onclick="openNav(mySidenav- jobname)">jobname</span><br>
That opennav call is doing a mathematical subtraction of two undefined variables, and sending the result of that undefined operation as an argument to the function.
You probably want something more like:
echo '<span onclick="openNav(\'mySidenav'.$row['jobname'].'\')">'.$row['jobname'].'</span><br>';
^^----------------------------^^
Note the extra (escaped) quotes, which now produces
<span onclick="openNav('mySideNav-jobname')">jobname</span><br>
Now your argument is a string, not a math operation.

Related

Use of PHP script in a jquery function

I've echoed the following php and it shows up properly in HTML so that can't be a problem:
PHP
if (mysqli_num_rows($result) > 0) {
//create the drop down menu
$list ="";
while($row = mysqli_fetch_assoc($result)) {
$list = '<div class="dropOption">'.$row["item"].'</div>';
}
This outputs three rows - apple, pear, strawberry - in the right div format.
And when I put the following php script into the jquery function below, the menu does contain the value strawberry (the last), however the first two are missing.
JavaScript
//drop down menu
$(document).ready(function(){
function createDropdown(){
var drop = $('#customDropdown');
var i;
var htmlString = '<div id="dropContainer">';
htmlString += '<?php echo $list;?>';
htmlString += '</div>';
drop.append(htmlString);
}
createDropdown();
I'm new to jquery and php so forgive me if the error is simple; however I'm pretty sure it's right, functionally speaking, because I'm getting something; so I figured the syntax must get be wrong somewhere. Can anybody help? Thanks in advance.
In your php it should be
$list .= '<div class="dropOption">'.$row["item"].'</div>';
and then output just like this <?=$list;?> in your js part
. is used to concatenate strings in php
You're only assigning the last item to the $list variable. You need to concatenate them all together.
Try:
if (mysqli_num_rows($result) > 0) {
// Create the drop down menu
$list = "";
while($row = mysqli_fetch_assoc($result)) {
$list .= '<div class="dropOption">' . $row["item"] . '</div>';
}
}
Note the $list .= instead of $list = part.

Why would the second time using a search cause it to stop the drop down list?

I have a jQuery drop down list that uses first CARS then secondly, the models from that car. Then, when the second choice is made - hit a submit button and search for the tire that the car uses. It works great the first time, but the second time, it stops and I have to reload the page to get it to work again. Any ideas of why this is happening would be helpful. My code example is here:
Accessing a variable from inside a jquery drop down list?
Here is the code that searches:
function findtire() {
global $db;
if (isset($_POST['car'])) {
$_SESSION['car'] = $_POST['car'];
$car = $_SESSION['car'];
}
if (isset($car)) {
$query = $db->prepare("SELECT idtires FROM vehicle WHERE idcarmodel = '$car'");
$query->execute();
$tire = $query->fetchAll();
}
if (isset($tire)) {
echo "<ul>";
foreach ($tire as $name) {
echo "<li id='tiresearch'>";
echo "Tire Size is Available: " . $name['idtires'];
echo "</li>";
}
echo "</ul>";
}
else {
}
}

javascript call inside php where loop not working and breaks query

I am attempting to call a javascript function inside a php where loop. I've succeeded in calling the variable, however the function only works on the first line, and then breaks a subsequent query.
The javascript is a simple show/hide of a div or span tag with a specific id. I'm trying to have this appear for every instance of a variable, but only open the span associated with that entry, so I used a php variable from the query.
The javascript code is contained in the header; it works fine without the php, and the php works fine without the javascript but I can't seem to make them work together.
Here's the code:
while($row = mysqli_fetch_array($qir)) {
$ingredient_id = $row['ingredient_id'];
echo '<input type="checkbox" value="' . $ingredient_id . '" name="markdelete[]">';
echo $row['amt'] . ' ' .$row['ingredient_name']; ?> <button onclick="showHide('<?php echo $row['ingredient_id']; ?>'); return false">Edit amount</button> <br />
<span id="<?php echo $row['ingredient_id']; ?>" class="hide">
<?php include_once('amt.php');
echo '</span> ';
// }
echo '<br />';
}
echo '<input type ="submit" name="remove" value="Remove">';
First of all, the showHide is only working on the first record
It is also making this query not respond at all.
if (isset($_POST['remove'])) {
iF (!empty($_POST['markdelete'])) {
foreach ($_POST['markdelete'] as $delete_id) {
// remove specific source from source_subject
$rem_ing = "DELETE from dish_ingredient
where ingredient_id = $delete_id
and dish_id = $dish_id ";
mysqli_query($dbc, $rem_ing)
or die ('Error removing ingredient: '.mysqli_error($dbc));
}
}
}
I tried removing the return false;, to no avail. Please let me know if I need to show more of the code (e.g. the javascript itself)
Edit:
I've tried working within the php string (this is actually what I had tried first) but it seems to break everything (no javascript, no php)
echo $row['amt'] . ' ' .$row['ingredient_name'] . '<button onclick="showHide(\''. $row['ingredient_id'] .'\') return false">Edit amount</button> <br />';
echo '<span id=" '. $row['ingredient_id'] .' " class="hide">';
include_once('amt.php');
echo '</span> ';
Edit: I am open to other solutions if this is not something that is possible. I'm feeling a bit stumped. Realistically I just want to have a list of items called from a mysql database, and have a field appear onclick to edit an associated variable if desired without having to send it to another page or reload the script for usability (hence the javascript piece).
Thanks again, anyone who can assist.
Note: this is the script that I am calling:
<script language="JavaScript" type="text/JavaScript">
menu_status = new Array();
function showHide(theid){
if (document.getElementById) {
var switch_id = document.getElementById(theid);
if(menu_status[theid] != 'show') {
switch_id.className = 'show';
menu_status[theid] = 'show';
}else{
switch_id.className = 'hide';
menu_status[theid] = 'hide';
}
}
}
</script>
You don't need tag there as you are already in php block.Try it without and use
showHide(\''.$row['ingredient_id'].'\')
and change
<?php include_once(....);
to
include_once(........);
Hopefully that would work
===========
try this for you javascript
<script language="JavaScript" type="text/JavaScript">
function showHide(theid){
if (document.getElementById) {
var switch_id = document.getElementById(theid);
if(!switch_id) {
switch_id.className = (switch_id.className.indexOf("show") > -1) ? "hide" : "show"
}
}
}
Okay after a long time on this, I finally figured out what was going on. Part of the issue was that I was trying to call a form inside a form, which I had forgotten is not permitted in HTML, so this required some redesign.
Other issues involved calling loops within inside loops, which caused problems where the first record would work, but not for the remaining records.
The javascript above did not need to be modified, only the way that it was called.
Here is what worked. The main key was using include() instead of include_once().
while($r = $qir->fetch_assoc()) {
$ingredient_id = $r['ingredient_id'];
$amt = $r['amt'];
$ingredient_name = $r['ingredient_name'];
echo $r['amt'] . ' ' .$r['ingredient_name'];
if ($row['user_id'] == $user_id) {
echo ' <span class="openlink"><button onclick="showHide(\''.$ingredient_id. '\')">edit amount</button></span><br/>';
echo '<div id="'.$ingredient_id.'" class="hide">';
include('amt1.php');
echo '</div>';
}
}

Accessing JSON results from jQuery Ajax

I'm working on a web application to maintain the administration for a restaurant kind of type. The idea is to make new orders, put order items in that, check finance overviews etc...
I've also got a function to see all the orders in a list, when you select one of them, the order data (such as the name, emailadress, location of the customer) shows up in a another element inside the document.
I'm doing that with this function, every tr inside the has been given a custom attribute; the order_id. When selecting that, a class is given, called selectedRow.
function select_order(order) {
var item = $(order);
if (!item.hasClass("selectedRow")) {
if (!selectedOrderInformation.is(":visible")) {
switchScreen(selectedOrderInformation, financeOverview);
}
item.parent().find(".selectedRow").removeClass("selectedRow");
item.addClass("selectedRow");
selectedOrderInformation.html("loading......");
$.ajax({
url: "includes/functions/select-order.php",
type: "get",
data: {order_id: item.attr("data-order-index")},
success: function (data) {
selectedOrderInformation.html(data);
$("#delete-order-btn").prop("disabled", false);
}
});
} else {
console.log("DEBUG: Row is already selected");
}
}
The usage of that function is by doing this:
$("#list tbody tr").click(function () {
select_order(this);
});
At the first place, i was deploying all the HTML data via PHP. This took a pretty long time, it could take from 500ms to about 1 second. In my opinion thats pretty long.
I was doing that like this (select-order.php):
if (!empty($_GET['order_id'])) {
$order_id = $_GET['order_id'];
$order_data = Database::getInstance()->get_all_data_by_order_id($order_id);
$order_items = Database::getInstance()->get_order_items_by_order_id($order_id);
while ($row = mysqli_fetch_array($order_data)) {
echo "<h1>Klant informatie</h1>";
echo "<p>Voornaam: " . $row['first_name'] . "</p>";
echo "<p>Achternaam: " . $row['last_name'] . "</p>";
echo "<p>Emailadres: " . $row['email_adress'] . "</p>";
echo "<p>Klant informatie: " . $row['customer_info'] . "</p>";
echo "<br>";
echo "<h1>Bestellingsinformatie</h1>";
echo "<p>Order informatie: " . $row['order_info'] . "</p>";
echo "<p>Locatie: " . $row['location'] . "</p>";
echo "<p>Gemaakt op: " . $row['created'] . "</p>";
}
echo "<br>";
echo "<table>";
echo "<thead>";
echo "<tr>";
echo "<th>Product naam</th>";
echo "<th>Hoeveelheid</th>";
echo "</tr>";
echo "</thead>";
while ($row = mysqli_fetch_array($order_items)) {
echo "<tr>";
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['quantity'] . "</td>";
echo "</tr>";
}
echo "</table>";
exit;
}
This goes together with the Database class with all the functions:
class Database extends mysqli
{
// single instance of self shared among all instances
private static $instance = null;
private $databaseHost = "";
private $databaseUser = "";
private $databasePassword = "";
private $databaseName = "";
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
public function __wakeup() {
trigger_error('Deserializing is not allowed.', E_USER_ERROR);
}
function __construct() {
parent::__construct($this->databaseHost, $this->databaseUser, $this->databasePassword, $this->databaseName);
if (mysqli_connect_error()) {
exit('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
}
parent::set_charset('utf-8');
}
function get_all_data_by_order_id($order_id) {
$query = "SELECT customers.first_name,
customers.last_name,
customers.email_adress,
customers.customer_info,
orders.order_info,
orders.total_price,
orders.location,
orders.created
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id
WHERE orders.id = {$order_id}";
return $this->query($query);
}
function get_order_items_by_order_id($order_id) {
$query = "SELECT `products`.`name`, `orders-items`.`quantity` FROM `orders-items`\n" . "INNER JOIN `products`ON `orders-items`.`products_id` = `products`.`id`\n" . "WHERE order_id=" . $order_id;
return $this->query($query);
}
}
Now someone told me i could better translate the data into json and return that, so i did this:
if (!empty($_GET['order_id'])) {
$order_id = $_GET['order_id'];
$order_data = Database::getInstance()->get_all_data_by_order_id($order_id);
$order_items = Database::getInstance()->get_order_items_by_order_id($order_id);
$rows = array();
while ($row = mysqli_fetch_array($order_data)) {
$rows[] = $row;
}
return json_encode($rows);
exit;
}
But as expected, nothing really happened. So i tried changing the javascript to this (trying it as a array because i'm returning it that way?), to deploy one piece of data:
$.ajax({
url: "includes/functions/select-order.php",
type: "get",
data: {order_id: item.attr("data-order-index")},
success: function (data) {
selectedOrderInformation.html(data['first_name']);
}
});
But that didn't work aswell.
Problems
The previous PHP code was to slow, so i had to find another way.
When trying to deploy HTML into the other screen, it doesnt do anything. It stays on the 'loading...' screen, so the success function was'nt reached.
Question
How can my piece of code be changed so it will actually deploy parts of the data from the mysql database?
In your $.ajax() call you should define what type your response data is expected to be, by adding the following parameter to the call:
dataType: 'json'
Also, you should try echo json_encode($rows); your data instead of returning it.
**Edit: you are receiving an array of arrays, so your original referencing in the success callback won't suffice. Having another look at your MySQL part, If you are only expecting one row to be returned by your query, then you can change your PHP to:
$row = mysqli_fetch_array($order_data);
echo json_encode($row); // instead of $rows
instead of the while loop. That way your selectedOrderInformation.html(data['first_name']); will most likely work.
To clean your query up a bit:
$query = "SELECT p.name, ot.quantity FROM orders-items AS ot
LEFT JOIN products AS p ON ot.products_id = p.id
WHERE ot.order_id = " . $order_id;
You could also switch your INNER JOIN to a LEFT JOIN in your "get order data" function. An inner join is absolutely useless here, as you'll have all your data paired based on the foreign keys anyways.
I would try secluding some of the codebase: try commenting out the Database::getInstance() calls, and supplementing some testdata into the processes. To put it short, fake a returned response, by declaring a $row = array('first_name' => 'Joe', 'order_date' => '2014-08-29 11:11:52', ...); and returning that. If its way faster, then your database server might be the bottleneck. If its still slow, then 500ms - 1000ms is actually argueably code related, it might be other hardware aspects that cause the problem. Or for example, do you have your jQuery library loaded from a CDN, or locally?
**Edit: As #Debflav pointed out (and I've also touched upon the matter), that your queries could benefit from not being executed as simple queries, but transforming them into prepared statements. For the full story you could start checking out PHP.net : Prepared Statements, or to keep it short:
Prepared statements look almost just like your everyday query, however variables are not just concatenated into the query string, rather bindings are used.
You use the database handler's prepare function instead of query - with this method, you are requesting the MySQL server to inspect your query and optimize it for later use (which will come handy if you're doing the same query over and over again, just with a few varying values).
For more detailed insights on the mechanics of prepared statements and how to get the hang of it for efficiently utilizing it in your projects I recommend you research the topic a bit, but as a quick conversion for your example at hand, it would look like this:
function get_all_data_by_order_id($order_id) {
$query = "SELECT c.first_name, c.last_name, c.email_adress, c.customer_info,
o.order_info, o.total_price, o.location, o.created
FROM customers AS c
LEFT JOIN orders AS o ON c.id = o.customer_id
WHERE o.id = :order_id";
$query_params = array(
':order_id' => $order_id
);
$preparedStatement = $this->prepare($query);
return $preparedStatement->execute($query_params);
}
and
function get_order_items_by_order_id($order_id) {
$query = "SELECT p.name, ot.quantity FROM orders-items AS ot
LEFT JOIN products AS p ON ot.products_id = p.id
WHERE ot.order_id = :order_id;";
$query_params = array(
':order_id' => $order_id
);
$preparedStatement = $this->prepare($query);
return $preparedStatement->execute($query_params);
}
And to reflect on how you would build up your JSON response with data including the order headers and the connected order-items would be:
if (!empty($_GET['order_id'])) {
$order_id = $_GET['order_id'];
$order_data = Database::getInstance()->get_all_data_by_order_id($order_id);
$order_items = Database::getInstance()->get_order_items_by_order_id($order_id);
$orderObject = array();
$orderObject['header'] = mysqli_fetch_array($order_data);
$orderObject['items'] = array();
while ($orderedItem = mysqli_fetch_array($order_items)){
$orderObject['items'][] = $orderedItem;
}
echo json_encode($orderObject);
}
This way your jQuery could look something as follows:
....
success: function (data) {
selectedOrderInformation.html('<h3>' + data['header']['first_name'] + '</h3><ul>');
$.each(data['items'], function(i, item) {
selectedOrderInformation.append('<li>' + item['name'] + ' x ' + item['quantity'] + '</li>');
});
selectedOrderInformation.append('</ul>');
}
....

loading php page only when the div containing him becomes visible

i make some sort of a shopping cart that when i press on a table line it suppose to open some details about the item, for this purpose i used a div which is at height 0 and hidden at first which contains the details, the problem is that i think that the browser will load the the info pages regardless of if the line was pressed or not. is there any way to make the browser load the page only when his DIV is visible?
$int = 0;
echo "<table class=\"result_table\" id=\"result_table\">";
foreach($types as $data){
echo "<tr onClick=\"present(".$int.");\" >";
echo "<td align=\"right\">";
echo $data['number'];
echo "</td>";
echo "<td align=\"right\">";
echo $data['item_name'];
echo "</td>";
echo "<td align=\"right\">";
echo $data['amount'];
echo "</td>";
echo "<td align=\"right\">";
echo "17";
echo "</td></tr>";
echo "<tr class=\"info_row\"><td colspan=\"4\"><div id=\"div_num_".$int."\" style=\"height:0px\">
<object type=\"text/html\" data=\"page.php\" style=\"width:100%; height:100%; margin:0%;\">
</div></td></tr>";
$int++;
}
echo "</form></table>";
the css for the row
.info_row{
visibility:hidden;
}
the JS:
function present(item_id){
var div = document.getElementById("div_num_"+item_id);
if(div.style.visibility=="visible"){
div.style.visibility = 'hidden';
div.style.height= '0';
} else {
div.style.visibility = 'visible';
div.style.height= "200px";
}
}
as you can see all the info loads with the page but are invisible.
other good ways of tackling this problem will be appritiated especially if it does not include jquery because i am not really strong in it.
thanks in advance.
Firstly, if there isn't much info to load, preloading the data is probably more sensible anyway. Users want a responsive UI, even if it means a few extra milliseconds of initial download time for data they'll never see.
But, if you insist on loading the data separately, you could use an xmlhttprequest to load a representation of the data (such as in JSON), and use a templating solution to output the result into the info div.
The page that might generate the JSON representation of the data might look something like this:
<?php
$result = array();
// ... Code that defines type ... //
$int = 0;
foreach($types as $data){
$result[] = array(
"int" => $int,
"number" => $data["number"],
"item_name" => $data["item_name"],
"amount" => $data["amount"]
);
$int++;
}
echo json_encode($result);
?>
So, when a user clicks a link, the above page would load in an xmlhttprequest. You could then parse the result with JSON.parse(req.responseText), and apply an HTML template to the result (check out the above link, plus this one, for more info on how to do that).
Again, you're probably fine just loading all the data in one go. Extra HTTP headers actually make pages take longer to completely load.
You can use an ajax call:
with javascript
<script type="text/javascript">
function loadInfoRow()
{
var xmlhttp;
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var responseText = xmlhttp.responseText;
//Use the response text to add the extra row
}
}
xmlhttp.open("GET","info.txt",true);
xmlhttp.send();
}
</script>
with jquery
$.ajax({
url: "info.txt",
context: document.body,
success: function(text){
//where text will be the text returned by the ajax call
$(".result_table).append(text);
}
});

Categories