Jump to content

Php + Javascript


PNewCode

Recommended Posts

Hello. I selected php help because the loop where I need the function is in the php section.

What I have is something that ALMOST works. The code below allows for the first value in the list (loop) to be copied to the devices clipboard, but only the first one. (row "info"). I am guessing it's because my javascript isn't in the loop itself. I tried multiple times to move the js into the loop but then it just makes the page blank. I'm not showing examples of what I tried because there's been so many attempts that I don't remember them all. So what I am showing is what works for copying the first entry. Goal is to get this to work with each entry.

NOTE: I didin't include any connection to the database because all of that is working just fine and displaying all of the different entries and values. The copy function to work in the loop instead of just the first one is the only issue I'm having. Also, if anyone is wondering why I did "this and that" it's because everything except adding the id and the javascript was already made by someone else. I"m just adding the copy function to this
 

<?php

error_reporting(E_ALL);
ini_set('display_errors', '1');


echo 
nl2br( "<div id='goodContent'>" . $row['info'] . "</div><br><a href='updatecopypaste.php?id=" . $row['id'] . "'><img src='/ppreq/editbtn.jpg'></a>&nbsp &nbsp<a class='leftf' href='deletecopypaste.php?id=" . $row['id'] . "'><img src='/ppreq/deletebtn.jpg'></a>&nbsp &nbsp<button name='copy' id='clickCopy' name='copybtn' class='unstyled-button' style='cursor:pointer'><img src='/ppreq/copybtn.jpg' border='0'></button><br><br>___________<br><br>",60);
  }
} else {
  echo "0 Listings";
}
$conn->close();
?>


<script>
copyToClipboard(document.getElementById("content"));

document.getElementById("clickCopy").onclick = function() {
	copyToClipboard(document.getElementById("goodContent"));
}

document.getElementById("clickCopyString").onclick = function() {
	copyToClipboard("This is a variable string");
}

/**
* This will copy the innerHTML of an element to the clipboard
* @param element reference OR string
*/
function copyToClipboard(e) {
    var tempItem = document.createElement('input');

    tempItem.setAttribute('type','text');
    tempItem.setAttribute('display','none');
    
    let content = e;
    if (e instanceof HTMLElement) {
    		content = e.innerHTML;
    }
    
    tempItem.setAttribute('value',content);
    document.body.appendChild(tempItem);
    
    tempItem.select();
    document.execCommand('Copy');

    tempItem.parentElement.removeChild(tempItem);
}
</script>

 

Link to comment
Share on other sites

You are trying to use PHP to write something to a client's clipboard?  That is not possible since php runs on the server and not the client.

But then you think that JS can do that for you.  That MAY be true but it won't happen until the php script is done and the page is loaded on the client.  Is that what you are seeing?

How about you backup and tell us what your plan is and let us think about the programming?

Link to comment
Share on other sites

@ginerjm I said what the plan is lol.

This works for the first entry in the list.

It doesn't work for anything after the first entry.

 

Anotherwords, there are several entries in the database. If I click on the copy button for the first one, then it will copy to the clipboard and the user can paste it somewhere else.

 

BUT... if you click on the copy button on the 2nd one, then it does not copy anything to the clipboard. This is only working for the first in the list when displaying all of the entries

Link to comment
Share on other sites

ids in the html markup must be unique. you cannot use id='anything' more than once and any javascript code using a static getElementById('anything') cannot be used.

rather than showing non-working attempted code, show a couple of examples of server-side data and describe what operations you are trying to accomplish in the browser for that data.

Link to comment
Share on other sites

@ginerjm I want to make it so the javascript to make the "copy button" work for each listing instead of just the first one. See the screen shot below.
Right now, if you click on the first entry's copy button, then it copies it to the clipboard and can be pasted somewhere else (in a chat, notepad, etc)
If you go to the 2nd entry in the list, the copy button does not copy anything to the clipboard.

So this is only working for the first entry. Not the rest of them

image.png.4c1b70b46607c27c73064ea0801b3bc2.png

Link to comment
Share on other sites

2 hours ago, PNewCode said:

Any idea on how to add to this to grab the id for that specific entry?

It's generally better to just avoid ID's entirely. Use classes or your HTML structure to find the elements you need instead.  Your HTML is hard to read being all in a single line like that, and using nl2br on a single line is fairly pointless.  The code would be a lot nicer if you spaced it out and made it readable.  You might then notice that you have an error in your HTML in that your copy button has two name attributes.  Once that is all fixed up, you'd have something like this:

echo "
<div>
  <div class='copy-content'>".nl2br($row['info'])."</div>
  <br>
  <a href='updatecopypaste.php?id={$row['id']}'><img src='/ppreq/editbtn.jpg'></a>
  &nbsp &nbsp
  <a class='leftf' href='deletecopypaste.php?id={$row['id']}'><img src='/ppreq/deletebtn.jpg'></a>
  &nbsp &nbsp
  <button name='copy-button' class='unstyled-button' style='cursor:pointer'><img src='/ppreq/copybtn.jpg' border='0'></button>
</div>
<br><br>
";

Your copy button and copy content are now wrapped in a common parent element, which will make it easier to locate one relative to the other.  There are no more IDs so no more conflicts that need to be handled.  The content is identified via a class and your button via a name, both of which can be duplicated.

Now you need to create a single piece of JavaScript that can respond when any of the copy buttons are clicked.  That JavaScript code would use the button that was clicked as an initial point of references in the document, and locate the content to be copied by looking for the element with the class copy-content contained within the same parent element as the button.

window.addEventListener('DOMContentLoaded',()=>{
  //Find all the copy buttons
  document.querySelectorAll('button[name="copy-button"]').forEach((button)=>{
    //Add a click handler to each of the buttons
    button.addEventListener('click', (e)=>{
      //Locate the copy-content element
      const copyContent = button.parentElement.querySelector('.copy-content');
      //Do the copy
      copyToClipboard(copyContent);
    });
  });
});

Example.

Link to comment
Share on other sites

@kicken Thank you for that, and also for explaining it so I can understand. However I tried this just now and it gives me "page isn't working". I ran the whole page through an online debugger but it just showed an unclosed { error

Parse error: Unclosed '{' on line 31 does not match ')' in /in/upTHA on line 53
Process exited with code 255.

I tried in multiple places to close it but couldn't seem to make it work. Here's the whole pages code in hopes that this explains it better (with your update). Also, I know I have 2 different PHP instances, though it was like that when I got it and I didn't see any reason to mess with it unless I have to since it was semi-working for at least the first entry before.
 

<?php

$servername = "removed for posting";
$username = "removed for posting";
$password = "removed for posting";
$dbname = "removed for posting";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT * FROM copypaste";
$result = $conn->query($sql);


$resultt = mysqli_query($conn, "select COUNT(id) AS count FROM `copypaste`");

if(!$result) {
    die('Error: ' . mysqli_error($link));
} else {
    $num_rows = mysqli_fetch_assoc($resultt);
    // echo it
    echo "";
}

if ($result->num_rows > 0) {
  // output data of each row
  while($row = $result->fetch_assoc()) { ;  

?>


 
<?php

error_reporting(E_ALL);
ini_set('display_errors', '1');


echo "
<div>
  <div class='copy-content'>".nl2br($row['info'])."</div>
  <br>
  <a href='updatecopypaste.php?id={$row['id']}'><img src='/ppreq/editbtn.jpg'></a>
  &nbsp &nbsp
  <a class='leftf' href='deletecopypaste.php?id={$row['id']}'><img src='/ppreq/deletebtn.jpg'></a>
  &nbsp &nbsp
  <button name='copy-button' class='unstyled-button' style='cursor:pointer'><img src='/ppreq/copybtn.jpg' border='0'></button>
</div>
<br><br>",60);
  }
} else {
  echo "0 Listings";
}

?>

 

Link to comment
Share on other sites

The error is caused by the code remnant at the end of the string here:

<br><br>",60);

Try this instead:

<br><br>";

 

On an unrelated note, the following code is unnecessary:

$resultt = mysqli_query($conn, "select COUNT(id) AS count FROM `copypaste`");

if(!$result) {
    die('Error: ' . mysqli_error($link));
} else {
    $num_rows = mysqli_fetch_assoc($resultt);
    // echo it
    echo "";
}

You don't seem to be using that $num_rows variable. Plus, you can get the same information from the earlier query...which you use here:

if ($result->num_rows > 0) {

 

Link to comment
Share on other sites

2 hours ago, PNewCode said:

Also, I know I have 2 different PHP instances, though it was like that when I got it and I didn't see any reason to mess with it unless I have to since it was semi-working for at least the first entry before.

FYI - The extra PHP tags are unnecessary. Developers will sometimes break out of PHP to output some HTML, for example. Then go back into PHP to do more work. The close PHP tag "?>" and the open PHP tag "<?php" in the code below can be removed without issue.

  while($row = $result->fetch_assoc()) { ;  

?>


 
<?php

error_reporting(E_ALL);

More information about PHP tags can be found here:
https://www.php.net/manual/en/language.basic-syntax.phptags.php

 

Also, I just noticed there's a rogue semi-colon after the while loop line above. The semi-colon can be removed.

Link to comment
Share on other sites

@cyberRobot and @kicken No errors now but it's also not copying anything to the clipboard. Not even the first one now. I think I missed something between both of your posts. I really do appreciate everything. Here is the full page, maybe it can shed more light.

 

<?php

error_reporting(E_ALL);
ini_set('display_errors', '1');

$servername = "Removed for posting";
$username = "Removed for posting";
$password = "Removed for posting";
$dbname = "Removed for posting";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT * FROM copypaste";
$result = $conn->query($sql);



if ($result->num_rows > 0) {
  // output data of each row
  while($row = $result->fetch_assoc()) { ;  




echo "
<div>
  <div class='copy-content'>".nl2br($row['info'])."</div>
  <br>
  <a href='updatecopypaste.php?id={$row['id']}'><img src='/ppreq/editbtn.jpg'></a>
  &nbsp &nbsp
  <a class='leftf' href='deletecopypaste.php?id={$row['id']}'><img src='/ppreq/deletebtn.jpg'></a>
  &nbsp &nbsp
  <button name='copy-button' class='unstyled-button' style='cursor:pointer'><img src='/ppreq/copybtn.jpg' border='0'></button>
</div>
<br><br>";
  }
} else {
  echo "0 Listings";
}

?>


<script>
window.addEventListener('DOMContentLoaded',()=>{
  //Find all the copy buttons
  document.querySelectorAll('button[name="copy-button"]').forEach((button)=>{
    //Add a click handler to each of the buttons
    button.addEventListener('click', (e)=>{
      //Locate the copy-content element
      const copyContent = button.parentElement.querySelector('.copy-content');
      //Do the copy
      copyToClipboard(copyContent);
    });
  });
});
</script>

 

Link to comment
Share on other sites

3 hours ago, PNewCode said:

is that not the JS?

The JS from my post only sets up the event handling for the click event.  It still needs the copyToClipboard function from your original post to work.

 

Edited by kicken
Link to comment
Share on other sites

  • 2 weeks later...

Well, I searched about it on internet, there is an error on mentiones function. You can replace your code by below code.

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

echo nl2br("<div id='goodContent'>" . $row['info'] . "</div><br><a href='updatecopypaste.php?id=" . $row['id'] . "'><img src='/ppreq/editbtn.jpg'></a>&nbsp &nbsp<a class='leftf' href='deletecopypaste.php?id=" . $row['id'] . "'><img src='/ppreq/deletebtn.jpg'></a>&nbsp &nbsp<button name='copy' id='clickCopy' name='copybtn' class='unstyled-button' style='cursor:pointer'><img src='/ppreq/copybtn.jpg' border='0'></button><br><br>___________<br><br>", 60);
}

else {
  echo "0 Listings";
}
$conn->close();
?>

<script>
copyToClipboard(document.getElementById("content"));

document.getElementById("clickCopy").onclick = function() {
    copyToClipboard(document.getElementById("goodContent"));
}

document.getElementById("clickCopyString").onclick = function() {
    copyToClipboard("This is a variable string");
}

/**
* This will copy the innerHTML of an element to the clipboard
* @param element reference OR string
*/
function copyToClipboard(e) {
    var tempItem = document.createElement('input');

    tempItem.setAttribute('type', 'text');
    tempItem.setAttribute('display', 'none');

    let content = e;
    if (e instanceof HTMLElement) {
        content = e.innerHTML;
    }

    tempItem.setAttribute('value', content);
    document.body.appendChild(tempItem);

    tempItem.select();
    document.execCommand('Copy');

    tempItem.parentElement.removeChild(tempItem);
}
</script>

I hope it will work for you.

Thanks

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.