Grant
Grant

Reputation: 196

Passing PHP variable to javascript function with quotes

I need to pass these values to a javascript function in the head. The problem is when pulling from the DB some are more than one word, and using a href it cuts it off at a space when passing using javascript:function(vars), and I can't get onclick to work at all. I've tried all sorts of combinations of quotes and brackets around the variables ("",'',/", and {) as well as putting quotes around the ones I know will have more than one word before passing (see below). Here is the PHP:

<?php
    require('config/dbconfig.php');
    $query = "SELECT * FROM news ORDER BY id DESC LIMIT 4";
    if ($stmt = $mysqli->prepare($query)) {
        /* execute statement */
        $stmt->execute();

        /* bind result variables */
        $stmt->bind_result($idn, $titlen, $categoryn, $descn, $postdaten, $authorn);

        /* fetch values */
        while ($stmt->fetch()) {
            //echo 'id: '. $id .' title: '. $title;
            echo "<table border='0'>";
            $shortDescLengthn = strlen($descn);
            if ($shortDescLengthn > 106) {
                $sDCutn = 106 - $shortDescLengthn;
                $shortDescn = substr($descn, 0, $sDCutn);
            } else {
                $shortDescn = $descn;
            }
                        $titlenQuote = "'". $titlen ."'";
                        $descnQuote = "'". $descn ."'";
                        $authornQuote = "'". $authorn ."'";
            echo "
                <h1>". $titlen ."</h1>
                <tr><td>". $shortDescn ."...</td></tr>
                <tr><td><a href='javascript:return false;' onclick='readMore(". $idn .",". $titlenQuote .",". $categoryn .",
                            ". $descnQuote .",". $postdaten .",". $authornQuote .")'>Read More</a></td></tr>
                <tr><td>Written by: " . $authorn . "</td></tr>
                <tr><td><img src='images/hardcore-games-newsbar-border.png' width='470px' /></td></tr>
            ";
        }
        echo "</table><br />";

        /* close statement */
        $stmt->close();
    }

    /* close connection */
    $mysqli->close();
?>

And the function it's going to in the head:

<script type="text/javascript">
    function readMore(id,title,cat,desc,post,auth) {
        alert(id +","+ title +","+ cat +","+ desc +","+ post +","+ auth);
        var $dialog = $('<div></div>').html('This dialog will show every time!').dialog({autoOpen: false,title: 'Basic Dialog'});
        $dialog.dialog('open');
        $dialog.title = title;
        $dialog.html(desc);
    }
</script>

This is a page using load() in the main index page. I've had issues with dialog too, but it's not even hitting that point yet so thats the next step. In case need to know, all jquery includes are on the main index page. The load() is going into a div on the index page, and this works fine so far.

Upvotes: 1

Views: 2890

Answers (3)

Ravi Mane
Ravi Mane

Reputation: 1536

<html>
<head>
<SCRIPT LANGUAGE="JAVASCRIPT" TYPE="TEXT/JAVASCRIPT">
function login(t) {
alert(t);
}
</SCRIPT>
</head>
<body>
<?php
$id=$_GET['id'];
print "<input type='button' name='button' value='button' onClick=login('$id')>";
?>
</body>
</html>

Upvotes: 1

icktoofay
icktoofay

Reputation: 128991

You're currently doing something like this:

echo "<a href='#' onclick='doSomething('" . $someData . "');'>...";

As you noted, this will not work because the quotes conflict. There's a quick way to fix this, but I think it would be better if you changed it a little bit more.

First, start by putting your data in attributes:

echo "<a ... data-title=\"" . htmlspecialchars($title) . "\" ...>...";

Note how I am escaping the title before I put it in there. You can add more attributes like that, but you should make them all start with data-.

Next, apply a class to it. For example, read-more.

echo "<a ... class=\"read-more\" data-title=\"" . htmlspecialchars($title) . "\" ...>...";

Now you can bind event listeners to it. Say all of the items were contained in a div with an id of items. You could then do this in the JavaScript:

$("#items").on("click", ".read-more", function(e) {
    var me = $(this);
    var title = me.attr('data-title');
    alert("The title is:\n" + title);
    e.preventDefault();
});

You could then extend that to pop up a dialog or whatever you wanted it to do.


Why this way and not the 'easy' way?

This way is a start to separating the content, presentation, and behavior, which is generally considered a good thing. Before, you had tables for layout and presentation mixed with the content mixed with inline JavaScript for behavior; a big soup of stuff.

Separating this all out aids maintainability and can often bring better load times if the common things are put into separate files and cached by the browser. If it's all a big soup, the browser can't cache the pieces separately.

Upvotes: 3

Ry-
Ry-

Reputation: 224855

You're using the same type of quote for both the attribute value delimiter and the JavaScript string delimiter; don't do that. Also, json_encode the values instead of just wrapping them in quotes, like so:

echo "
    <h1>". $titlen ."</h1>
    <tr><td>". $shortDescn ."...</td></tr>
    <tr><td><a href='javascript:return false;' onclick='readMore(". $idn .",". json_encode($titlen) .",". json_encode($categoryn) .",
    ". json_encode($descn) .",". json_encode($postdaten) .",". json_encode($authorn) .")'>Read More</a></td></tr>
    <tr><td>Written by: " . $authorn . "</td></tr>
    <tr><td><img src='images/hardcore-games-newsbar-border.png' width='470px' /></td></tr>
";

… and you'll also want to HTML-encode them.

echo "<h1>$titlen</h1>";
echo "<tr><td>$shortDescn...</td></tr>";
echo '<tr><td><a href="javascript:return false;" onclick="'
    . 'readMore(' . $idn . ',' . htmlspecialchars(json_encode($titlen)) . ','
    . htmlspecialchars(json_encode($categoryn)) . ','
    . htmlspecialchars(json_encode($descn)) . ',' . htmlspecialchars(json_encode($postdaten)) . ','
    . htmlspecialchars(json_encode($authorn)) . ')">Read More</a></td></tr>';
echo "<tr><td>Written by: $authorn</td></tr>";
echo '<tr><td><img src="images/hardcore-games-newsbar-border.png" width="470px" /></td></tr>';

ProTip™: <tr> can't be directly after <h1>.

Upvotes: 2

Related Questions