Javascript not printing within php loop - javascript

new to php and javascript. I am trying to print an id using javascript within a php loop and nothing is turning up. Here is the code:
$sql = "SELECT dueDate, assignmentName, className FROM assignments INNER JOIN classes ON assignments.class = classes.id ORDER BY DATE(dueDate)";
if ($result = mysqli_query($link, $sql)) {
if (mysqli_num_rows($result) > 0) {
echo "Assignments";
while ($row = mysqli_fetch_array($result)) {
echo '<div class="popup" id="popup">';
echo '<div class="overlay"></div>';
echo '<div class = "content">' . $row['dueDate'] . $row['className'] . '</div>';
echo '<div class="close-btn content" onclick="togglePopup()">×</div>';
echo '<div class = "btn-group">' . '<button onclick="togglePopup()">' . $row['assignmentName'] . '</button>' . '</div>';
echo '</div>';
echo '<script type=\"text/javascript\"> document.write(printID()); </script>';
}
}

The problem is, that you want PHP to know, what printID() is and what it should do. PHP knows nothing about JavaScript functions, because JavaScript and PHP are executed on totally different places. PHP renders your HTML and sends a response to your browser, which executes JavaScript. JavaScript will not be executed, when PHP is processing data.
There 's one thing you could do. Wait until everything is rendered and execute your JavaScript functions at the end of your HTML before the </body> tag.
document.addEventListener('DOMContentLoaded', (event) => {
const elements = document.querySelectorAll('.popup');
Array.prototype.forEach.call(elements, (element) => {
let id = printID();
element.appendChild(document.createTextNode(id));
});
});
What does the above code snippet? It waits and will be executed, until all DOM is loaded. Then it searches for all elements with the css class named "popup". By the way there is another issue in your code. You 're processing your database query result with a loop and you 're using an id attribute. Id attributes should only be used once in your markup. So please use a css class instead of an id attribute. When using a class names "popup" you can read out all elements and execute your javascript function printID() and append a new element. That 's it.
Your failure is, that you didn 't recognize, that JavaScript is a client side language and is not executed by php. Even when it 's written in an html template.
A possible better approach
As you said you want to change a parameter in your togglePopup JavaScript function. The following code shows up a possible solition.
<?php
...
$i = 0;
while ($row = mysqli_fetch_array($result)) {
echo '<div class="popup">';
echo '<div class="overlay"></div>';
echo '<div class = "content">' . $row['dueDate'] . $row['className'] . '</div>';
echo '<div class="close-btn content">×</div>';
echo '<div class = "btn-group">' . '<button id="popup-' . $i . '">' . $row['assignmentName'] . '</button>' . '</div>';
echo '</div>';
$i++;
}
Instead of placing onclick attributes just leave this out. Instead place an id parameter on the button element. Keep in mind, that tha value of a id parameter has to be unique. Instead of using an id attribute, you can use a data attribute like data-id="my-value". Data attributes ensure, that the value of this attribute has not to be unique. Just to show you to possible ways ...
At the end of your HTML before the </body> tag place the following.
<script>
const togglePopup = (event) => {
let target = event.target;
let id = target.getAttribute('id');
// do something with the id attribute
}
document.addEventListener('DOMContentLoaded', (event) => {
const elements = document.querySelectorAll('.popup button[id^="popup-"]');
Array.prototype.forEach.call(elements, (element) => {
element.addEventListener('click', togglePopup);
});
});
</script>
This small snippet adds a click event handler to every button inside an element with the class .popup which has an id attribute which begins with popup-. When this button will be clicked the togglePopup function will be called. Inside this function the id attribute comes from the target element.
With this solution you keep your html markup clean and all javascript stuff is separated from the php code.

Related

Incorrect argument being passed to javascript

I am building a simple website for my family to track the jigsaw puzzles they own. One feature is the ability to delete a puzzle they no longer own. I intend to pass the row ID to a separate file as an argument, but thought I should put a javascript confirmation popup in the middle. I seem to have everything running almost correctly, but the argument being passed is incorrect and I don't know why. It is passing the ID of the last row in the table, rather than the current row ID. Hoping someone can point me in the right direction.
PHP Code
while ($row = $result->fetch_assoc()) {
echo "<script>var puzzleID = " . $row['id'] . "</script>";
echo "<td><a href='puzzleedit.php?=" . $row['id'] . "'>Edit</a> | <button onclick='confirmationBox()'>Delete</button></td>";
}
JS Code in a separate file
function confirmationBox() {
if (confirm("Are you sure you want to delete this puzzle?")) {
window.location = './puzzledelete.php?=' + puzzleID
} else {
}
}
The interesting thing is that using $row['id'] in the edit link works as expected, it is grabbing the correct row ID from the database. The $row['id'] in the script is grabbing the table's last row ID.
Your loop keeps reassigning puzzleId. When you call confirmationBox(), it will have the last value that was assigned, not the one that was assigned before each <td>.
Instead of using a global variable, use a function parameter.
while ($row = $result->fetch_assoc()) {
echo "<td><a href='puzzleedit.php?=" . $row['id'] . "'>Edit</a> | <button onclick='confirmationBox(" . $row['id'] . ")'>Delete</button></td>";
}
function confirmationBox(puzzleID) {
if (confirm("Are you sure you want to delete this puzzle?")) {
window.location = './puzzledelete.php?=' + puzzleID
} else {
}
}

PHP modify fetched variable and return to frontend for JS

Im fetching Product Attributes from Woocommerce, and echo them out in a script tag as variable to use with javascript in frontend.
This might be a bad practice, feel free to enlighten me.
Example:
Product Attributes:
Total height: 43m
Total length: 55m
PHP queries "Total-height" as Attribute Name and "43m" as Attribute Value.
PHP replaces empty space with "-".
I can't define a javascript var with "-" in var name.
Example: var Total-height = "43m";
How could I fix this issue?
Here is my code.
Thanks in advance.
function product_attribute_dimensions(){
global $product;
foreach ($product->get_attributes() as $taxonomy => $attribute_obj ) {
// Get the attribute label
$attribute_label_name = wc_attribute_label($taxonomy);
$value = $product->get_attribute($taxonomy);
if ($value) {
$label = get_taxonomy($taxonomy)->labels->singular_name;
$profile_one = $value;
echo '<script>' . $attribute_label_name . ' = "' . $value . '";
</script>';
}
}
try using window["variable_name"]
do this:
echo '<script>window["' . $attrname . '"]=' . $attrval
then in your js:
let this_var = window[attrname]
It seems like the clearest shortest way to do this.
As I understand the generated string in the variable "$attribute_label_name" is the problem? Take a look at https://www.php.net/manual/de/function.str-replace.php
With this native PHP function you can search for a character (eg."-") and replace with something else (eg. "_")
echo '<script>' . str_replace("-", "_", $attribute_label_name) . ' = "' . $value . '";
But as you said, this might not be the best approach. I personally would add this kind of information into a "data-X" HTML attribute in some HTML element and would extract this in my JS. Similar to this:
<div id="some_element" class="could be hidden" data-total-height="<?= $value ?>"></div>
You could Query something like this with jQuery $("#some_element").attr("data-total-height")
function product_attribute_dimensions() {
global $product;
$product_atrributes = array();
foreach ($product->get_attributes() as $taxonomy => $attribute_obj) {
// Get the attribute label
$attribute_label_name = wc_attribute_label($taxonomy);
$attribute_label_name = str_replace(' ', '_', $attribute_label_name);
$value = $product->get_attribute($taxonomy);
if ($value) {
$product_atrributes[$attribute_label_name] = $value;
}
}
echo '<script type="text/javascript">var product_atrributes = ' . json_encode($product_atrributes) . ';</script>';
}
Now you can use in JS like product_atrributes.Total_height.value
This way the redundant script tag also can be avoided.

Change of div in the same page without refresh

In one of my pages, I have an <a> tag. When I click it, I am passing the variable as a GET parameter and retrieving it in the same page and displaying the details.
The code to get the parameters:
if(isset($_GET['CatId']))
{
$CatId= $_GET['CatId'];
}
else $CatId=0;
if(isset($_GET['MainProductId']))
{
$MainProductId= $_GET['MainProductId'];
$FilterAllProductQuery ="WHERE Product.MainProductId = '$MainProductId'";
$FilterProductQuery = "AND Product.MainProductId = '$MainProductId'";
}
else
{
$MainProductId=0;
$FilterAllProductQuery="";
$FilterProductQuery="";
}
The <a> tag:
<a href='Products.php?CatId=<?php echo $CatId;?>&MainProductId=<?php echo $id;?>' ><?php echo $row["MainProdName"] ?></a>
The details to be displayed:
if($CatId == 0)
{$sql = "SELECT *,Product.Id AS ProdId, Product.Name as ProdName FROM Product $FilterAllProductQuery ";}
else
{$sql = "SELECT * ,Product.Id AS ProdId, Product.Name as ProdName FROM Product INNER JOIN MainProduct ON MainProduct.Id = Product.MainProductId
INNER JOIN Category ON Category.Id = MainProduct.CategoryId WHERE Category.Id = '$CatId' $FilterProductQuery ";}
$result1 = $dbcon->query($sql);
if ($result1->num_rows > 0) {
while ($row = $result1->fetch_assoc()) {
$id = $row["ProdId"];
// $image=$row["ImagePath1"];
$qty = $row["Quantity"];
?>
<li class="col-lg-4">
<div class="product-box">
<span class="sale_tag"></span>
<div class="row">
<img src='themes/images/<?php echo $row["ImagePath1"]; ?>' height='200' width='250'> </a></div></div></li>
Now the code is working fine, but what's happening is that when I click the <a> tag, as I am passing the get parameters, the page is refreshing. As all the code are on the same page, I don't want the page to be refreshed. For that, I need to use Ajax request. How can I do that?
I would make an onclick() event on the a tag like so:
<?php echo '<a c_id="'.$CatId.'" MainProductId="'.$id.'" onclick="sendProduct()">'.$row["MainProdName"].'</a>';
Afterwards i would in a .js file write a simple function called sendProduct() and inside i would do an ajax request to a page named ex: insertproduct.php, get the information back and Insertproduct.php would process the data and you could use .html() or .append() to assign the data to the div showing the data with a normal id.
The c_id, MainProductId are custom attributes you could recieve in the .js file as $("#youraTag").attr("c_id");
There's a really good guide here on basic ajax: https://www.youtube.com/watch?v=_XBeGcczFJo&list=PLQj6bHfDUS-b5EXUbHVQ21N_2Vli39w0k&index=3&t=1023s
First you have to remove the href of the link and give it an id.
<a id='link'>
<?php echo $row["MainProdName"] ?>
</a>
Then you put this jQuery into your page. Note, you need to have a div in which you are going to put in all your obtained results. I reffered to this div in the code as #mydiv.
$("#link").click(function(){
$("#mydiv").load("Products.php?CatId=<?php echo $CatId;?>&MainProductId=<?php echo $id;?>");
});

How to overcome of passing single static value to the function?

I'm displaying as many buttons as the number of rows in query. Every row has it's own names & properties. When i click on any of the buttons, it should pass that particular value to the function. But, when i tried with the following code, it only passes very first value if i click on any buttons.
<?php
while ($rec = mysql_fetch_array($query)) {
echo "<figure>";
echo "<button onclick='change()' title='".$rec["UserName"]."' class='fa fa-user' id='myButton1' value='".$rec["UserName"]."' style='font-size:100px;color:red'></button>";
echo "<figcaption>".$rec["UserName"]."</figcaption>";
echo "</figure>";
//echo "</a>";
}
?>
<script type="text/javascript">
function change()
{
var elem = document.getElementById("myButton1");
alert(elem.value);
// SQL Query and display the results in a proper table <?php echo "<table><tr><td>".elem.value."</td></tr></table>"; ?>
}
</script>
How do make it passing dynamic values (clicking upon any buttons, it should pass it's corresponding value) ?
id values must be unique in HTML. Having multiple elements with the same id is invalid and will not work as desired.
You don't need ids at all. Instead, the minimal change is to pass this into your function:
<button onclick='change(this)' ... >
and in your function
function change(btn) {
alert(btn.value);
}
But the real answer is don't use onclick attribute event handlers. They're a mid-1990's technology. Things have moved on in 20 years.
In this case, I'd use a delegated handler on the container all these figures are in. There's probably a container nearer to them that you can use, but in the worst case, you can use document.body:
Put a common identifying feature on the buttons (say, a class), then:
$(document.body).on("click", ".the-class", function() {
alert(this.value);
});
One handler handles all the buttons, since click bubbles.
Again you probably want a container closer to the list of figures, rather than document.body.
<?php
while ($rec = mysql_fetch_array($query)) {
echo "<figure>";
echo "<button onclick='change(this.value)' title='".$rec["UserName"]."' class='fa fa-user' id='myButton1' value='".$rec["UserName"]."' style='font-size:100px;color:red'></button>";
echo "<figcaption>".$rec["UserName"]."</figcaption>";
echo "</figure>";
//echo "</a>";
}
?>
<script type="text/javascript">
function change(button_val)
{
alert(button_val);
// SQL Query and display the results in a proper table <?php echo "<table><tr><td>".button_val."</td></tr></table>"; ?>
}
</script>

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>';
}
}

Categories